[Bf-blender-cvs] [b91332e93d9] temp-soc-2019-outliner-sync: Outliner: Allow select on row icons

Nathan Craddock noreply at git.blender.org
Fri Aug 9 06:01:56 CEST 2019


Commit: b91332e93d9c23d42ad05d384a6aecc53cdefa15
Author: Nathan Craddock
Date:   Thu Aug 8 15:37:32 2019 -0600
Branches: temp-soc-2019-outliner-sync
https://developer.blender.org/rBb91332e93d9c23d42ad05d384a6aecc53cdefa15

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.

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

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..190e859e189 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -478,6 +478,116 @@ 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) {
+    if (tree_element_id_type_to_index(te) == type && tselem_type == TREESTORE(te)->type) {
+      if (BLI_strcasestr(te->name, str)) {
+        BLI_strncpy(name, te->name, 64);
+
+        iconid = tree_element_get_icon(TREESTORE(te), te).icon;
+
+        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)
+{
+  MergedSearchData *search_data = (MergedSearchData *)data;
+  TreeElement *parent = search_data->parent_element;
+  TreeElement *te = search_data->select_element;
+
+  int type = tree_element_id_type_to_index(te);
+
+  merged_element_search_cb_recursive(&parent->subtree, TREESTORE(te)->type, type, str, items);
+}
+
+/* Activate an element fr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list