[Bf-blender-cvs] [01006aa45d1] master: Outliner: Allow select on row icons

Nathan Craddock noreply at git.blender.org
Fri Aug 16 20:31:42 CEST 2019


Commit: 01006aa45d1afc9f45d2f6a42f6981f5c92af051
Author: Nathan Craddock
Date:   Thu Aug 8 15:37:32 2019 -0600
Branches: master
https://developer.blender.org/rB01006aa45d1afc9f45d2f6a42f6981f5c92af051

Outliner: Allow select on row icons

Allow selection of subtree elements on a collapsed element's
row. Because subtree elements are aggregated by type, a select on
an icon that represents multiple subtree elements will invoke a
popup menu to select the specific subtree element.

Also draws highlights on cursor hover over a row icon.

Any child elements that are linked to multiple collections will
only be listed in the popup one time, and selection from the
popup will select the first instance in the subtree.

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

M	source/blender/editors/space_outliner/outliner_draw.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
M	source/blender/editors/space_outliner/outliner_tools.c
M	source/blender/editors/space_outliner/outliner_utils.c

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

diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index a2fe131198d..a3b1c03a1b8 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2590,7 +2590,11 @@ static void tselem_draw_icon(uiBlock *block,
     return;
   }
 
+  /* Icon is covered by restrict buttons */
   if (!is_clickable || x >= xmax) {
+    /* Reduce alpha to match icon buttons */
+    alpha *= 0.8f;
+
     /* placement of icons, copied from interface_widgets.c */
     float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
     x += 2.0f * aspect;
@@ -2698,7 +2702,6 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
     float ufac = UI_UNIT_X / 20.0f;
     float icon_color[4], icon_border[4];
     outliner_icon_background_colors(icon_color, icon_border);
-    icon_color[3] *= alpha_fac;
     if (active == OL_DRAWSEL_ACTIVE) {
       UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_color);
       icon_border[3] = 0.3f;
@@ -2723,6 +2726,9 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
     GPU_blend(true); /* Roundbox disables. */
   }
 
+  if (tselem->flag & TSE_HIGHLIGHTED) {
+    alpha_fac += 0.5;
+  }
   tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, alpha_fac, false);
   te->xs = *offsx;
   te->ys = ys;
@@ -2730,7 +2736,12 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
 
   if (num_elements > 1) {
     outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
+    te->flag |= TE_ICONROW_MERGED;
   }
+  else {
+    te->flag |= TE_ICONROW;
+  }
+
   (*offsx) += UI_UNIT_X;
 }
 
@@ -2740,7 +2751,7 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
  * We use a continuum of indices until we get to the object data-blocks
  * and we then make room for the object types.
  */
-static int tree_element_id_type_to_index(TreeElement *te)
+int tree_element_id_type_to_index(TreeElement *te)
 {
   TreeStoreElem *tselem = TREESTORE(te);
 
@@ -2870,7 +2881,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
   TreeElement *ten;
 
   /* closed items may be displayed in row of parent, don't change their coordinate! */
-  if ((te->flag & TE_ICONROW) == 0) {
+  if ((te->flag & TE_ICONROW) == 0 && (te->flag & TE_ICONROW_MERGED) == 0) {
     /* store coord and continue, we need coordinates for elements outside view too */
     te->xs = startx;
     te->ys = starty;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 57fea544c77..842502ec82f 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -101,9 +101,15 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
 
   ARegion *ar = CTX_wm_region(C);
   SpaceOutliner *soops = CTX_wm_space_outliner(C);
-  const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
 
-  TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
+  float view_mval[2];
+  UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+
+  TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+  if (hovered_te) {
+    hovered_te = outliner_find_item_at_x_in_row(soops, hovered_te, view_mval[0], NULL);
+  }
   bool changed = false;
 
   if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index c12fdcc6d1f..72cd8dc6424 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -131,6 +131,9 @@ enum {
   TE_DISABLED = (1 << 4),
   TE_DRAGGING = (1 << 5),
   TE_CHILD_NOT_IN_COLLECTION = (1 << 6),
+  /* Child elements of the same type in the iconrow are drawn merged as one icon.
+   * TE_ICONROW_MERGED is set for an element that is part of these merged child icons. */
+  TE_ICONROW_MERGED = (1 << 7),
 };
 
 /* button events */
@@ -223,6 +226,8 @@ void outliner_collection_isolate_flag(struct Scene *scene,
                                       const char *propname,
                                       const bool value);
 
+int tree_element_id_type_to_index(TreeElement *te);
+
 /* outliner_select.c -------------------------------------------- */
 eOLDrawState tree_element_type_active(struct bContext *C,
                                       struct Scene *scene,
@@ -255,6 +260,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 *,
@@ -382,6 +389,10 @@ void OUTLINER_OT_orphans_purge(struct wmOperatorType *ot);
 
 /* outliner_tools.c ---------------------------------------------- */
 
+void merged_element_search_menu_invoke(struct bContext *C,
+                                       TreeElement *parent_te,
+                                       TreeElement *activate_te);
+
 void OUTLINER_OT_operation(struct wmOperatorType *ot);
 void OUTLINER_OT_scene_operation(struct wmOperatorType *ot);
 void OUTLINER_OT_object_operation(struct wmOperatorType *ot);
@@ -441,7 +452,8 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
                                      float view_co_y);
 TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops,
                                             const TreeElement *parent_te,
-                                            float view_co_x);
+                                            float view_co_x,
+                                            bool *multiple_objects);
 TreeElement *outliner_find_tse(struct SpaceOutliner *soops, const TreeStoreElem *tse);
 TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem);
 TreeElement *outliner_find_parent_element(ListBase *lb,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 38dfe439b9c..ddb943d6c66 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1246,12 +1246,6 @@ 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)
