Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r--source/blender/editors/space_action/action_select.c150
1 files changed, 91 insertions, 59 deletions
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 4a4ff5f5605..ca6efb5f69e 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -153,7 +153,8 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac,
float region_x,
float *r_selx,
float *r_frame,
- bool *r_found)
+ bool *r_found,
+ bool *r_is_selected)
{
*r_found = false;
@@ -182,6 +183,7 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac,
*r_selx = BKE_nla_tweakedit_remap(adt, ak->cfra, NLATIME_CONVERT_UNMAP);
*r_frame = ak->cfra;
*r_found = true;
+ *r_is_selected = (ak->sel & SELECT) != 0;
break;
}
}
@@ -197,14 +199,16 @@ static void actkeys_find_key_at_position(bAnimContext *ac,
bAnimListElem **r_ale,
float *r_selx,
float *r_frame,
- bool *r_found)
+ bool *r_found,
+ bool *r_is_selected)
{
*r_found = false;
*r_ale = actkeys_find_list_element_at_position(ac, filter, region_x, region_y);
if (*r_ale != NULL) {
- actkeys_find_key_in_list_element(ac, *r_ale, region_x, r_selx, r_frame, r_found);
+ actkeys_find_key_in_list_element(
+ ac, *r_ale, region_x, r_selx, r_frame, r_found, r_is_selected);
}
}
@@ -213,9 +217,11 @@ static bool actkeys_is_key_at_position(bAnimContext *ac, float region_x, float r
bAnimListElem *ale;
float selx, frame;
bool found;
+ bool is_selected;
int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- actkeys_find_key_at_position(ac, filter, region_x, region_y, &ale, &selx, &frame, &found);
+ actkeys_find_key_at_position(
+ ac, filter, region_x, region_y, &ale, &selx, &frame, &found, &is_selected);
if (ale != NULL) {
MEM_freeN(ale);
@@ -1681,20 +1687,29 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
/* ------------------- */
-static void mouse_action_keys(bAnimContext *ac,
- const int mval[2],
- short select_mode,
- const bool deselect_all,
- const bool column,
- const bool same_channel)
+static int mouse_action_keys(bAnimContext *ac,
+ const int mval[2],
+ short select_mode,
+ const bool deselect_all,
+ const bool column,
+ const bool same_channel,
+ bool wait_to_deselect_others)
{
int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS;
bAnimListElem *ale = NULL;
bool found = false;
+ bool is_selected = false;
float frame = 0.0f; /* frame of keyframe under mouse - NLA corrections not applied/included */
float selx = 0.0f; /* frame of keyframe under mouse */
- actkeys_find_key_at_position(ac, filter, mval[0], mval[1], &ale, &selx, &frame, &found);
+ int ret_value = OPERATOR_FINISHED;
+
+ actkeys_find_key_at_position(
+ ac, filter, mval[0], mval[1], &ale, &selx, &frame, &found, &is_selected);
+
+ if (select_mode != SELECT_REPLACE) {
+ wait_to_deselect_others = false;
+ }
/* For replacing selection, if we have something to select, we have to clear existing selection.
* The same goes if we found nothing to select, and deselect_all is true
@@ -1703,56 +1718,61 @@ static void mouse_action_keys(bAnimContext *ac,
/* reset selection mode for next steps */
select_mode = SELECT_ADD;
- /* deselect all keyframes */
- deselect_action_keys(ac, 0, SELECT_SUBTRACT);
-
- /* highlight channel clicked on */
- if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight Action-Group or F-Curve? */
- if (ale != NULL && ale->data) {
- if (ale->type == ANIMTYPE_GROUP) {
- bActionGroup *agrp = ale->data;
-
- agrp->flag |= AGRP_SELECTED;
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
- }
- else if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
- FCurve *fcu = ale->data;
-
- fcu->flag |= FCURVE_SELECTED;
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
+ if (wait_to_deselect_others && is_selected) {
+ ret_value = OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ /* deselect all keyframes */
+ deselect_action_keys(ac, 0, SELECT_SUBTRACT);
+
+ /* highlight channel clicked on */
+ if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+
+ /* Highlight Action-Group or F-Curve? */
+ if (ale != NULL && ale->data) {
+ if (ale->type == ANIMTYPE_GROUP) {
+ bActionGroup *agrp = ale->data;
+
+ agrp->flag |= AGRP_SELECTED;
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ }
+ else if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
+ FCurve *fcu = ale->data;
+
+ fcu->flag |= FCURVE_SELECTED;
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
+ }
}
}
- }
- else if (ac->datatype == ANIMCONT_GPENCIL) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight GPencil Layer */
- if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_GPLAYER) {
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = ale->data;
-
- gpl->flag |= GP_LAYER_SELECT;
- /* Update other layer status. */
- if (BKE_gpencil_layer_getactive(gpd) != gpl) {
- BKE_gpencil_layer_setactive(gpd, gpl);
- BKE_gpencil_layer_autolock_set(gpd, false);
- WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ else if (ac->datatype == ANIMCONT_GPENCIL) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+
+ /* Highlight GPencil Layer */
+ if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_GPLAYER) {
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = ale->data;
+
+ gpl->flag |= GP_LAYER_SELECT;
+ /* Update other layer status. */
+ if (BKE_gpencil_layer_getactive(gpd) != gpl) {
+ BKE_gpencil_layer_setactive(gpd, gpl);
+ BKE_gpencil_layer_autolock_set(gpd, false);
+ WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
}
}
- }
- else if (ac->datatype == ANIMCONT_MASK) {
- /* deselect all other channels first */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ else if (ac->datatype == ANIMCONT_MASK) {
+ /* deselect all other channels first */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
- if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_MASKLAYER) {
- MaskLayer *masklay = ale->data;
+ if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_MASKLAYER) {
+ MaskLayer *masklay = ale->data;
- masklay->flag |= MASK_LAYERFLAG_SELECT;
+ masklay->flag |= MASK_LAYERFLAG_SELECT;
+ }
}
}
}
@@ -1787,12 +1807,15 @@ static void mouse_action_keys(bAnimContext *ac,
/* free this channel */
MEM_freeN(ale);
}
+
+ return ret_value;
}
/* handle clicking */
-static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int actkeys_clickselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
+ int ret_value;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0) {
@@ -1805,20 +1828,26 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
/* select mode is either replace (deselect all, then add) or add/extend */
const short selectmode = RNA_boolean_get(op->ptr, "extend") ? SELECT_INVERT : SELECT_REPLACE;
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
+ const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
+ int mval[2];
/* column selection */
const bool column = RNA_boolean_get(op->ptr, "column");
const bool channel = RNA_boolean_get(op->ptr, "channel");
+ mval[0] = RNA_int_get(op->ptr, "mouse_x");
+ mval[1] = RNA_int_get(op->ptr, "mouse_y");
+
/* select keyframe(s) based upon mouse position*/
- mouse_action_keys(&ac, event->mval, selectmode, deselect_all, column, channel);
+ ret_value = mouse_action_keys(
+ &ac, mval, selectmode, deselect_all, column, channel, wait_to_deselect_others);
/* set notifier that keyframe selection (and channels too) have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
/* for tweak grab to work */
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ return ret_value | OPERATOR_PASS_THROUGH;
}
void ACTION_OT_clickselect(wmOperatorType *ot)
@@ -1831,13 +1860,16 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
ot->description = "Select keyframes by clicking on them";
/* callbacks */
- ot->invoke = actkeys_clickselect_invoke;
ot->poll = ED_operator_action_active;
+ ot->exec = actkeys_clickselect_exec;
+ ot->invoke = WM_generic_select_invoke;
+ ot->modal = WM_generic_select_modal;
/* flags */
ot->flag = OPTYPE_UNDO;
/* properties */
+ WM_operator_properties_generic_select(ot);
prop = RNA_def_boolean(
ot->srna,
"extend",