Select: Add 'deselect on nothing' to Action (dopesheet) editor.
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 30 Apr 2019 14:51:44 +0000 (16:51 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 30 Apr 2019 14:51:44 +0000 (16:51 +0200)
Also removed annoying console error when clicking outside of valid range
of channels, that is no error at all. ;)

Part of T63995.

release/scripts/presets/keyconfig/keymap_data/blender_default.py
source/blender/editors/space_action/action_select.c

index 18ecdb4..7f50de7 100644 (file)
@@ -1921,7 +1921,8 @@ def km_dopesheet(params):
 
     items.extend([
         ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS'},
-         {"properties": [("extend", False), ("column", False), ("channel", False)]}),
+         {"properties": [("extend", False), ("deselect_all", not params.legacy),
+                         ("column", False), ("channel", False)]}),
         ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS', "alt": True},
          {"properties": [("extend", False), ("column", True), ("channel", False)]}),
         ("action.clickselect", {"type": params.select_mouse, "value": 'PRESS', "shift": True},
index fb35afb..bbbb9a0 100644 (file)
@@ -1423,8 +1423,12 @@ 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, bool column, bool same_channel)
+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)
 {
   ListBase anim_data = {NULL, NULL};
   DLRBT_Tree anim_keys;
@@ -1469,14 +1473,7 @@ static void mouse_action_keys(
 
   /* try to get channel */
   ale = BLI_findlink(&anim_data, channel_index);
-  if (ale == NULL) {
-    /* channel not found */
-    printf("Error: animation channel (index = %d) not found in mouse_action_keys()\n",
-           channel_index);
-    ANIM_animdata_freelist(&anim_data);
-    return;
-  }
-  else {
+  if (ale != NULL) {
     /* found match - must return here... */
     AnimData *adt = ANIM_nla_mapping_get(ac, ale);
     ActKeyColumn *ak, *akn = NULL;
@@ -1561,8 +1558,10 @@ static void mouse_action_keys(
     ANIM_animdata_freelist(&anim_data);
   }
 
-  /* for replacing selection, firstly need to clear existing selection */
-  if (select_mode == SELECT_REPLACE) {
+  /* For replacing selection, if we have somthing to select, we have to clear existing selection.
+   * The same goes if we found nothing to select, and deselect_all is true
+   * (deselect on nothing behavior). */
+  if ((select_mode == SELECT_REPLACE && found) || (!found && deselect_all)) {
     /* reset selection mode for next steps */
     select_mode = SELECT_ADD;
 
@@ -1575,7 +1574,7 @@ static void mouse_action_keys(
       ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
 
       /* Highlight Action-Group or F-Curve? */
-      if (ale && ale->data) {
+      if (ale != NULL && ale->data) {
         if (ale->type == ANIMTYPE_GROUP) {
           bActionGroup *agrp = ale->data;
 
@@ -1595,7 +1594,7 @@ static void mouse_action_keys(
       ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
 
       /* Highlight GPencil Layer */
-      if ((ale && ale->data) && (ale->type == ANIMTYPE_GPLAYER)) {
+      if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_GPLAYER) {
         bGPDlayer *gpl = ale->data;
 
         gpl->flag |= GP_LAYER_SELECT;
@@ -1607,7 +1606,7 @@ static void mouse_action_keys(
       ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
 
       /* Highlight GPencil Layer */
-      if ((ale && ale->data) && (ale->type == ANIMTYPE_MASKLAYER)) {
+      if (ale != NULL && ale->data != NULL && ale->type == ANIMTYPE_MASKLAYER) {
         MaskLayer *masklay = ale->data;
 
         masklay->flag |= MASK_LAYERFLAG_SELECT;
@@ -1617,7 +1616,7 @@ static void mouse_action_keys(
   }
 
   /* only select keyframes if we clicked on a valid channel and hit something */
-  if (ale) {
+  if (ale != NULL) {
     if (found) {
       /* apply selection to keyframes */
       if (column) {
@@ -1652,9 +1651,6 @@ static void mouse_action_keys(
 static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
   bAnimContext ac;
-  /* ARegion *ar; */ /* UNUSED */
-  short selectmode;
-  bool column, channel;
 
   /* get editor data */
   if (ANIM_animdata_get_context(C, &ac) == 0) {
@@ -1665,19 +1661,15 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
   /* ar = ac.ar; */ /* UNUSED */
 
   /* select mode is either replace (deselect all, then add) or add/extend */
-  if (RNA_boolean_get(op->ptr, "extend")) {
-    selectmode = SELECT_INVERT;
-  }
-  else {
-    selectmode = SELECT_REPLACE;
-  }
+  const short selectmode = RNA_boolean_get(op->ptr, "extend") ? SELECT_INVERT : SELECT_REPLACE;
+  const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
 
   /* column selection */
-  column = RNA_boolean_get(op->ptr, "column");
-  channel = RNA_boolean_get(op->ptr, "channel");
+  const bool column = RNA_boolean_get(op->ptr, "column");
+  const bool channel = RNA_boolean_get(op->ptr, "channel");
 
   /* select keyframe(s) based upon mouse position*/
-  mouse_action_keys(&ac, event->mval, selectmode, column, channel);
+  mouse_action_keys(&ac, event->mval, selectmode, deselect_all, column, channel);
 
   /* set notifier that keyframe selection (and channels too) have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
@@ -1712,6 +1704,13 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
       "Toggle keyframe selection instead of leaving newly selected keyframes only");  // SHIFTKEY
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 
+  prop = RNA_def_boolean(ot->srna,
+                         "deselect_all",
+                         false,
+                         "Deselect On Nothing",
+                         "Deselect all when nothing under the cursor");
+  RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
   prop = RNA_def_boolean(
       ot->srna,
       "column",