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:
-rw-r--r--source/blender/editors/include/ED_screen.h5
-rw-r--r--source/blender/editors/include/UI_interface.h3
-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/screen/area.c263
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c163
6 files changed, 298 insertions, 147 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..6655db3395c 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);
@@ -1874,7 +1873,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 b528f9e29b2..2310eca777d 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5307,10 +5307,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);
@@ -5326,6 +5326,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/screen/area.c b/source/blender/editors/screen/area.c
index 171d6105547..e4dccea279e 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,7 +2712,7 @@ 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);
@@ -2734,6 +2736,79 @@ 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)
+{
+ 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 +2823,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);
}
}
@@ -2783,10 +2836,7 @@ void ED_region_panels_layout_ex(const bContext *C,
/* 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 +2852,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 +3069,138 @@ 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);
+ }
+
+ /* Check after each layout to increase the likelyhood of returning early. */
+ 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 (UI_block_apply_search_filter(block)) {
+ return true;
+ }
+ }
+
+ 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 (UI_block_apply_search_filter(block)) {
+ return true;
+ }
+ }
+
+ 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);
+ 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)) {
+ if (panel_property_search(C, region, style, NULL, 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(CTX_wm_area(C), 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);
+ }
+
+ 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;
+
+ 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;
+ }
+ }
+
+ has_result = panel_property_search(C, region, style, NULL, panel_type, search_filter);
+ if (has_result) {
+ break;
+ }
+ }
+
+ if (!has_result && has_instanced_panel) {
+ LISTBASE_FOREACH (Panel *, panel, &region->panels) {
+ 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;
+ }
+ }
+ }
+
+ 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 2cb706b97f6..cd31598b0e6 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -232,80 +232,70 @@ 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, const short mainb)
{
- if (sbuts->mainb == BCONTEXT_TOOL) {
- ED_view3d_buttons_region_layout_ex(C, region, "Tool");
+ const char *contexts[2] = {buttons_main_region_context_string(mainb), NULL};
+
+ if (mainb == BCONTEXT_TOOL) {
+ return false;
}
else {
- buttons_main_region_layout_properties(C, sbuts, region);
+ return ED_region_property_search(C, region, &region->type->paneltypes, contexts, NULL);
}
}
@@ -340,66 +330,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;
/* 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);
- BKE_area_region_panels_free(&region_copy->panels);
+ BLI_listbase_clear(&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->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->context_search_filter_active,
+ property_search_for_context(C_copy, region_copy, sbuts_copy->mainb),
+ (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);
@@ -411,11 +376,29 @@ 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);
+
+ 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;
+ }
+ }
+
+ if (!current_tab_has_search_match && 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;