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--release/scripts/startup/bl_ui/space_properties.py6
-rw-r--r--source/blender/editors/include/ED_buttons.h5
-rw-r--r--source/blender/editors/include/ED_screen.h5
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/interface/interface_layout.c13
-rw-r--r--source/blender/editors/screen/area.c146
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h11
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c174
-rw-r--r--source/blender/makesdna/DNA_space_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_space.c64
10 files changed, 423 insertions, 14 deletions
diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py
index ff25b8cd2fa..fe5057bed5d 100644
--- a/release/scripts/startup/bl_ui/space_properties.py
+++ b/release/scripts/startup/bl_ui/space_properties.py
@@ -53,7 +53,11 @@ class PROPERTIES_PT_navigation_bar(Panel):
layout.scale_x = 1.4
layout.scale_y = 1.4
- layout.prop_tabs_enum(view, "context", icon_only=True)
+ if view.search_filter:
+ layout.prop_tabs_enum(view, "context", data_highlight=view,
+ property_highlight="tab_search_results", icon_only=True)
+ else:
+ layout.prop_tabs_enum(view, "context", icon_only=True)
classes = (
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index a4cd2525af3..5d153757900 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -29,6 +29,11 @@ extern "C" {
struct SpaceProperties;
int ED_buttons_tabs_list(struct SpaceProperties *sbuts, short *context_tabs_array);
+bool ED_buttons_tab_has_search_result(struct SpaceProperties *sbuts, const int index);
+
+void ED_buttons_search_string_set(struct SpaceProperties *sbuts, const char *value);
+int ED_buttons_search_string_length(struct SpaceProperties *sbuts);
+const char *ED_buttons_search_string_get(struct SpaceProperties *sbuts);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 53554e3f34c..b8500ba0c37 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -92,6 +92,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 94095d04271..2c8518de700 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1874,6 +1874,7 @@ uiLayout *UI_block_layout(uiBlock *block,
const struct uiStyle *style);
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_layout_free(uiBlock *block);
bool UI_block_apply_search_filter(uiBlock *block, const char *search_filter);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 98b1c020d95..3e276a69277 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5600,6 +5600,19 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
layout->root->argv = argv;
}
+/**
+ * Used for property search when the layout process needs to be cancelled in order to avoid
+ * computing the locations for buttons, but the layout items created while adding the buttons
+ * must still be freed.
+ */
+void UI_block_layout_free(uiBlock *block)
+{
+ LISTBASE_FOREACH_MUTABLE (uiLayoutRoot *, root, &block->layouts) {
+ ui_layout_free(root->layout);
+ MEM_freeN(root);
+ }
+}
+
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
{
BLI_assert(block->active);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 6fa9d203bba..fd94eea337f 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -48,6 +48,7 @@
#include "WM_toolsystem.h"
#include "WM_types.h"
+#include "ED_buttons.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
@@ -765,7 +766,7 @@ const char *ED_area_region_search_filter_get(const ScrArea *area, const ARegion
if (area->spacetype == SPACE_PROPERTIES) {
SpaceProperties *sbuts = area->spacedata.first;
if (region->regiontype == RGN_TYPE_WINDOW) {
- return sbuts->runtime->search_string;
+ return ED_buttons_search_string_get(sbuts);
}
}
@@ -3074,6 +3075,149 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
+/**
+ * Check whether any of the buttons generated by the \a panel_type's
+ * layout callbacks match the \a search_filter.
+ *
+ * \param panel: If non-NULL, use this instead of adding a new panel for the \a panel_type.
+ */
+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);
+
+ if (panel == NULL) {
+ bool open; /* Dummy variable. */
+ 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);
+ 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);
+ 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);
+ panel_type->draw(C, panel);
+ }
+
+ UI_block_layout_free(block);
+
+ /* 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, search_filter)) {
+ return true;
+ }
+
+ LISTBASE_FOREACH (LinkData *, link, &panel_type->children) {
+ PanelType *panel_type_child = link->data;
+ 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;
+}
+
+/**
+ * Build the same panel list as #ED_region_panels_layout_ex and checks whether any
+ * of the panels contain a search result based on the area / region's search filter.
+ */
+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_region_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/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index a5419fea5ca..0a0846cf216 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -23,6 +23,7 @@
#pragma once
+#include "BLI_bitmap.h"
#include "DNA_listBase.h"
#include "RNA_types.h"
@@ -37,6 +38,16 @@ struct bNodeTree;
struct uiLayout;
struct wmOperatorType;
+struct SpaceProperties_Runtime {
+ /** For filtering properties displayed in the space. */
+ char search_string[UI_MAX_NAME_STR];
+ /**
+ * Bitfield (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.
+ */
+ BLI_bitmap *tab_search_results;
+};
+
/* context data */
typedef struct ButsContextPath {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 8c1030f6fc4..e7f057683ab 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -48,6 +49,7 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "UI_interface.h"
#include "UI_resources.h"
#include "buttons_intern.h" /* own include */
@@ -110,7 +112,10 @@ static void buttons_free(SpaceLink *sl)
MEM_freeN(ct);
}
- MEM_SAFE_FREE(sbuts->runtime);
+ if (sbuts->runtime != NULL) {
+ MEM_SAFE_FREE(sbuts->runtime->tab_search_results);
+ MEM_freeN(sbuts->runtime);
+ }
}
/* spacetype; init callback */
@@ -121,6 +126,7 @@ static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
if (sbuts->runtime == NULL) {
sbuts->runtime = MEM_mallocN(sizeof(SpaceProperties_Runtime), __func__);
sbuts->runtime->search_string[0] = '\0';
+ sbuts->runtime->tab_search_results = BLI_BITMAP_NEW(BCONTEXT_TOT * 2, __func__);
}
}
@@ -135,6 +141,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
if (sfile_old->runtime != NULL) {
sbutsn->runtime = MEM_dupallocN(sfile_old->runtime);
sbutsn->runtime->search_string[0] = '\0';
+ sbutsn->runtime->tab_search_results = BLI_BITMAP_NEW(BCONTEXT_TOT, __func__);
}
return (SpaceLink *)sbutsn;
@@ -298,6 +305,163 @@ static void buttons_main_region_layout_properties(const bContext *C,
ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
}
+const char *ED_buttons_search_string_get(SpaceProperties *sbuts)
+{
+ return sbuts->runtime->search_string;
+}
+
+int ED_buttons_search_string_length(struct SpaceProperties *sbuts)
+{
+ return BLI_strnlen(sbuts->runtime->search_string, sizeof(sbuts->runtime->search_string));
+}
+
+void ED_buttons_search_string_set(SpaceProperties *sbuts, const char *value)
+{
+ BLI_strncpy(sbuts->runtime->search_string, value, sizeof(sbuts->runtime->search_string));
+}
+
+bool ED_buttons_tab_has_search_result(SpaceProperties *sbuts, const int index)
+{
+ return BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, index);
+}
+
+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) {
+ return false;
+ }
+
+ buttons_context_compute(C, sbuts);
+ return ED_region_property_search(C, region, &region->type->paneltypes, contexts, NULL);
+}
+
+static void property_search_move_to_next_tab_with_results(SpaceProperties *sbuts,
+ const short *context_tabs_array,
+ const int tabs_len)
+{
+ /* As long as all-tab search in the tool is disabled in the tool context, don't move from it. */
+ if (sbuts->mainb == BCONTEXT_TOOL) {
+ return;
+ }
+
+ int current_tab_index = 0;
+ for (int i = 0; i < tabs_len; i++) {
+ if (sbuts->mainb == context_tabs_array[i]) {
+ current_tab_index = i;
+ break;
+ }
+ }
+
+ /* Try the tabs after the current tab. */
+ for (int i = current_tab_index; i < tabs_len; i++) {
+ if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
+ sbuts->mainbuser = context_tabs_array[i];
+ return;
+ }
+ }
+
+ /* Try the tabs before the current tab. */
+ for (int i = 0; i < current_tab_index; i++) {
+ if (BLI_BITMAP_TEST(sbuts->runtime->tab_search_results, i)) {
+ sbuts->mainbuser = context_tabs_array[i];
+ return;
+ }
+ }
+}
+
+static void property_search_all_tabs(const bContext *C,
+ SpaceProperties *sbuts,
+ ARegion *main_region,
+ const short *context_tabs_array,
+ const int tabs_len)
+{
+ /* Use local copies of the area and duplicate the region as a mainly-paranoid protection
+ * against changing any of the space / region data while running the search. */
+ ScrArea area_copy = *CTX_wm_area(C);
+ ARegion *region_copy = BKE_area_region_copy(area_copy.type, main_region);
+ 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 = *sbuts;
+ sbuts_copy.path = NULL;
+ sbuts_copy.texuser = NULL;
+ sbuts_copy.runtime = MEM_dupallocN(sbuts->runtime);
+ sbuts_copy.runtime->tab_search_results = NULL;
+ area_copy.spacedata.first = &sbuts_copy;
+
+ /* Loop through the tabs added to the properties editor. */
+ for (int i = 0; i < tabs_len; i++) {
+ /* -1 corresponds to a spacer. */
+ if (context_tabs_array[i] == -1) {
+ continue;
+ }
+
+ /* Handle search for the current tab in the normal layout pass. */
+ if (context_tabs_array[i] == sbuts->mainb) {
+ continue;
+ }
+
+ sbuts_copy.mainb = sbuts_copy.mainbo = sbuts_copy.mainbuser = context_tabs_array[i];
+
+ /* Actually do the search and store the result in the bitmap. */
+ BLI_BITMAP_SET(sbuts->runtime->tab_search_results,
+ i,
+ property_search_for_context(C_copy, region_copy, &sbuts_copy));
+
+ UI_blocklist_free(C_copy, &region_copy->uiblocks);
+ }
+
+ BKE_area_region_free(area_copy.type, region_copy);
+ MEM_freeN(region_copy);
+ buttons_free((SpaceLink *)&sbuts_copy);
+ MEM_freeN(C_copy);
+}
+
+/**
+ * Handle property search for the layout pass, including finding which tabs have
+ * search results and switching if the current tab doesn't have a result.
+ */
+static void buttons_main_region_property_search(const bContext *C,
+ SpaceProperties *sbuts,
+ ARegion *region)
+{
+ /* Theoretical maximum of every context shown with a spacer between every tab. */
+ short context_tabs_array[BCONTEXT_TOT * 2];
+ 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. */
+ BLI_BITMAP_SET(
+ sbuts->runtime->tab_search_results, current_tab_index, current_tab_has_search_match);
+
+ /* 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);
+ }
+ }
+}
+
static void buttons_main_region_layout(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
@@ -310,6 +474,10 @@ static void buttons_main_region_layout(const bContext *C, ARegion *region)
buttons_main_region_layout_properties(C, sbuts, region);
}
+ if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
+ buttons_main_region_property_search(C, sbuts, region);
+ }
+
sbuts->mainbo = sbuts->mainb;
}
@@ -722,8 +890,8 @@ void ED_spacetype_buttons(void)
buttons_context_register(art);
BLI_addhead(&st->regiontypes, art);
- /* Register the panel types from modifiers. The actual panels are built per modifier rather than
- * per modifier type. */
+ /* Register the panel types from modifiers. The actual panels are built per modifier rather
+ * than per modifier type. */
for (ModifierType i = 0; i < NUM_MODIFIER_TYPES; i++) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(i);
if (mti != NULL && mti->panelRegister != NULL) {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 9d9b41a1f81..be02e450412 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -56,6 +56,9 @@ struct bNodeTree;
struct wmOperator;
struct wmTimer;
+/* Defined in `buttons_intern.h`. */
+typedef struct SpaceProperties_Runtime SpaceProperties_Runtime;
+
/* TODO 2.8: We don't write the global areas to files currently. Uncomment
* define to enable writing (should become the default in a bit). */
//#define WITH_GLOBAL_AREA_WRITING
@@ -129,13 +132,6 @@ typedef enum eSpaceInfo_RptMask {
/** \name Properties Editor
* \{ */
-#
-#
-typedef struct SpaceProperties_Runtime {
- /** For filtering properties displayed in the space. Length defined as UI_MAX_NAME_STR. */
- char search_string[128];
-} SpaceProperties_Runtime;
-
/* Properties Editor */
typedef struct SpaceProperties {
SpaceLink *next, *prev;
@@ -168,7 +164,7 @@ typedef struct SpaceProperties {
void *texuser;
/* Doesn't necessarily need to be a pointer, but runtime structs are still written to files. */
- SpaceProperties_Runtime *runtime;
+ struct SpaceProperties_Runtime *runtime;
} SpaceProperties;
/* button defines (deprecated) */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 2a4bc6bae06..5b34281ffa0 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1825,6 +1825,53 @@ static void rna_SpaceProperties_context_update(Main *UNUSED(bmain),
}
}
+static int rna_SpaceProperties_tab_search_results_getlength(PointerRNA *ptr,
+ int length[RNA_MAX_ARRAY_DIMENSION])
+{
+ SpaceProperties *sbuts = ptr->data;
+
+ short context_tabs_array[BCONTEXT_TOT * 2]; /* Dummy variable. */
+ const int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array);
+
+ length[0] = tabs_len;
+
+ return length[0];
+}
+
+static void rna_SpaceProperties_tab_search_results_get(PointerRNA *ptr, bool *values)
+{
+ SpaceProperties *sbuts = ptr->data;
+
+ short context_tabs_array[BCONTEXT_TOT * 2]; /* Dummy variable. */
+ const int tabs_len = ED_buttons_tabs_list(sbuts, context_tabs_array);
+
+ for (int i = 0; i < tabs_len; i++) {
+ values[i] = ED_buttons_tab_has_search_result(sbuts, i);
+ }
+}
+
+static void rna_SpaceProperties_search_filter_get(PointerRNA *ptr, char *value)
+{
+ SpaceProperties *sbuts = ptr->data;
+ const char *search_filter = ED_buttons_search_string_get(sbuts);
+
+ strcpy(value, search_filter);
+}
+
+static int rna_SpaceProperties_search_filter_length(PointerRNA *ptr)
+{
+ SpaceProperties *sbuts = ptr->data;
+
+ return ED_buttons_search_string_length(sbuts);
+}
+
+static void rna_SpaceProperties_search_filter_set(struct PointerRNA *ptr, const char *value)
+{
+ SpaceProperties *sbuts = ptr->data;
+
+ ED_buttons_search_string_set(sbuts, value);
+}
+
static void rna_SpaceProperties_search_filter_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *ptr)
@@ -4514,8 +4561,23 @@ static void rna_def_space_properties(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pin ID", "Use the pinned context");
/* Property search. */
+
+ prop = RNA_def_property(srna, "tab_search_results", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_array(prop, 0); /* Dynamic length, see next line. */
+ RNA_def_property_flag(prop, PROP_DYNAMIC);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_SpaceProperties_tab_search_results_get", NULL);
+ RNA_def_property_dynamic_array_funcs(prop, "rna_SpaceProperties_tab_search_results_getlength");
+ RNA_def_property_ui_text(
+ prop, "Tab Search Results", "Whether or not each visible tab has a search result");
+
prop = RNA_def_property(srna, "search_filter", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "runtime->search_string");
+ /* The search filter is stored in the property editor's runtime struct which
+ * is only defined in an internal header, so use the getter / setter here. */
+ RNA_def_property_string_funcs(prop,
+ "rna_SpaceProperties_search_filter_get",
+ "rna_SpaceProperties_search_filter_length",
+ "rna_SpaceProperties_search_filter_set");
RNA_def_property_ui_text(prop, "Display Filter", "Live search filtering string");
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(