-{
-  return ((te->flag & TE_ICONROW) == 0) && (view_co_x > te->xs) &&
-         (view_co_x < te->xs + UI_UNIT_X);
-}
-
 static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
                                                    const ARegion *ar,
                                                    float view_co_x)
@@ -1313,8 +1307,18 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
   else {
     Scene *scene = CTX_data_scene(C);
     ViewLayer *view_layer = CTX_data_view_layer(C);
-    /* the row may also contain children, if one is hovered we want this instead of current te */
-    TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
+
+    /* The row may also contain children, if one is hovered we want this instead of current te */
+    bool merged_elements = false;
+    TreeElement *activate_te = outliner_find_item_at_x_in_row(
+        soops, te, view_mval[0], &merged_elements);
+
+    /* If the selected icon was an aggregate of multiple elements, run the search popup */
+    if (merged_elements) {
+      merged_element_search_menu_invoke(C, te, activate_te);
+      return OPERATOR_CANCELLED;
+    }
+
     TreeStoreElem *activate_tselem = TREESTORE(activate_te);
 
     outliner_item_select(soops, activate_te, extend, extend);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index f9905cc4fcd..582a9cad312 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -63,6 +63,7 @@
 
 #include "ED_armature.h"
 #include "ED_object.h"
+#include "ED_outliner.h"
 #include "ED_scene.h"
 #include "ED_screen.h"
 #include "ED_sequencer.h"
@@ -478,6 +479,127 @@ void OUTLINER_OT_scene_operation(wmOperatorType *ot)
 }
 /* ******************************************** */
 
+/* Stores the parent and a child element of a merged iconrow icon for
+ * the merged select popup menu. The subtree of the parent is searched and
+ * the child is needed to only show elements of the same type in the popup. */
+typedef struct MergedSearchData {
+  TreeElement *parent_element;
+  TreeElement *select_element;
+} MergedSearchData;
+
+static void merged_element_search_cb_recursive(
+    const ListBase *tree, short tselem_type, short type, const char *str, uiSearchItems *items)
+{
+  char name[64];
+  int iconid;
+
+  for (TreeElement *te = tree->first; te; te = te->next) {
+    TreeStoreElem *tselem = TREESTORE(te);
+
+    if (tree_element_id_type_to_index(te) == type && tselem_type == tselem->type) {
+      if (BLI_strcasestr(te->name, str)) {
+        BLI_strncpy(name, te->name, 64);
+
+        iconid = tree_element_get_icon(tselem, te).icon;
+
+        /* Don't allow duplicate named items */
+        if (UI_search_items_find_index(items, name) == -1) {
+          if (!UI_search_item_add(items, name, te, iconid)) {
+            break;
+          }
+        }
+      }
+    }
+
+    merged_element_search_cb_recursive(&te->subtree, tselem_type, type, str, items);
+  }
+}
+
+/* Get a list of elements that match the search string */
+static void merged_element_search_cb(const bContext *UNUSED(C),
+                                     void *data,
+                                     const char *str,
+                                     uiSearchItems *items)
+{
+  MergedSearch

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list