[Bf-blender-cvs] [88a2c578274] soc-2019-outliner: Outliner: Support click+drag for toggling disclosure triangles

Nathan Craddock noreply at git.blender.org
Fri Jul 26 04:39:59 CEST 2019


Commit: 88a2c5782745f2ece9d8f2d046fb6bce83a2f7b0
Author: Nathan Craddock
Date:   Thu Jul 25 15:28:58 2019 -0600
Branches: soc-2019-outliner
https://developer.blender.org/rB88a2c5782745f2ece9d8f2d046fb6bce83a2f7b0

Outliner: Support click+drag for toggling disclosure triangles

This reworks the openclose operator for toggling disclosure
triangles. Rather than mapping to `Enter` by default, it supports
left click and left tweak events. This allows click+drag over
elements in the tree to open or close levels. Once the click+drag
is started, only elements on that level in the outliner will open
or close.

This removes the toggling from `outliner_select.c` which adds more
clarity to the activate function.

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/space_outliner/outliner_dragdrop.c
M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_outliner/outliner_intern.h
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 ec820e56e2a..3aa22c16648 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -726,10 +726,11 @@ def km_outliner(params):
          {"properties": [("direction", 'DOWN'), ("extend", True)]}),
         ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'LEFT')]}),
         ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'RIGHT')]}),
-        ("outliner.item_openclose", {"type": 'RET', "value": 'PRESS'},
+        ("outliner.item_openclose", {"type": 'LEFTMOUSE', "value": 'CLICK'},
          {"properties": [("all", False)]}),
-        ("outliner.item_openclose", {"type": 'RET', "value": 'PRESS', "shift": True},
+        ("outliner.item_openclose", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True},
          {"properties": [("all", True)]}),
+        ("outliner.item_openclose", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("all", False)]}),
         ("outliner.operation", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None),
         ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None),
         ("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, None),
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index ca14f9637b8..b7a38c0b82f 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -994,6 +994,12 @@ static int outliner_item_drag_drop_invoke(bContext *C,
     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
   }
 
+  float view_mval[2];
+  UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+  if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
+    return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+  }
+
   wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
 
   if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index f80a2cf8fdd..9cccdbdd186 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -140,59 +140,94 @@ void OUTLINER_OT_highlight_update(wmOperatorType *ot)
 
 /* Toggle Open/Closed ------------------------------------------- */
 
-static int do_outliner_item_openclose(
-    bContext *C, SpaceOutliner *soops, TreeElement *te, const bool all, const float mval[2])
+/* Open or close a tree element */
+static bool outliner_item_openclose(TreeElement *te, bool open_all)
 {
+  TreeStoreElem *tselem = TREESTORE(te);
 
-  if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
-    TreeStoreElem *tselem = TREESTORE(te);
+  /* all below close/open? */
+  if (open_all) {
+    tselem->flag &= ~TSE_CLOSED;
+    outliner_flag_set(
+        &te->subtree, TSE_CLOSED, !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1));
 
-    /* all below close/open? */
-    if (all) {
+    return true;
+  }
+  else {
+    if (tselem->flag & TSE_CLOSED) {
       tselem->flag &= ~TSE_CLOSED;
-      outliner_flag_set(
-          &te->subtree, TSE_CLOSED, !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1));
     }
     else {
-      if (tselem->flag & TSE_CLOSED) {
-        tselem->flag &= ~TSE_CLOSED;
-      }
-      else {
-        tselem->flag |= TSE_CLOSED;
-      }
+      tselem->flag |= TSE_CLOSED;
     }
 
-    return 1;
+    return true;
   }
 
-  for (te = te->subtree.first; te; te = te->next) {
-    if (do_outliner_item_openclose(C, soops, te, all, mval)) {
-      return 1;
+  return false;
+}
+
+static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  ARegion *ar = CTX_wm_region(C);
+  SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+  float view_mval[2];
+  UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+
+  if (event->type == MOUSEMOVE) {
+    TreeElement *te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+    TreeStoreElem *prev_tselem = (TreeStoreElem *)op->customdata;
+    TreeElement *prev_elem = outliner_find_tree_element(&soops->tree, prev_tselem);
+
+    /* Only openclose if mouse is not over the previously toggled element */
+    if (te && TREESTORE(te) != prev_tselem) {
+
+      /* Only toggle openclose on the same level as the first clicked element */
+      if (te->xs == prev_elem->xs) {
+        if (outliner_item_openclose(te, false)) {
+          ED_region_tag_redraw(ar);
+        }
+        op->customdata = TREESTORE(te);
+      }
     }
   }
-  return 0;
+  else if (event->val == KM_RELEASE) {
+    return OPERATOR_FINISHED;
+  }
+
+  return OPERATOR_RUNNING_MODAL;
 }
 
-/* event can enterkey, then it opens/closes */
-static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *event)
+static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
   ARegion *ar = CTX_wm_region(C);
   SpaceOutliner *soops = CTX_wm_space_outliner(C);
-  TreeElement *te;
-  float fmval[2];
-  const bool all = RNA_boolean_get(op->ptr, "all");
 
-  UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+  const bool open_all = RNA_boolean_get(op->ptr, "all");
 
-  for (te = soops->tree.first; te; te = te->next) {
-    if (do_outliner_item_openclose(C, soops, te, all, fmval)) {
-      break;
+  float view_mval[2];
+  UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+
+  TreeElement *te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+  if (te && outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
+    outliner_item_openclose(te, open_all);
+    ED_region_tag_redraw(ar);
+
+    /* Store the first clicked on element */
+    op->customdata = TREESTORE(te);
+
+    /* Only toggle once for single click toggling */
+    if (event->type == LEFTMOUSE) {
+      return OPERATOR_FINISHED;
     }
-  }
 
-  ED_region_tag_redraw(ar);
+    WM_event_add_modal_handler(C, op);
+    return OPERATOR_RUNNING_MODAL;
+  }
 
-  return OPERATOR_FINISHED;
+  return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
 }
 
 void OUTLINER_OT_item_openclose(wmOperatorType *ot)
@@ -201,7 +236,8 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
   ot->idname = "OUTLINER_OT_item_openclose";
   ot->description = "Toggle whether item under cursor is enabled or closed";
 
-  ot->invoke = outliner_item_openclose;
+  ot->invoke = outliner_item_openclose_invoke;
+  ot->modal = outliner_item_openclose_modal;
 
   ot->poll = ED_operator_outliner_active;
 
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 5a02361087c..e00eb5ea365 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -266,6 +266,8 @@ void outliner_object_mode_toggle(struct bContext *C,
 
 void outliner_element_activate(struct SpaceOutliner *soops, struct TreeStoreElem *tselem);
 
+bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x);
+
 /* outliner_edit.c ---------------------------------------------- */
 typedef void (*outliner_operation_cb)(struct bContext *C,
                                       struct ReportList *,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index bd19d4bbedf..09b62261c90 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1345,7 +1345,7 @@ static void outliner_item_toggle_closed(TreeElement *te, const bool toggle_child
   }
 }
 
-static bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x)
+bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x)
 {
   return (view_co_x > te->xs) && (view_co_x < te->xs + UI_UNIT_X);
 }
@@ -1408,9 +1408,7 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
   /* Don't allow toggle on scene collection */
   else if ((TREESTORE(te)->type != TSE_VIEW_COLLECTION_BASE) &&
            outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
-    outliner_item_toggle_closed(te, extend);
-    changed = true;
-    rebuild_tree = true;
+    return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
   }
   else {
     ViewLayer *view_layer = CTX_data_view_layer(C);



More information about the Bf-blender-cvs mailing list