[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