[Bf-blender-cvs] [8bcdcab659f] master: UI: Single tab property search

Hans Goudey noreply at git.blender.org
Tue Sep 15 18:25:59 CEST 2020


Commit: 8bcdcab659fb688d976a50d892dcb4285ff2a180
Author: Hans Goudey
Date:   Tue Sep 15 11:25:49 2020 -0500
Branches: master
https://developer.blender.org/rB8bcdcab659fb688d976a50d892dcb4285ff2a180

UI: Single tab property search

This adds a search bar to the properties editor. The full search for
every tab isn't included in this patch, but the interaction with
panels, searching behavior, UI, region level, and DNA changes are
included here.

The block-level search works by iterating over the block's button
groups and checking whether they match the search. If they do, they
are tagged with a flag, and the block's panel is tagged too. For
every update (text edit), the panel's expansion is set to whether
the panel has a result or not. The search also checks for matching
strings inside enums and in panel labels.

One complication to this that isn't immediately apparent is that
closed panel's subpanels have to be searched too. This adds some
complexity to the area-level panel layout code.

Possible Future Improvements:
 - Use the new fuzzy search in BLI
 - Reset panels to their expansion before the search started if
   the user escape out of the text box.
 - Open all child panels of a panel with expansion.

Differential Revision: https://developer.blender.org/D8856

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

M	release/scripts/startup/bl_ui/space_properties.py
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/space_buttons/space_buttons.c
M	source/blender/makesdna/DNA_screen_types.h
M	source/blender/makesdna/DNA_space_types.h
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py
index 53b67a20115..ff25b8cd2fa 100644
--- a/release/scripts/startup/bl_ui/space_properties.py
+++ b/release/scripts/startup/bl_ui/space_properties.py
@@ -31,6 +31,10 @@ class PROPERTIES_HT_header(Header):
 
         layout.separator_spacer()
 
+        layout.prop(view, "search_filter", icon='VIEWZOOM', text="")
+
+        layout.separator_spacer()
+
         row = layout.row()
         row.emboss = 'NONE'
         row.operator("buttons.toggle_pin", icon=('PINNED' if view.use_pin_id else 'UNPINNED'), text="")
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 38dc63af1fe..1a9abe99012 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4924,6 +4924,9 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
 
   BLO_read_list(reader, &region->ui_lists);
 
+  /* The area's search filter is runtime only, so we need to clear the active flag on read. */
+  region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE;
+
   LISTBASE_FOREACH (uiList *, ui_list, &region->ui_lists) {
     ui_list->type = NULL;
     ui_list->dyn_data = NULL;
@@ -5164,6 +5167,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
       sbuts->texuser = NULL;
       sbuts->mainbo = sbuts->mainb;
       sbuts->mainbuser = sbuts->mainb;
+      sbuts->runtime = NULL;
     }
     else if (sl->spacetype == SPACE_CONSOLE) {
       SpaceConsole *sconsole = (SpaceConsole *)sl;
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index d9c7128c2ee..53554e3f34c 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -80,6 +80,10 @@ void ED_region_tag_redraw_no_rebuild(struct ARegion *region);
 void ED_region_tag_refresh_ui(struct ARegion *region);
 void ED_region_tag_redraw_editor_overlays(struct ARegion *region);
 
+void ED_region_search_filter_update(const struct ScrArea *area, struct ARegion *region);
+const char *ED_area_region_search_filter_get(const struct ScrArea *area,
+                                             const struct ARegion *region);
+
 void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *region);
 void ED_region_panels_ex(const struct bContext *C, struct ARegion *region, const char *contexts[]);
 void ED_region_panels(const struct bContext *C, struct ARegion *region);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index d5d489b1742..6a0b643fb84 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -157,6 +157,9 @@ enum {
   UI_BLOCK_POPOVER_ONCE = 1 << 22,
   /** Always show keymaps, even for non-menus. */
   UI_BLOCK_SHOW_SHORTCUT_ALWAYS = 1 << 23,
+  /** The block is only used during the search process and will not be drawn.
+   * Currently just for the case of a closed panel's subpanel (and its subpanels). */
+  UI_BLOCK_SEARCH_ONLY = 1 << 25,
 };
 
 /** #uiPopupBlockHandle.menuretval */
@@ -671,6 +674,9 @@ enum {
 void UI_block_theme_style_set(uiBlock *block, char theme_style);
 char UI_block_emboss_get(uiBlock *block);
 void UI_block_emboss_set(uiBlock *block, char emboss);
+bool UI_block_is_search_only(const uiBlock *block);
+void UI_block_set_search_only(uiBlock *block, bool search_only);
+void UI_block_set_search_filter(uiBlock *block, const char *search_filter);
 
 void UI_block_free(const struct bContext *C, uiBlock *block);
 void UI_blocklist_free(const struct bContext *C, struct ListBase *lb);
@@ -1684,6 +1690,8 @@ void UI_panels_scale(struct ARegion *region, float new_width);
 void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y);
 int UI_panel_size_y(const struct Panel *panel);
 bool UI_panel_is_dragging(const struct Panel *panel);
+bool UI_panel_matches_search_filter(const struct Panel *panel);
+void UI_panels_set_expansion_from_seach_filter(const struct bContext *C, struct ARegion *region);
 
 bool UI_panel_category_is_visible(const struct ARegion *region);
 void UI_panel_category_add(struct ARegion *region, const char *name);
