Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-09-15 01:36:42 +0300
committerHans Goudey <h.goudey@me.com>2020-09-15 01:36:42 +0300
commite13e8d727a74a90b8d8d5e527c7ee76afe338a4c (patch)
tree19d85eabc8db1698e22e3a6147c21452799346af
parentadaf9947b108c6c174114dafe35b39196cfd76f9 (diff)
parentb037801f5ec39e5e1a2a3919797f65a8d16116bf (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.h5
-rw-r--r--source/blender/editors/include/UI_interface.h5
-rw-r--r--source/blender/editors/interface/interface.c5
-rw-r--r--source/blender/editors/interface/interface_layout.c6
-rw-r--r--source/blender/editors/interface/interface_panel.c17
-rw-r--r--source/blender/editors/screen/area.c274
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c189
-rw-r--r--source/blender/makesdna/DNA_space_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_space.c1
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, &region->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 = &region->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(&region->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, &region->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, &region->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, &region->uiblocks);
+ UI_panels_free_instanced(C, region);
+ BKE_area_region_panels_free(&region->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, &region->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, &region->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(&region_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 : &region_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(&region_copy->panels);
- UI_blocklist_free(C_copy, &region_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, &region->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(