[Bf-blender-cvs] [8f2c296e22e] soc-2019-outliner: Outliner: Show menu when clicking on aggregated iconrow icons

Nathan Craddock noreply at git.blender.org
Fri Jul 19 06:18:33 CEST 2019


Commit: 8f2c296e22e7bc1d7af9b0c96b1dcc130b037850
Author: Nathan Craddock
Date:   Thu Jul 18 22:17:16 2019 -0600
Branches: soc-2019-outliner
https://developer.blender.org/rB8f2c296e22e7bc1d7af9b0c96b1dcc130b037850

Outliner: Show menu when clicking on aggregated iconrow icons

This is still a work in progress. The code needs to be better
and the behavior could use some improvement. It works okay for
now though.

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

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_utils.c

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

diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 0a32741858c..f80a2cf8fdd 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -108,7 +108,7 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
   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]);
+    hovered_te = outliner_find_item_at_x_in_row(soops, hovered_te, view_mval[0], NULL);
   }
   bool changed = false;
 
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index f6f442dbecb..b0a17dfc0b7 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -451,7 +451,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 1829a5da99b..1268bba7cb2 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -37,11 +37,13 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_listbase.h"
+#include "BLI_string.h"
 
 #include "BKE_armature.h"
 #include "BKE_collection.h"
 #include "BKE_context.h"
 #include "BKE_gpencil.h"
+#include "BKE_idcode.h"
 #include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
@@ -66,6 +68,7 @@
 #include "WM_types.h"
 
 #include "UI_interface.h"
+#include "UI_resources.h"
 #include "UI_view2d.h"
 
 #include "RNA_access.h"
@@ -1372,6 +1375,108 @@ void outliner_item_do_activate_from_tree_element(
       C, scene, view_layer, soops, te, tselem, extend, recursive);
 }
 
+static int get_element_type(TreeElement *te)
+{
+  TreeStoreElem *tselem = TREESTORE(te);
+  const int id_index = tselem->type == 0 ? BKE_idcode_to_index(te->idcode) : INDEX_ID_GR;
+  if (id_index < INDEX_ID_OB) {
+    return id_index;
+  }
+  else if (id_index == INDEX_ID_OB) {
+    const Object *ob = (Object *)tselem->id;
+    return INDEX_ID_OB + ob->type;
+  }
+  else {
+    return 0;
+  }
+}
+
+static void merged_element_search_cb_recursive(const ListBase *tree,
+                                               short type,
+                                               const char *str,
+                                               uiSearchItems *items)
+{
+  char name[64];
+
+  for (TreeElement *te = tree->first; te; te = te->next) {
+    if (get_element_type(te) == type) {
+      if (BLI_strcasestr(te->name, str)) {
+        BLI_strncpy(name, te->name, 64);
+
+        if (!UI_search_item_add(items, name, te, 0)) {
+          break;
+        }
+      }
+    }
+
+    merged_element_search_cb_recursive(&te->subtree, type, str, items);
+  }
+}
+
+static void merged_element_search_cb(const bContext *C,
+                                     void *element,
+                                     const char *str,
+                                     uiSearchItems *items)
+{
+  TreeElement *te = (TreeElement *)element;
+  const short type = get_element_type(te);
+
+  merged_element_search_cb_recursive(&te->parent->subtree, type, str, items);
+}
+
+static void merged_element_search_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+  char search = (char *)arg1;
+  search = "";
+  puts("HI");
+
+  TreeElement *te = (TreeElement *)arg2;
+
+  outliner_item_do_activate_from_tree_element(C, te, te->store_elem, false, false);
+}
+
+static uiBlock *merged_element_search_menu(bContext *C, ARegion *ar, void *element)
+{
+  static char search[64] = "";
+  uiBlock *block;
+  uiBut *but;
+
+  short menuwidth = 10 * UI_UNIT_X;
+
+  block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+  UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+  UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+
+  TreeElement *te = (TreeElement *)element;
+
+  but = uiDefSearchBut(
+      block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, menuwidth, UI_UNIT_Y, 0, 0, "");
+  UI_but_func_search_set(
+      but, NULL, merged_element_search_cb, te, false, merged_element_search_call_cb, search);
+  UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
+
+  /* fake button, it holds space for search items */
+  uiDefBut(block,
+           UI_BTYPE_LABEL,
+           0,
+           "",
+           10,
+           10 - UI_searchbox_size_y(),
+           UI_searchbox_size_x(),
+           UI_searchbox_size_y(),
+           NULL,
+           0,
+           0,
+           0,
+           0,
+           NULL);
+
+  /* Move it downwards, mouse over button. */
+  UI_block_bounds_set_popup(block, 6, (const int[2]){-(menuwidth / 2), -UI_UNIT_Y});
+
+  return block;
+}
+
 /**
  * Action to run when clicking in the outliner,
  *
@@ -1413,7 +1518,15 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
   else {
     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]);
+    bool multiple_items = false;
+    TreeElement *activate_te = outliner_find_item_at_x_in_row(
+        soops, te, view_mval[0], &multiple_items);
+
+    if (multiple_items) {
+      UI_popup_block_invoke(C, merged_element_search_menu, activate_te, NULL);
+
+      return OPERATOR_CANCELLED;
+    }
     TreeStoreElem *activate_tselem = TREESTORE(activate_te);
 
     if (use_range) {
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 195b9ea7bab..3e32c76734e 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -63,7 +63,8 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
 }
 
 static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *parent_te,
-                                                             float view_co_x)
+                                                             float view_co_x,
+                                                             bool *r_multiple_objects)
 {
   TreeElement *child_te = parent_te->subtree.first;
 
@@ -74,11 +75,15 @@ static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *
     if ((child_te->flag & TE_ICONROW) && over_element) {
       return child_te;
     }
-    else if ((child_te->flag & TE_ICONROW_MULTI) && over_element) {
+    else if ((child_te->flag & TE_ICONROW_MERGED) && over_element) {
+      if (r_multiple_objects) {
+        *r_multiple_objects = true;
+      }
       return child_te;
     }
 
-    TreeElement *te = outliner_find_item_at_x_in_row_recursive(child_te, view_co_x);
+    TreeElement *te = outliner_find_item_at_x_in_row_recursive(
+        child_te, view_co_x, r_multiple_objects);
     if (te != child_te) {
       return te;
     }
@@ -98,11 +103,12 @@ static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *
  */
 TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops,
                                             const TreeElement *parent_te,
-                                            float view_co_x)
+                                            float view_co_x,
+                                            bool *r_multiple_objects)
 {
   /* if parent_te is opened, it doesn't show children in row */
   if (!TSELEM_OPEN(TREESTORE(parent_te), soops)) {
-    return outliner_find_item_at_x_in_row_recursive(parent_te, view_co_x);
+    return outliner_find_item_at_x_in_row_recursive(parent_te, view_co_x, r_multiple_objects);
   }
 
   return (TreeElement *)parent_te;



More information about the Bf-blender-cvs mailing list