[Bf-blender-cvs] [94be4ea6cf4] soc-2019-outliner: Outliner: Add range select

Nathan Craddock noreply at git.blender.org
Thu May 30 06:59:04 CEST 2019


Commit: 94be4ea6cf4201835857f9a704882ba1414f7b1f
Author: Nathan Craddock
Date:   Wed May 29 22:57:35 2019 -0600
Branches: soc-2019-outliner
https://developer.blender.org/rB94be4ea6cf4201835857f9a704882ba1414f7b1f

Outliner: Add range select

Adds range select to outliner_activate.
Range select is based on the active element and the clicked element.
If no active element is visible, report an error

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/space_outliner/outliner_select.c

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 9b1cccb59ad..7f08c635778 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -687,7 +687,7 @@ def km_outliner(params):
         ("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True},
          {"properties": [("extend", True), ("range", False), ("recursive", False)]}),
         ("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True},
-         {"properties": [("extend", True), ("range", True), ("recursive", False)]}),
+         {"properties": [("extend", False), ("range", True), ("recursive", False)]}),
         ("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "alt": True},
          {"properties": [("extend", False), ("range", False), ("recursive", True)]}),
         ("outliner.item_activate", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True, "alt": True},
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index d70dc5ac5f0..235c0374d35 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -45,6 +45,7 @@
 #include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
+#include "BKE_report.h"
 #include "BKE_paint.h"
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
@@ -1211,7 +1212,8 @@ void outliner_item_select(SpaceOutliner *soops,
                           const bool toggle)
 {
   TreeStoreElem *tselem = TREESTORE(te);
-  const short new_flag = toggle ? (tselem->flag ^ TSE_SELECTED) : (tselem->flag | TSE_SELECTED);
+  const short new_flag = (toggle && (tselem->flag & TSE_ACTIVE)) ? (tselem->flag ^ TSE_SELECTED) :
+                                                                   (tselem->flag | TSE_SELECTED);
 
   // Change active element
   outliner_flag_set(&soops->tree, TSE_ACTIVE, false);
@@ -1222,6 +1224,55 @@ void outliner_item_select(SpaceOutliner *soops,
   tselem->flag = new_flag | TSE_ACTIVE;
 }
 
+static void do_outliner_range_select_recursive(ListBase *lb,
+                                               TreeElement *active,
+                                               TreeElement *cursor,
+                                               bool *selecting)
+{
+  for (TreeElement *te = lb->first; te; te = te->next) {
+    if (*selecting) {
+      TREESTORE(te)->flag |= TSE_SELECTED;
+    }
+
+    /* Set state for selection */
+    if (te == active || te == cursor) {
+      *selecting = !*selecting;
+    }
+
+    if (*selecting) {
+      TREESTORE(te)->flag |= TSE_SELECTED;
+    }
+
+    /* Don't look at closed elements */
+    if (!(TREESTORE(te)->flag & TSE_CLOSED)) {
+      do_outliner_range_select_recursive(&te->subtree, active, cursor, selecting);
+    }
+  }
+}
+
+/* Select a range of items between cursor and active element */
+static bool do_outliner_range_select(SpaceOutliner *soops, const TreeElement *cursor_element)
+{
+  TreeElement *active_element = outliner_find_active_element(&soops->tree);
+
+  /* Once synced selection is implemented this check may not be needed */
+  if (!active_element) {
+    return false;
+  }
+
+  /* Range select requires the active element to be visible */
+  if (!outliner_is_element_visible(&soops->tree, active_element)) {
+    return false;
+  }
+
+  outliner_flag_set(&soops->tree, TSE_SELECTED, false);
+
+  bool selecting = false;
+  do_outliner_range_select_recursive(&soops->tree, active_element, cursor_element, &selecting);
+
+  return true;
+}
+
 static void outliner_item_toggle_closed(TreeElement *te, const bool toggle_children)
 {
   TreeStoreElem *tselem = TREESTORE(te);
@@ -1272,8 +1323,10 @@ void outliner_item_do_activate_from_tree_element(
  * May expend/collapse branches or activate items.
  * */
 static int outliner_item_do_activate_from_cursor(bContext *C,
+                                                 wmOperator *op,
                                                  const int mval[2],
                                                  const bool extend,
+                                                 const bool range,
                                                  const bool recursive,
                                                  const bool deselect_all)
 {
@@ -1307,9 +1360,18 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
     TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
     TreeStoreElem *activate_tselem = TREESTORE(activate_te);
 
-    outliner_item_select(soops, activate_te, extend, extend);
-    do_outliner_item_activate_tree_element(
-        C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive);
+    if (range) {
+      if (!do_outliner_range_select(soops, activate_te)) {
+        BKE_report(op->reports, RPT_ERROR, "Range select requires a visible active element");
+        return OPERATOR_CANCELLED;
+      }
+    }
+    else {
+      outliner_item_select(soops, activate_te, extend, extend);
+      do_outliner_item_activate_tree_element(
+          C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive);
+    }
+
     changed = true;
   }
 
@@ -1330,9 +1392,11 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
 static int outliner_item_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
   const bool extend = RNA_boolean_get(op->ptr, "extend");
+  const bool range = RNA_boolean_get(op->ptr, "range");
   const bool recursive = RNA_boolean_get(op->ptr, "recursive");
   const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
-  return outliner_item_do_activate_from_cursor(C, event->mval, extend, recursive, deselect_all);
+  return outliner_item_do_activate_from_cursor(
+      C, op, event->mval, extend, range, recursive, deselect_all);
 }
 
 void OUTLINER_OT_item_activate(wmOperatorType *ot)
@@ -1347,6 +1411,7 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
 
   PropertyRNA *prop;
   RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
+  RNA_def_boolean(ot->srna, "range", false, "Range", "Select a range from active element");
   RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
   prop = RNA_def_boolean(ot->srna,
                          "deselect_all",



More information about the Bf-blender-cvs mailing list