[Bf-blender-cvs] [3de1bd9b380] soc-2019-outliner: Outliner: Fix walk selection wrapping and other issues

Nathan Craddock noreply at git.blender.org
Fri Jun 28 01:51:44 CEST 2019


Commit: 3de1bd9b380fb1b78dffea17bd60f6a4f3b58fad
Author: Nathan Craddock
Date:   Thu Jun 27 15:39:46 2019 -0600
Branches: soc-2019-outliner
https://developer.blender.org/rB3de1bd9b380fb1b78dffea17bd60f6a4f3b58fad

Outliner: Fix walk selection wrapping and other issues

This prevents walk selection from wrapping around from the last
to the first tree element. Additionally, if the active tree
element is within a closed subtree, walk select will move the
active element to the first visible parent.

The operator code is also simplified and slightly optimized.

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

M	source/blender/editors/space_outliner/outliner_select.c

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

diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 94cb08cbad9..048a915a10b 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1576,7 +1576,7 @@ void OUTLINER_OT_select_box(wmOperatorType *ot)
 
 /* **************** Walk Select Tool ****************** */
 
-static TreeElement *outliner_find_rightmost_child(SpaceOutliner *soops, TreeElement *te)
+static TreeElement *outliner_find_rightmost_visible_child(SpaceOutliner *soops, TreeElement *te)
 {
   while (te->subtree.last) {
     if (TSELEM_OPEN(TREESTORE(te), soops)) {
@@ -1589,24 +1589,30 @@ static TreeElement *outliner_find_rightmost_child(SpaceOutliner *soops, TreeElem
   return te;
 }
 
-static TreeElement *do_outliner_select_walk_up(SpaceOutliner *soops, TreeElement *active)
+static TreeElement *outliner_element_find_successor_in_parents(TreeElement *te)
 {
-  if (active->prev) {
-    TreeStoreElem *tselem = TREESTORE(active->prev);
-
-    if (TSELEM_OPEN(tselem, soops)) {
-      active = outliner_find_rightmost_child(soops, active->prev);
+  TreeElement *successor = te;
+  while (successor->parent) {
+    if (successor->parent->next) {
+      te = successor->parent->next;
+      break;
     }
     else {
-      active = active->prev;
+      successor = successor->parent;
     }
   }
+
+  return te;
+}
+
+static TreeElement *do_outliner_select_walk_up(SpaceOutliner *soops, TreeElement *active)
+{
+  if (active->prev) {
+    active = outliner_find_rightmost_visible_child(soops, active->prev);
+  }
   else if (active->parent) {
     active = active->parent;
   }
-  else {
-    active = outliner_find_rightmost_child(soops, active);
-  }
 
   return active;
 }
@@ -1622,15 +1628,7 @@ static TreeElement *do_outliner_select_walk_down(SpaceOutliner *soops, TreeEleme
     active = active->next;
   }
   else {
-    while (active->parent) {
-      if (active->parent->next) {
-        active = active->parent->next;
-        break;
-      }
-      else {
-        active = active->parent;
-      }
-    }
+    active = outliner_element_find_successor_in_parents(active);
   }
 
   return active;
@@ -1643,25 +1641,27 @@ static void do_outliner_select_walk(SpaceOutliner *soops, TreeElement *active, c
   outliner_flag_set(&soops->tree, TSE_SELECTED, false);
   tselem->flag &= ~TSE_ACTIVE;
 
-  if (direction == OUTLINER_SELECT_WALK_UP) {
-    active = do_outliner_select_walk_up(soops, active);
-  }
-  else if (direction == OUTLINER_SELECT_WALK_DOWN) {
-    active = do_outliner_select_walk_down(soops, active);
-  }
-  else if (direction == OUTLINER_SELECT_WALK_LEFT) {
-    if (TSELEM_OPEN(tselem, soops)) {
-      tselem->flag |= TSE_CLOSED;
-    }
-    else {
-      /* Jummp active to parent */
-      active = active->parent;
-    }
-  }
-  else if (direction == OUTLINER_SELECT_WALK_RIGHT) {
-    if (!TSELEM_OPEN(tselem, soops) && active->subtree.first) {
-      tselem->flag &= ~TSE_CLOSED;
-    }
+  switch (direction) {
+    case OUTLINER_SELECT_WALK_UP:
+      active = do_outliner_select_walk_up(soops, active);
+      break;
+    case OUTLINER_SELECT_WALK_DOWN:
+      active = do_outliner_select_walk_down(soops, active);
+      break;
+    case OUTLINER_SELECT_WALK_LEFT:
+      /* Close open element or jummp active to parent */
+      if (TSELEM_OPEN(tselem, soops)) {
+        tselem->flag |= TSE_CLOSED;
+      }
+      else if (active->parent) {
+        active = active->parent;
+      }
+      break;
+    case OUTLINER_SELECT_WALK_RIGHT:
+      if (!TSELEM_OPEN(tselem, soops) && active->subtree.first) {
+        tselem->flag &= ~TSE_CLOSED;
+      }
+      break;
   }
 
   tselem = TREESTORE(active);
@@ -1676,11 +1676,20 @@ static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEven
 
   TreeElement *active = outliner_find_active_element(&soops->tree);
 
-  /* Set root to active if no active exists (may not be needed now that syncing works) */
+  /* Set first element to active if no active exists (may not be needed with synced selection) */
   if (!active) {
     active = soops->tree.first;
     TREESTORE(active)->flag |= TSE_SELECTED | TSE_ACTIVE;
   }
+  else if (!outliner_is_element_visible(&soops->tree, active)) {
+    /* If active is not visible, set its first visble parent to active */
+    while (!outliner_is_element_visible(&soops->tree, active)) {
+      active = active->parent;
+    }
+
+    outliner_flag_set(&soops->tree, TSE_SELECTED | TSE_ACTIVE, false);
+    TREESTORE(active)->flag |= TSE_SELECTED | TSE_ACTIVE;
+  }
   else {
     TreeStoreElem *tselem = TREESTORE(active);



More information about the Bf-blender-cvs mailing list