diff options
author | Hans Goudey <h.goudey@me.com> | 2020-09-15 01:36:42 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-09-15 01:36:42 +0300 |
commit | e13e8d727a74a90b8d8d5e527c7ee76afe338a4c (patch) | |
tree | 19d85eabc8db1698e22e3a6147c21452799346af | |
parent | adaf9947b108c6c174114dafe35b39196cfd76f9 (diff) | |
parent | b037801f5ec39e5e1a2a3919797f65a8d16116bf (diff) |
Merge branch 'property-search-all-tabs-v2' into property-search-ui-v2property-search-ui-v2
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 5 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 6 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 17 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 274 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/space_buttons.c | 189 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 1 |
9 files changed, 341 insertions, 173 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 1e6f3ed3af1..dfdce21614c 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -91,6 +91,11 @@ void ED_region_panels_layout_ex(const struct bContext *C, struct ListBase *paneltypes, const char *contexts[], const char *category_override); +bool ED_region_property_search(const struct bContext *C, + struct ARegion *region, + struct ListBase *paneltypes, + const char *contexts[], + const char *category_override); void ED_region_panels_layout(const struct bContext *C, struct ARegion *region); void ED_region_panels_draw(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 fe0a57f26ea..48112e70f7c 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -674,7 +674,6 @@ 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_has_search_filter(const uiBlock *block); 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); @@ -1719,8 +1718,6 @@ struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContex const struct wmEvent *event); void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data); -void UI_region_panels_remove_handlers(const struct bContext *C, struct ARegion *region); - /* Polyinstantiated panels for representing a list of data. */ struct Panel *UI_panel_add_instanced(struct ARegion *region, struct ListBase *panels, @@ -1874,7 +1871,7 @@ 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); -void UI_block_apply_search_filter(uiBlock *block); +bool UI_block_apply_search_filter(uiBlock *block); void UI_region_message_subscribe(struct ARegion *region, struct wmMsgBus *mbus); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 98140a2c058..8aa25100b0b 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3509,11 +3509,6 @@ void UI_block_theme_style_set(uiBlock *block, char theme_style) block->theme_style = theme_style; } -bool UI_block_has_search_filter(const uiBlock *block) -{ - return block->search_filter != NULL && block->search_filter[0] != '\0'; -} - bool UI_block_is_search_only(const uiBlock *block) { return block->flag & UI_BLOCK_SEARCH_ONLY; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 794cb53d5da..213917929e3 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -5311,10 +5311,10 @@ static void block_search_deactivate_buttons(uiBlock *block) * * \note Must be run before #UI_block_layout_resolve. */ -void UI_block_apply_search_filter(uiBlock *block) +bool UI_block_apply_search_filter(uiBlock *block) { if (!(block->search_filter && block->search_filter[0])) { - return; + return false; } const bool panel_label_matches = block_search_panel_label_matches(block); @@ -5330,6 +5330,8 @@ void UI_block_apply_search_filter(uiBlock *block) if (!panel_label_matches) { block_search_deactivate_buttons(block); } + + return has_result; } /** \} */ diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 95b4cbc82cc..51df6ae5676 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -2647,13 +2647,6 @@ static void ui_handler_remove_panel(bContext *C, void *userdata) panel_activate_state(C, panel, PANEL_STATE_EXIT); } -void UI_region_panels_remove_handlers(const bContext *C, ARegion *region) -{ - LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { - panel_activate_state(C, panel, PANEL_STATE_EXIT); - } -} - static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state) { uiHandlePanelData *data = panel->activedata; @@ -2681,13 +2674,11 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS } if (state == PANEL_STATE_EXIT) { - if (data != NULL) { - MEM_freeN(data); - panel->activedata = NULL; + MEM_freeN(data); + panel->activedata = NULL; - WM_event_remove_ui_handler( - &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, panel, false); - } + WM_event_remove_ui_handler( + &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, panel, false); } else { if (!data) { diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 81150d78c9e..229cd80143c 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -2610,6 +2610,8 @@ static void ed_panel_draw(const bContext *C, bool open; panel = UI_panel_begin(region, lb, block, pt, panel, &open); + const bool search_filter_active = search_filter != NULL && search_filter[0] != '\0'; + /* bad fixed values */ int xco, yco, h = 0; int headerend = w - UI_UNIT_X; @@ -2670,7 +2672,7 @@ static void ed_panel_draw(const bContext *C, panel->labelofs = 0; } - if (open || UI_block_has_search_filter(block) || search_only) { + if (open || search_filter_active) { short panelContext; /* panel context can either be toolbar region or normal panels region */ @@ -2710,11 +2712,10 @@ static void ed_panel_draw(const bContext *C, UI_block_end(C, block); /* Draw child panels. */ - if (open || UI_block_has_search_filter(block)) { + if (open || search_filter_active) { LISTBASE_FOREACH (LinkData *, link, &pt->children) { PanelType *child_pt = link->data; Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt); - if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) { ed_panel_draw(C, region, @@ -2734,6 +2735,81 @@ static void ed_panel_draw(const bContext *C, } /** + * Check whether a panel should be added to the region's panel layout. + */ +static bool panel_add_check(const bContext *C, + const WorkSpace *workspace, + const char *contexts[], + const char *category_override, + PanelType *panel_type) +{ + /* Only add top level panels. */ + if (panel_type->parent) { + return false; + } + /* Check the category override first. */ + if (category_override) { + if (!STREQ(panel_type->category, category_override)) { + return false; + } + } + + /* Verify context. */ + if (contexts != NULL && panel_type->context[0]) { + if (!streq_array_any(panel_type->context, contexts)) { + return false; + } + } + + /* If we're tagged, only use compatible. */ + if (panel_type->owner_id[0]) { + if (!BKE_workspace_owner_id_check(workspace, panel_type->owner_id)) { + return false; + } + } + + if (LIKELY(panel_type->draw)) { + if (panel_type->poll && !panel_type->poll(C, panel_type)) { + return false; + } + } + + return true; +} + +static bool region_uses_category_tabs(const ScrArea *area, const ARegion *region) +{ + /* XXX, should use some better check? */ + /* For now also has hardcoded check for clip editor until it supports actual toolbar. */ + return ((1 << region->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) || + (region->regiontype == RGN_TYPE_TOOLS && area->spacetype == SPACE_CLIP); +} + +static const char *region_panels_collect_categories(ARegion *region, + LinkNode *panel_types_stack, + bool *use_category_tabs) +{ + UI_panel_category_clear_all(region); + + /* gather unique categories */ + for (LinkNode *pt_link = panel_types_stack; pt_link; pt_link = pt_link->next) { + PanelType *pt = pt_link->link; + if (pt->category[0]) { + if (!UI_panel_category_find(region, pt->category)) { + UI_panel_category_add(region, pt->category); + } + } + } + + if (UI_panel_category_is_visible(region)) { + return UI_panel_category_active_get(region, true); + } + + *use_category_tabs = false; + return NULL; +} + +/** * \param contexts: A NULL terminated array of context strings to match against. * Matching against any of these strings will draw the panel. * Can be NULL to skip context checks. @@ -2748,29 +2824,7 @@ void ED_region_panels_layout_ex(const bContext *C, WorkSpace *workspace = CTX_wm_workspace(C); LinkNode *panel_types_stack = NULL; LISTBASE_FOREACH_BACKWARD (PanelType *, pt, paneltypes) { - /* Only draw top level panels. */ - if (pt->parent) { - continue; - } - - if (category_override) { - if (!STREQ(pt->category, category_override)) { - continue; - } - } - - /* verify context */ - if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) { - continue; - } - - /* If we're tagged, only use compatible. */ - if (pt->owner_id[0] && BKE_workspace_owner_id_check(workspace, pt->owner_id) == false) { - continue; - } - - /* draw panel */ - if (pt->draw && (!pt->poll || pt->poll(C, pt))) { + if (panel_add_check(C, workspace, contexts, category_override, pt)) { BLI_linklist_prepend_alloca(&panel_types_stack, pt); } } @@ -2781,12 +2835,7 @@ void ED_region_panels_layout_ex(const bContext *C, View2D *v2d = ®ion->v2d; int x, y, w, em; - /* XXX, should use some better check? */ - /* For now also has hardcoded check for clip editor until it supports actual toolbar. */ - bool use_category_tabs = (category_override == NULL) && - ((((1 << region->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) || - (region->regiontype == RGN_TYPE_TOOLS && - area->spacetype == SPACE_CLIP))); + bool use_category_tabs = (category_override == NULL) && region_uses_category_tabs(area, region); /* offset panels for small vertical tab area */ const char *category = NULL; const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH; @@ -2802,25 +2851,10 @@ void ED_region_panels_layout_ex(const bContext *C, /* collect categories */ if (use_category_tabs) { - UI_panel_category_clear_all(region); - - /* gather unique categories */ - for (LinkNode *pt_link = panel_types_stack; pt_link; pt_link = pt_link->next) { - PanelType *pt = pt_link->link; - if (pt->category[0]) { - if (!UI_panel_category_find(region, pt->category)) { - UI_panel_category_add(region, pt->category); - } - } - } - - if (!UI_panel_category_is_visible(region)) { - use_category_tabs = false; - } - else { - category = UI_panel_category_active_get(region, true); - margin_x = category_tabs_width; - } + category = region_panels_collect_categories(region, panel_types_stack, &use_category_tabs); + } + if (use_category_tabs) { + margin_x = category_tabs_width; } w = BLI_rctf_size_x(&v2d->cur); @@ -3034,6 +3068,144 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *region) WM_event_add_keymap_handler(®ion->handlers, keymap); } +static bool panel_property_search(const bContext *C, + ARegion *region, + const uiStyle *style, + Panel *panel, + PanelType *panel_type, + const char *search_filter) +{ + uiBlock *block = UI_block_begin(C, region, panel_type->idname, UI_EMBOSS); + UI_block_set_search_only(block, true); + UI_block_set_search_filter(block, search_filter); + + if (panel == NULL) { + bool open; + panel = UI_panel_begin(region, ®ion->panels, block, panel_type, panel, &open); + } + + /* Build the layouts. Because they are only used for search, + * they don't need any of the proper style or layout information. */ + if (panel->type->draw_header_preset != NULL) { + panel->layout = UI_block_layout( + block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, 0, 0, 0, 0, 0, style); + uiLayoutRootSetSearchOnly(panel->layout, true); + panel_type->draw_header_preset(C, panel); + } + if (panel->type->draw_header != NULL) { + panel->layout = UI_block_layout( + block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, 0, 0, 0, 0, 0, style); + uiLayoutRootSetSearchOnly(panel->layout, true); + panel_type->draw_header(C, panel); + } + if (LIKELY(panel->type->draw != NULL)) { + panel->layout = UI_block_layout( + block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 0, 0, 0, style); + uiLayoutRootSetSearchOnly(panel->layout, true); + panel_type->draw(C, panel); + } + + /* We could check after each layout to increase the likelyhood of returning early, + * but that probably wouldn't make much of a difference anyway. */ + if (UI_block_apply_search_filter(block)) { + return true; + } + + LISTBASE_FOREACH (LinkData *, link, &panel_type->children) { + PanelType *panel_type_child = link->data; + if (LIKELY(panel->type->draw != NULL)) { + if (!panel_type_child->poll || panel_type_child->poll(C, panel_type_child)) { + /* Search for the existing child panel here because it might be an instanced + * child panel with a custom data field that will be needed to build the layout. */ + Panel *child_panel = UI_panel_find_by_type(&panel->children, panel_type_child); + if (panel_property_search( + C, region, style, child_panel, panel_type_child, search_filter)) { + return true; + } + } + } + } + + return false; +} + +bool ED_region_property_search(const bContext *C, + ARegion *region, + ListBase *paneltypes, + const char *contexts[], + const char *category_override) +{ + ScrArea *area = CTX_wm_area(C); + WorkSpace *workspace = CTX_wm_workspace(C); + const uiStyle *style = UI_style_get_dpi(); + const char *search_filter = ED_area_search_filter_get(area, region); + + LinkNode *panel_types_stack = NULL; + LISTBASE_FOREACH_BACKWARD (PanelType *, pt, paneltypes) { + if (panel_add_check(C, workspace, contexts, category_override, pt)) { + BLI_linklist_prepend_alloca(&panel_types_stack, pt); + } + } + + const char *category = NULL; + bool use_category_tabs = (category_override == NULL) && region_uses_category_tabs(area, region); + if (use_category_tabs) { + category = region_panels_collect_categories(region, panel_types_stack, &use_category_tabs); + } + + /* Run property search for each panel, stopping if a result is found. */ + bool has_result = true; + bool has_instanced_panel = false; + for (LinkNode *pt_link = panel_types_stack; pt_link; pt_link = pt_link->next) { + PanelType *panel_type = pt_link->link; + /* Note that these checks are duplicated from #ED_region_panels_layout_ex. */ + if (panel_type->flag & PNL_INSTANCED) { + has_instanced_panel = true; + continue; + } + + if (use_category_tabs) { + if (panel_type->category[0] && !STREQ(category, panel_type->category)) { + continue; + } + } + + /* We start property search with an empty panel list, so there's + * no point in trying to find an existing panel with this type. */ + has_result = panel_property_search(C, region, style, NULL, panel_type, search_filter); + if (has_result) { + break; + } + } + + /* Run property search for instanced panels (created in the layout calls of previous panels). */ + if (!has_result && has_instanced_panel) { + LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { + /* Note that these checks are duplicated from #ED_region_panels_layout_ex. */ + if (panel->type == NULL || !(panel->type->flag & PNL_INSTANCED)) { + continue; + } + if (use_category_tabs) { + if (panel->type->category[0] && !STREQ(category, panel->type->category)) { + continue; + } + } + + has_result = panel_property_search(C, region, style, panel, panel->type, search_filter); + if (has_result) { + break; + } + } + } + + /* Free the panels and blocks, as they are only used for search. */ + UI_blocklist_free(C, ®ion->uiblocks); + UI_panels_free_instanced(C, region); + BKE_area_region_panels_free(®ion->panels); + + return has_result; +} + void ED_region_header_layout(const bContext *C, ARegion *region) { const uiStyle *style = UI_style_get_dpi(); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index d5cd546e587..cbcf03e30f2 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -111,8 +111,7 @@ static void buttons_free(SpaceLink *sl) MEM_freeN(ct); } - BLI_assert(sbuts->runtime != NULL); - MEM_freeN(sbuts->runtime); + MEM_SAFE_FREE(sbuts->runtime); } /* spacetype; init callback */ @@ -242,80 +241,71 @@ int ED_buttons_tabs_list(SpaceProperties *sbuts, int *context_tabs_array) return length; } -static void buttons_main_region_layout_properties(const bContext *C, - SpaceProperties *sbuts, - ARegion *region) +static const char *buttons_main_region_context_string(const short mainb) { - buttons_context_compute(C, sbuts); - - const char *contexts[2] = {NULL, NULL}; - - switch (sbuts->mainb) { + switch (mainb) { case BCONTEXT_SCENE: - contexts[0] = "scene"; - break; + return "scene"; case BCONTEXT_RENDER: - contexts[0] = "render"; - break; + return "render"; case BCONTEXT_OUTPUT: - contexts[0] = "output"; - break; + return "output"; case BCONTEXT_VIEW_LAYER: - contexts[0] = "view_layer"; - break; + return "view_layer"; case BCONTEXT_WORLD: - contexts[0] = "world"; - break; + return "world"; case BCONTEXT_OBJECT: - contexts[0] = "object"; - break; + return "object"; case BCONTEXT_DATA: - contexts[0] = "data"; - break; + return "data"; case BCONTEXT_MATERIAL: - contexts[0] = "material"; - break; + return "material"; case BCONTEXT_TEXTURE: - contexts[0] = "texture"; - break; + return "texture"; case BCONTEXT_PARTICLE: - contexts[0] = "particle"; - break; + return "particle"; case BCONTEXT_PHYSICS: - contexts[0] = "physics"; - break; + return "physics"; case BCONTEXT_BONE: - contexts[0] = "bone"; - break; + return "bone"; case BCONTEXT_MODIFIER: - contexts[0] = "modifier"; - break; + return "modifier"; case BCONTEXT_SHADERFX: - contexts[0] = "shaderfx"; - break; + return "shaderfx"; case BCONTEXT_CONSTRAINT: - contexts[0] = "constraint"; - break; + return "constraint"; case BCONTEXT_BONE_CONSTRAINT: - contexts[0] = "bone_constraint"; - break; + return "bone_constraint"; case BCONTEXT_TOOL: - contexts[0] = "tool"; - break; + return "tool"; } + /* All the cases should be handled. */ + BLI_assert(false); + return ""; +} + +static void buttons_main_region_layout_properties(const bContext *C, + SpaceProperties *sbuts, + ARegion *region) +{ + buttons_context_compute(C, sbuts); + + const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL}; + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, contexts, NULL); } -static void main_region_layout_current_context(const bContext *C, - SpaceProperties *sbuts, - ARegion *region) +static bool property_search_for_context(const bContext *C, ARegion *region, SpaceProperties *sbuts) { + const char *contexts[2] = {buttons_main_region_context_string(sbuts->mainb), NULL}; + if (sbuts->mainb == BCONTEXT_TOOL) { - ED_view3d_buttons_region_layout_ex(C, region, "Tool"); + return false; } else { - buttons_main_region_layout_properties(C, sbuts, region); + buttons_context_compute(C, sbuts); + return ED_region_property_search(C, region, ®ion->type->paneltypes, contexts, NULL); } } @@ -333,7 +323,7 @@ static void property_search_move_to_next_tab_with_results(SpaceProperties *sbuts /* Try the tabs after the current tab. */ for (int i = current_tab_index; i < tabs_len; i++) { - if (sbuts->context_search_filter_active & (1 << i)) { + if (sbuts->runtime->context_search_filter_active & (1 << i)) { sbuts->mainbuser = context_tabs_array[i]; return; } @@ -341,7 +331,7 @@ static void property_search_move_to_next_tab_with_results(SpaceProperties *sbuts /* Try the tabs before the current tab. */ for (int i = 0; i < current_tab_index; i++) { - if (sbuts->context_search_filter_active & (1 << i)) { + if (sbuts->runtime->context_search_filter_active & (1 << i)) { sbuts->mainbuser = context_tabs_array[i]; return; } @@ -350,66 +340,41 @@ static void property_search_move_to_next_tab_with_results(SpaceProperties *sbuts static void property_search_all_tabs(const bContext *C, SpaceProperties *sbuts, - ARegion *main_region) + ARegion *main_region, + const int *context_tabs_array, + const int tabs_len) { - sbuts->context_search_filter_active = 0; + sbuts->runtime->context_search_filter_active = 0; /* Duplicate space and region so we don't change any data for this space. */ ScrArea *area_copy = MEM_dupallocN(CTX_wm_area(C)); - ARegion *region_copy = BKE_area_region_copy(CTX_wm_area(C)->type, main_region); + ARegion *region_copy = BKE_area_region_copy(area_copy->type, main_region); BKE_area_region_panels_free(®ion_copy->panels); bContext *C_copy = CTX_copy(C); CTX_wm_area_set(C_copy, area_copy); CTX_wm_region_set(C_copy, region_copy); SpaceProperties *sbuts_copy = MEM_dupallocN(sbuts); - int context_tabs_array[32]; - int tabs_tot = ED_buttons_tabs_list(sbuts, context_tabs_array); - - bool current_tab_has_search_match = false; - /* Loop through the tabs added to the properties editor. */ - for (int i = 0; i < tabs_tot; i++) { + for (int i = 0; i < tabs_len; i++) { + /* -1 corresponds to a spacer. */ if (context_tabs_array[i] == -1) { continue; } - /* Run the layout with this tab set active. */ - sbuts_copy->mainb = sbuts->mainbo = sbuts_copy->mainbuser = context_tabs_array[i]; - - /* Run the layout for the actual region if the tab matches to avoid doing it again later on. */ - const bool use_actual_region = sbuts->mainb == sbuts_copy->mainb; - if (use_actual_region) { - main_region_layout_current_context(C, sbuts, main_region); - } - else { - main_region_layout_current_context(C_copy, sbuts_copy, region_copy); - } - - /* Store whether this tab has any unfiltered panels left. */ - bool tab_has_search_match = false; - LISTBASE_FOREACH ( - Panel *, panel, use_actual_region ? &main_region->panels : ®ion_copy->panels) { - tab_has_search_match |= UI_panel_matches_search_filter(panel) && UI_panel_is_active(panel); - } - if (tab_has_search_match) { - sbuts->context_search_filter_active |= (1 << i); - if (use_actual_region) { - current_tab_has_search_match = tab_has_search_match; - } + /* Handle search for the current tab later in the normal layout pass. */ + if (context_tabs_array[i] == sbuts->mainb) { + continue; } - /* Free data created during the layout process. */ - UI_region_panels_remove_handlers(C_copy, region_copy); - BKE_area_region_panels_free(®ion_copy->panels); - UI_blocklist_free(C_copy, ®ion_copy->uiblocks); - } + sbuts_copy->mainb = sbuts_copy->mainbo = sbuts_copy->mainbuser = context_tabs_array[i]; - if (!current_tab_has_search_match && main_region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) { - property_search_move_to_next_tab_with_results(sbuts, context_tabs_array, tabs_tot); + SET_FLAG_FROM_TEST(sbuts->runtime->context_search_filter_active, + property_search_for_context(C_copy, region_copy, sbuts_copy), + (1 << i)); } - BKE_area_region_free(CTX_wm_area(C_copy)->type, region_copy); + BKE_area_region_free(area_copy->type, region_copy); MEM_freeN(region_copy); MEM_freeN(sbuts_copy); MEM_freeN(area_copy); @@ -421,11 +386,47 @@ static void buttons_main_region_layout(const bContext *C, ARegion *region) /* draw entirely, view changes should be handled here */ SpaceProperties *sbuts = CTX_wm_space_properties(C); - if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) { - property_search_all_tabs(C, sbuts, region); + if (sbuts->mainb == BCONTEXT_TOOL) { + ED_view3d_buttons_region_layout_ex(C, region, "Tool"); } else { - main_region_layout_current_context(C, sbuts, region); + buttons_main_region_layout_properties(C, sbuts, region); + } + + if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) { + int context_tabs_array[32]; + int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array); + + property_search_all_tabs(C, sbuts, region, context_tabs_array, tabs_len); + + /* Check whether the current tab has a search match. */ + bool current_tab_has_search_match = false; + LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { + if (UI_panel_is_active(panel) && UI_panel_matches_search_filter(panel)) { + current_tab_has_search_match = true; + } + } + + /* Find which index in the list the current tab corresponds to. */ + int current_tab_index = -1; + for (int i = 0; i < tabs_len; i++) { + if (context_tabs_array[i] == sbuts->mainb) { + current_tab_index = i; + } + } + BLI_assert(current_tab_index != -1); + + /* Update the tab search match flag for the current tab. */ + SET_FLAG_FROM_TEST(sbuts->runtime->context_search_filter_active, + current_tab_has_search_match, + (1 << current_tab_index)); + + /* Move to the next tab with a result */ + if (!current_tab_has_search_match) { + if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) { + property_search_move_to_next_tab_with_results(sbuts, context_tabs_array, tabs_len); + } + } } sbuts->mainbo = sbuts->mainb; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 827c233f99e..86218eaaf03 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -132,6 +132,13 @@ typedef enum eSpaceInfo_RptMask { typedef struct SpaceProperties_Runtime { /** For filtering properties displayed in the space. Length defined as UI_MAX_NAME_STR. */ char search_string[128]; + /** + * Bitfield flag (in the same order as the tabs) for whether each tab has properties + * that match the search filter. Only valid when #search_string is set. + */ + int context_search_filter_active; + + char _pad[4]; } SpaceProperties_Runtime; /* Properties Editor */ @@ -152,12 +159,9 @@ typedef struct SpaceProperties { /** Context tabs. */ short mainb, mainbo, mainbuser; - /** Runtime. Bitfield flag (in the same order as the tabs) for whether each tab has properties - * that match the search filter. Only valid when #search_string is set. */ - int context_search_filter_active; /** Preview is signal to refresh. */ short preview; - char _pad[1]; + char _pad[5]; char flag; /** Runtime. */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 74a18f98e25..49538c4e2b9 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4496,6 +4496,7 @@ static void rna_def_space_properties(BlenderRNA *brna) /* Property search. */ prop = RNA_def_property(srna, "context_search_filter_active", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "runtime->context_search_filter_active"); RNA_def_property_enum_items(prop, buttons_context_items); RNA_def_property_flag(prop, PROP_ENUM_FLAG); RNA_def_property_enum_funcs( |