@@ -1862,6 +1870,8 @@ uiLayout *UI_block_layout(uiBlock *block,
 void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
 void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y);
 
+bool UI_block_apply_search_filter(uiBlock *block);
+
 void UI_region_message_subscribe(struct ARegion *region, struct wmMsgBus *mbus);
 
 uiBlock *uiLayoutGetBlock(uiLayout *layout);
@@ -1914,6 +1924,7 @@ float uiLayoutGetUnitsY(uiLayout *layout);
 int uiLayoutGetEmboss(uiLayout *layout);
 bool uiLayoutGetPropSep(uiLayout *layout);
 bool uiLayoutGetPropDecorate(uiLayout *layout);
+void uiLayoutRootSetSearchOnly(uiLayout *layout, bool search_only);
 
 /* layout specifiers */
 uiLayout *uiLayoutRow(uiLayout *layout, bool align);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b9a001a9571..5d20846c528 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1995,8 +1995,12 @@ void UI_block_draw(const bContext *C, uiBlock *block)
         }
       }
     }
-    ui_draw_aligned_panel(
-        &style, block, &rect, UI_panel_category_is_visible(region), show_background);
+    ui_draw_aligned_panel(&style,
+                          block,
+                          &rect,
+                          UI_panel_category_is_visible(region),
+                          show_background,
+                          region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE);
   }
 
   BLF_batch_draw_begin();
@@ -3541,6 +3545,25 @@ void UI_block_theme_style_set(uiBlock *block, char theme_style)
   block->theme_style = theme_style;
 }
 
+bool UI_block_is_search_only(const uiBlock *block)
+{
+  return block->flag & UI_BLOCK_SEARCH_ONLY;
+}
+
+/**
+ * Use when a block must be searched to give accurate results
+ * for the whole region but shouldn't be displayed.
+ */
+void UI_block_set_search_only(uiBlock *block, bool search_only)
+{
+  SET_FLAG_FROM_TEST(block->flag, search_only, UI_BLOCK_SEARCH_ONLY);
+}
+
+void UI_block_set_search_filter(uiBlock *block, const char *search_filter)
+{
+  block->search_filter = search_filter;
+}
+
 static void ui_but_build_drawstr_float(uiBut *but, double value)
 {
   size_t slen = 0;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index edaadd880d7..d62b8a0258a 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -81,6 +81,11 @@ enum {
   UI_HAS_ICON = (1 << 3),
   UI_HIDDEN = (1 << 4),
   UI_SELECT_DRAW = (1 << 5), /* Display selected, doesn't impact interaction. */
+  /**
+   * The button matches the search filter. When property search is active, this
+   * is used to determine which items to keep enabled and which to disable.
+   */
+  UI_SEARCH_FILTER_MATCHES = (1 << 12),
   /* warn: rest of uiBut->flag in UI_interface.h */
 };
 
@@ -517,6 +522,12 @@ struct uiBlock {
    */
   char display_device[64];
 
+  /**
+   * Pointer to the space's property search string.
+   * The block doesn't allocate this or change it.
+   */
+  const char *search_filter;
+
   struct PieMenuData pie_data;
 };
 
@@ -805,7 +816,9 @@ extern void ui_draw_aligned_panel(const struct uiStyle *style,
                                   const uiBlock *block,
                                   const rcti *rect,
                                   const bool show_pin,
-                                  const bool show_background);
+                                  const bool show_background,
+                                  const bool region_search_filter_active);
+void ui_panel_set_search_filter_match(struct Panel *panel, const bool value);
 
 /* interface_draw.c */
 extern void ui_draw_dropshadow(
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index c3bcaff0d0c..38f2a2fb3c0 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -97,6 +97,13 @@ typedef struct uiLayoutRoot {
   int type;
   int opcontext;
 
+  /**
+   * If true, the root will be removed as part of the property search process.
+   * Necessary for cases like searching the contents of closed panels, where the
+   * block-level tag isn't enough, as there might be visible buttons in the header.
+   */
+  bool search_only;
+
   ListBase button_groups; /* #uiButtonGroup. */
 
   int emw, emh;
@@ -5132,6 +5139,208 @@ int uiLayoutGetEmboss(uiLayout *layout)
   return layout->emboss;
 }
 
+/**
+ * Tags the layout root as search only, meaning the search process will run, but not the rest of
+ * the layout process. Use in situations where part of the block's contents normally wouldn't be
+ * drawn, but must be searched anyway, like the contents of closed panels with headers.
+ */
+void uiLayoutRootSetSearchOnly(uiLayout *layout, bool search_only)
+{
+  layout->root->search_only = search_only;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Block Layout Search Filtering
+ * \{ */
+
+/* Disabled for performance reasons, but this could be turned on in the future. */
+// #define PROPERTY_SEARCH_USE_TOOLTIPS
+
+static bool block_search_panel_label_matches(const uiBlock *block)
+{
+  if ((block->panel != NULL) && (block->panel->type != NULL)) {
+    if (BLI_strcasestr(block->panel->type->label, block->search_filter)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * Buttons for search only layouts (closed panel subpanels) have still been added from the
+ * layout functions, but they need to be hidden. Theoretically they could be removed too.
+ */
+static void layout_free_and_hide_buttons(uiLayout *layout)
+{
+  LISTBASE_FOREACH_MUTABLE (uiItem *, item, &layout->items) {
+    if (item->type == ITEM_BUTTON) {
+      uiButtonItem *b

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list