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:
authorJulian Eisel <julian@blender.org>2020-08-07 15:34:11 +0300
committerJulian Eisel <julian@blender.org>2020-08-07 16:17:52 +0300
commit49f088e2d0936ed3b5f08881a14ad83c19951791 (patch)
treee0d64f096345e3cda1e18a248a09a52869e37407 /source/blender
parent48e089375ebe4aeb30d60e9d8ef6f467280cf07d (diff)
UI Code Quality: Use derived structs for search buttons and decorators
The current on-size-fits-all `uiBut` creates quite a mess, where it's hard to reason about which members are free for use, under which conditions they are used and how. `uiBut` also has members that aren't used at times, violating the "don't pay for what you don't use" principle. To address this, we want to move to typed buttons, where `uiBut` is just a base struct and each type extends it as needed. That structures data better and type specific data is only available if it's actually used by a button type. Two trade-offs: * Many casts to the derived type have to be done. * Sometimes we change the button type after it's created. So I had to add logic to reallocate the button for use with the new, possibly derived struct. Ideally that wouldn't be needed, but for now that's what we have. Part of T74432. Differential Revision: https://developer.blender.org/D7610 Reviewed by: Brecht Van Lommel, Campbell Barton
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/UI_interface.h8
-rw-r--r--source/blender/editors/interface/interface.c199
-rw-r--r--source/blender/editors/interface/interface_anim.c40
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c30
-rw-r--r--source/blender/editors/interface/interface_intern.h72
-rw-r--r--source/blender/editors/interface/interface_layout.c116
-rw-r--r--source/blender/editors/interface/interface_ops.c7
-rw-r--r--source/blender/editors/interface/interface_query.c2
-rw-r--r--source/blender/editors/interface/interface_region_search.c72
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c3
12 files changed, 383 insertions, 172 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 184032df3c6..4a98d72a463 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -57,6 +57,7 @@ struct bNodeSocket;
struct bNodeTree;
struct bScreen;
struct rcti;
+struct uiButSearch;
struct uiFontStyle;
struct uiList;
struct uiStyle;
@@ -371,6 +372,7 @@ typedef enum {
UI_BTYPE_SEPR_SPACER = 56 << 9,
/** Resize handle (resize uilist). */
UI_BTYPE_GRIP = 57 << 9,
+ UI_BTYPE_DECORATOR = 58 << 9,
} eButType;
#define BUTTYPE (63 << 9)
@@ -500,7 +502,7 @@ typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
/* Search types. */
typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ struct uiButSearch *search_but);
typedef void (*uiButSearchUpdateFn)(const struct bContext *C,
void *arg,
const char *str,
@@ -537,7 +539,7 @@ typedef bool (*uiMenuStepFunc)(struct bContext *C, int direction, void *arg1);
bool UI_but_has_tooltip_label(const uiBut *but);
bool UI_but_is_tool(const uiBut *but);
bool UI_but_is_utf8(const uiBut *but);
-#define UI_but_is_decorator(but) ((but)->func == ui_but_anim_decorate_cb)
+#define UI_but_is_decorator(but) ((but)->type == UI_BTYPE_DECORATOR)
bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title);
bool UI_block_is_empty(const uiBlock *block);
@@ -1929,8 +1931,6 @@ uiLayout *uiLayoutGridFlow(uiLayout *layout,
uiLayout *uiLayoutBox(uiLayout *layout);
uiLayout *uiLayoutListBox(uiLayout *layout,
struct uiList *ui_list,
- struct PointerRNA *ptr,
- struct PropertyRNA *prop,
struct PointerRNA *actptr,
struct PropertyRNA *actprop);
uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c5d5fbb90c0..9a4eb73c20e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -807,7 +807,12 @@ static bool ui_but_update_from_old_block(const bContext *C,
SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
- SWAP(struct uiButSearchData *, oldbut->search, but->search);
+ if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
+
+ SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
+ SWAP(void *, search_oldbut->arg, search_but->arg);
+ }
/* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
* when scrolling without moving mouse (see [#28432]) */
@@ -1773,7 +1778,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
+ ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
ui_but_predefined_extra_operator_icons_add(but);
}
@@ -2021,6 +2026,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
case UI_BTYPE_HOTKEY_EVENT:
case UI_BTYPE_KEY_EVENT:
case UI_BTYPE_COLOR:
+ case UI_BTYPE_DECORATOR:
is_push = -1;
break;
case UI_BTYPE_BUT_TOGGLE:
@@ -2945,10 +2951,10 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL, NULL);
return true;
}
+
+ uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but : NULL;
/* RNA pointer */
PointerRNA rptr;
- PointerRNA ptr = but->rnasearchpoin;
- PropertyRNA *prop = but->rnasearchprop;
/* This is kind of hackish, in theory think we could only ever use the second member of
* this if/else, since ui_searchbox_apply() is supposed to always set that pointer when
@@ -2956,12 +2962,16 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
* to try to break as little as possible existing code. All this is band-aids anyway.
* Fact remains, using editstr as main 'reference' over whole search button thingy
* is utterly weak and should be redesigned imho, but that's not a simple task. */
- if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
+ if (search_but && search_but->rnasearchprop &&
+ RNA_property_collection_lookup_string(
+ &search_but->rnasearchpoin, search_but->rnasearchprop, str, &rptr)) {
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
- else if (but->func_arg2 != NULL) {
- RNA_pointer_create(
- NULL, RNA_property_pointer_type(&but->rnapoin, but->rnaprop), but->func_arg2, &rptr);
+ else if (search_but->item_active != NULL) {
+ RNA_pointer_create(NULL,
+ RNA_property_pointer_type(&but->rnapoin, but->rnaprop),
+ search_but->item_active,
+ &rptr);
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
@@ -3231,6 +3241,28 @@ void ui_but_range_set_soft(uiBut *but)
/* ******************* Free ********************/
+/**
+ * Free data specific to a certain button type.
+ * For now just do in a switch-case, we could instead have a callback stored in #uiBut and set that
+ * in #ui_but_alloc_info().
+ */
+static void ui_but_free_type_specific(uiBut *but)
+{
+ switch (but->type) {
+ case UI_BTYPE_SEARCH_MENU: {
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ if (search_but->arg_free_fn) {
+ search_but->arg_free_fn(search_but->arg);
+ search_but->arg = NULL;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
/* can be called with C==NULL */
static void ui_but_free(const bContext *C, uiBut *but)
{
@@ -3251,13 +3283,7 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->hold_argN);
}
- if (but->search != NULL) {
- if (but->search->arg_free_fn) {
- but->search->arg_free_fn(but->search->arg);
- but->search->arg = NULL;
- }
- MEM_freeN(but->search);
- }
+ ui_but_free_type_specific(but);
if (but->active) {
/* XXX solve later, buttons should be free-able without context ideally,
@@ -3736,14 +3762,99 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
IMB_colormanagement_scene_linear_to_display_v3(pixel, display);
}
-static uiBut *ui_but_alloc(const eButType type)
+static void ui_but_alloc_info(const eButType type,
+ size_t *r_alloc_size,
+ const char **r_alloc_str,
+ bool *r_has_custom_type)
{
+ size_t alloc_size;
+ const char *alloc_str;
+ bool has_custom_type = true;
+
switch (type) {
+ case UI_BTYPE_DECORATOR:
+ alloc_size = sizeof(uiButDecorator);
+ alloc_str = "uiButDecorator";
+ break;
case UI_BTYPE_TAB:
- return MEM_callocN(sizeof(uiButTab), "uiButTab");
+ alloc_size = sizeof(uiButTab);
+ alloc_str = "uiButTab";
+ break;
+ case UI_BTYPE_SEARCH_MENU:
+ alloc_size = sizeof(uiButSearch);
+ alloc_str = "uiButSearch";
+ break;
default:
- return MEM_callocN(sizeof(uiBut), "uiBut");
+ alloc_size = sizeof(uiBut);
+ alloc_str = "uiBut";
+ has_custom_type = false;
+ break;
+ }
+
+ if (r_alloc_size) {
+ *r_alloc_size = alloc_size;
+ }
+ if (r_alloc_str) {
+ *r_alloc_str = alloc_str;
+ }
+ if (r_has_custom_type) {
+ *r_has_custom_type = has_custom_type;
+ }
+}
+
+static uiBut *ui_but_alloc(const eButType type)
+{
+ size_t alloc_size;
+ const char *alloc_str;
+
+ ui_but_alloc_info(type, &alloc_size, &alloc_str, NULL);
+
+ return MEM_callocN(alloc_size, alloc_str);
+}
+
+/**
+ * Reallocate the button (new address is returned) for a new button type.
+ * This should generally be avoided and instead the correct type be created right away.
+ *
+ * \note Only the #uiBut data can be kept. If the old button used a derived type (e.g. #uiButTab),
+ * the data that is not inside #uiBut will be lost.
+ */
+uiBut *ui_but_change_type(uiBut *but, eButType new_type)
+{
+ if (but->type != new_type) {
+ size_t alloc_size;
+ const char *alloc_str;
+ uiBut *insert_after_but = but->prev;
+ bool new_has_custom_type, old_has_custom_type;
+
+ /* Remove old button address */
+ BLI_remlink(&but->block->buttons, but);
+
+ ui_but_alloc_info(but->type, NULL, NULL, &old_has_custom_type);
+ ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type);
+
+ if (new_has_custom_type || old_has_custom_type) {
+ const void *old_but_ptr = but;
+ /* Button may have pointer to a member within itself, this will have to be updated. */
+ const bool has_str_ptr_to_self = but->str == but->strdata;
+
+ but = MEM_recallocN_id(but, alloc_size, alloc_str);
+ but->type = new_type;
+ if (has_str_ptr_to_self) {
+ but->str = but->strdata;
+ }
+
+ BLI_insertlinkafter(&but->block->buttons, insert_after_but, but);
+
+ if (but->layout) {
+ const bool found_layout = ui_layout_replace_but_ptr(but->layout, old_but_ptr, but);
+ BLI_assert(found_layout);
+ UNUSED_VARS_NDEBUG(found_layout);
+ }
+ }
}
+
+ return but;
}
/**
@@ -3891,6 +4002,7 @@ static uiBut *ui_def_but(uiBlock *block,
if (ELEM(but->type,
UI_BTYPE_BLOCK,
UI_BTYPE_BUT,
+ UI_BTYPE_DECORATOR,
UI_BTYPE_LABEL,
UI_BTYPE_PULLDOWN,
UI_BTYPE_ROUNDBOX,
@@ -6385,54 +6497,55 @@ void UI_but_func_search_set(uiBut *but,
uiButHandleFunc search_exec_fn,
void *active)
{
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
/* needed since callers don't have access to internal functions
* (as an alternative we could expose it) */
if (search_create_fn == NULL) {
search_create_fn = ui_searchbox_create_generic;
}
- struct uiButSearchData *search = but->search;
- if (search != NULL) {
- if (search->arg_free_fn != NULL) {
- search->arg_free_fn(but->search->arg);
- search->arg = NULL;
- }
- }
- else {
- search = MEM_callocN(sizeof(*but->search), __func__);
- but->search = search;
+ if (search_but->arg_free_fn != NULL) {
+ search_but->arg_free_fn(search_but->arg);
+ search_but->arg = NULL;
}
- search->create_fn = search_create_fn;
- search->update_fn = search_update_fn;
+ search_but->popup_create_fn = search_create_fn;
+ search_but->items_update_fn = search_update_fn;
+ search_but->item_active = active;
- search->arg = arg;
- search->arg_free_fn = search_arg_free_fn;
+ search_but->arg = arg;
+ search_but->arg_free_fn = search_arg_free_fn;
if (search_exec_fn) {
#ifdef DEBUG
- if (but->func) {
+ if (search_but->but.func) {
/* watch this, can be cause of much confusion, see: T47691 */
printf("%s: warning, overwriting button callback with search function callback!\n",
__func__);
}
#endif
- UI_but_func_set(but, search_exec_fn, search->arg, active);
+ /* Handling will pass the active item as arg2 later, so keep it NULL here. */
+ UI_but_func_set(but, search_exec_fn, search_but->arg, NULL);
}
/* search buttons show red-alert if item doesn't exist, not for menus */
if (0 == (but->block->flag & UI_BLOCK_LOOP)) {
/* skip empty buttons, not all buttons need input, we only show invalid */
if (but->drawstr[0]) {
- ui_but_search_refresh(but);
+ ui_but_search_refresh(search_but);
}
}
}
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn)
{
- struct uiButSearchData *search = but->search;
- search->context_menu_fn = context_menu_fn;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_context_menu_fn = context_menu_fn;
}
/**
@@ -6441,14 +6554,18 @@ void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn co
*/
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
{
- struct uiButSearchData *search = but->search;
- search->sep_string = search_sep_string;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_sep_string = search_sep_string;
}
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
{
- struct uiButSearchData *search = but->search;
- search->tooltip_fn = tooltip_fn;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_tooltip_fn = tooltip_fn;
}
/* Callbacks for operator search button. */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 8d12a1dd1ad..cc58082cb02 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -120,35 +120,41 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
}
}
-static uiBut *ui_but_anim_decorate_find_attached_button(uiBut *but_decorate)
+static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate)
{
uiBut *but_iter = NULL;
- BLI_assert(UI_but_is_decorator(but_decorate));
- BLI_assert(but_decorate->rnasearchpoin.data && but_decorate->rnasearchprop);
+ BLI_assert(UI_but_is_decorator(&but_decorate->but));
+ BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop);
- LISTBASE_CIRCULAR_BACKWARD_BEGIN (&but_decorate->block->buttons, but_iter, but_decorate->prev) {
- if (but_iter != but_decorate &&
- ui_but_rna_equals_ex(but_iter,
- &but_decorate->rnasearchpoin,
- but_decorate->rnasearchprop,
- POINTER_AS_INT(but_decorate->custom_data))) {
+ LISTBASE_CIRCULAR_BACKWARD_BEGIN (
+ &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) {
+ if (but_iter != (uiBut *)but_decorate &&
+ ui_but_rna_equals_ex(
+ but_iter, &but_decorate->rnapoin, but_decorate->rnaprop, but_decorate->rnaindex)) {
return but_iter;
}
}
- LISTBASE_CIRCULAR_BACKWARD_END(&but_decorate->block->buttons, but_iter, but_decorate->prev);
+ LISTBASE_CIRCULAR_BACKWARD_END(
+ &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev);
return NULL;
}
-void ui_but_anim_decorate_update_from_flag(uiBut *but)
+void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but)
{
- const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but);
+ if (!decorator_but->rnapoin.data || !decorator_but->rnaprop) {
+ /* Nothing to do. */
+ return;
+ }
+
+ const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(decorator_but);
+ uiBut *but = &decorator_but->but;
if (!but_anim) {
printf("Could not find button with matching property to decorate (%s.%s)\n",
- RNA_struct_identifier(but->rnasearchpoin.type),
- RNA_property_identifier(but->rnasearchprop));
+ RNA_struct_identifier(decorator_but->rnapoin.type),
+ RNA_property_identifier(decorator_but->rnaprop));
return;
}
@@ -325,7 +331,7 @@ void ui_but_anim_paste_driver(bContext *C)
void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
{
wmWindowManager *wm = CTX_wm_manager(C);
- uiBut *but_decorate = arg_but;
+ uiButDecorator *but_decorate = arg_but;
uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate);
if (!but_anim) {
@@ -333,7 +339,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)
}
/* FIXME(campbell), swapping active pointer is weak. */
- SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
+ SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
wm->op_undo_depth++;
if (but_anim->flag & UI_BUT_DRIVEN) {
@@ -357,6 +363,6 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)
WM_operator_properties_free(&props_ptr);
}
- SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
+ SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
wm->op_undo_depth--;
}
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index aaa5e1c0cf1..46876fca9a5 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -962,7 +962,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const PropertyType prop_type = RNA_property_type(but->rnaprop);
if (((prop_type == PROP_POINTER) ||
(prop_type == PROP_STRING && but->type == UI_BTYPE_SEARCH_MENU &&
- but->search->update_fn == ui_rna_collection_search_update_fn)) &&
+ ((uiButSearch *)but)->items_update_fn == ui_rna_collection_search_update_fn)) &&
ui_jump_to_target_button_poll(C)) {
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Jump to Target"),
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 7ea64d36d48..f55d8d5ccc6 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -767,11 +767,12 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->rnapoin = but->rnapoin;
after->rnaprop = but->rnaprop;
- if (but->search != NULL) {
- after->search_arg_free_fn = but->search->arg_free_fn;
- after->search_arg = but->search->arg;
- but->search->arg_free_fn = NULL;
- but->search->arg = NULL;
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_but = (uiButSearch *)but;
+ after->search_arg_free_fn = search_but->arg_free_fn;
+ after->search_arg = search_but->arg;
+ search_but->arg_free_fn = NULL;
+ search_but->arg = NULL;
}
if (but->context) {
@@ -1047,8 +1048,19 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
but->rename_orig = data->origstr;
data->origstr = NULL;
}
+
+ void *orig_arg2 = but->func_arg2;
+
+ /* If arg2 isn't in use already, pass the active search item through it. */
+ if ((but->func_arg2 == NULL) && (but->type == UI_BTYPE_SEARCH_MENU)) {
+ uiButSearch *search_but = (uiButSearch *)but;
+ but->func_arg2 = search_but->item_active;
+ }
+
ui_apply_but_func(C, but);
+ but->func_arg2 = orig_arg2;
+
data->retval = but->retval;
data->applied = true;
}
@@ -2087,6 +2099,7 @@ static void ui_apply_but(
/* handle different types */
switch (but->type) {
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
ui_apply_but_BUT(C, but, data);
break;
case UI_BTYPE_TEXT:
@@ -3321,7 +3334,9 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
/* optional searchbox */
if (but->type == UI_BTYPE_SEARCH_MENU) {
- data->searchbox = but->search->create_fn(C, data->region, but);
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ data->searchbox = search_but->popup_create_fn(C, data->region, search_but);
ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
}
@@ -7522,6 +7537,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
switch (but->type) {
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
retval = ui_do_but_BUT(C, but, data, event);
break;
case UI_BTYPE_KEY_EVENT:
@@ -8430,7 +8446,7 @@ void UI_context_update_anim_flag(const bContext *C)
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
+ ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index bf2971f93df..0dfa23a4332 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -147,19 +147,11 @@ enum {
/* max amount of items a radial menu (pie menu) can contain */
#define PIE_MAX_ITEMS 8
-struct uiButSearchData {
- uiButSearchCreateFn create_fn;
- uiButSearchUpdateFn update_fn;
- void *arg;
- uiButSearchArgFreeFn arg_free_fn;
- uiButSearchContextMenuFn context_menu_fn;
- uiButSearchTooltipFn tooltip_fn;
-
- const char *sep_string;
-};
-
struct uiBut {
struct uiBut *next, *prev;
+
+ /* Pointer back to the layout item holding this button. */
+ uiLayout *layout;
int flag, drawflag;
eButType type;
eButPointerType pointype;
@@ -214,8 +206,6 @@ struct uiBut {
uiButCompleteFunc autocomplete_func;
void *autofunc_arg;
- struct uiButSearchData *search;
-
uiButHandleRenameFunc rename_func;
void *rename_arg1;
void *rename_orig;
@@ -256,9 +246,6 @@ struct uiBut {
struct PropertyRNA *rnaprop;
int rnaindex;
- struct PointerRNA rnasearchpoin;
- struct PropertyRNA *rnasearchprop;
-
/* Operator data */
struct wmOperatorType *optype;
struct PointerRNA *opptr;
@@ -294,11 +281,41 @@ struct uiBut {
uiBlock *block;
};
+/** Derived struct for #UI_BTYPE_TAB */
typedef struct uiButTab {
uiBut but;
struct MenuType *menu;
} uiButTab;
+/** Derived struct for #UI_BTYPE_SEARCH_MENU */
+typedef struct uiButSearch {
+ uiBut but;
+
+ uiButSearchCreateFn popup_create_fn;
+ uiButSearchUpdateFn items_update_fn;
+ void *item_active;
+
+ void *arg;
+ uiButSearchArgFreeFn arg_free_fn;
+
+ uiButSearchContextMenuFn item_context_menu_fn;
+ uiButSearchTooltipFn item_tooltip_fn;
+
+ const char *item_sep_string;
+
+ struct PointerRNA rnasearchpoin;
+ struct PropertyRNA *rnasearchprop;
+} uiButSearch;
+
+/** Derived struct for #UI_BTYPE_DECORATOR */
+typedef struct uiButDecorator {
+ uiBut but;
+
+ struct PointerRNA rnapoin;
+ struct PropertyRNA *rnaprop;
+ int rnaindex;
+} uiButDecorator;
+
/**
* Additional, superimposed icon for a button, invoking an operator.
*/
@@ -493,6 +510,8 @@ extern void ui_window_to_region_rcti(const struct ARegion *region,
extern void ui_region_to_window(const struct ARegion *region, int *x, int *y);
extern void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r_rect);
+uiBut *ui_but_change_type(uiBut *but, eButType new_type);
+
extern double ui_but_value_get(uiBut *but);
extern void ui_but_value_set(uiBut *but, double value);
extern void ui_but_hsv_set(uiBut *but);
@@ -662,13 +681,13 @@ ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
/* Searchbox for string button */
struct ARegion *ui_searchbox_create_generic(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
struct ARegion *ui_searchbox_create_operator(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
struct ARegion *ui_searchbox_create_menu(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
bool ui_searchbox_inside(struct ARegion *region, int x, int y);
int ui_searchbox_find_index(struct ARegion *region, const char *name);
@@ -681,7 +700,7 @@ bool ui_searchbox_event(struct bContext *C,
const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *region);
void ui_searchbox_free(struct bContext *C, struct ARegion *region);
-void ui_but_search_refresh(uiBut *but);
+void ui_but_search_refresh(uiButSearch *but);
/* interface_region_menu_popup.c */
int ui_but_menu_step(uiBut *but, int step);
@@ -925,11 +944,12 @@ void ui_resources_free(void);
/* interface_layout.c */
void ui_layout_add_but(uiLayout *layout, uiBut *but);
-void ui_but_add_search(uiBut *but,
- PointerRNA *ptr,
- PropertyRNA *prop,
- PointerRNA *searchptr,
- PropertyRNA *searchprop);
+bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but);
+uiBut *ui_but_add_search(uiBut *but,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ PointerRNA *searchptr,
+ PropertyRNA *searchprop);
void ui_layout_list_set_labels_active(uiLayout *layout);
/* menu callback */
void ui_item_menutype_func(struct bContext *C, struct uiLayout *layout, void *arg_mt);
@@ -950,7 +970,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str);
void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, float cfra);
void ui_but_anim_decorate_cb(struct bContext *C, void *arg_but, void *arg_dummy);
-void ui_but_anim_decorate_update_from_flag(uiBut *but);
+void ui_but_anim_decorate_update_from_flag(uiButDecorator *but);
/* interface_query.c */
bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 98408156f4b..888cacb64eb 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2278,7 +2278,7 @@ void uiItemFullR(uiLayout *layout,
/* property with separate label */
else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag);
- ui_but_add_search(but, ptr, prop, NULL, NULL);
+ but = ui_but_add_search(but, ptr, prop, NULL, NULL);
if (layout->redalert) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
@@ -2651,7 +2651,10 @@ static void ui_rna_collection_search_arg_free_fn(void *ptr)
MEM_freeN(ptr);
}
-void ui_but_add_search(
+/**
+ * \note May reallocate \a but, so the possibly new address is returned.
+ */
+uiBut *ui_but_add_search(
uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
{
StructRNA *ptype;
@@ -2669,11 +2672,13 @@ void ui_but_add_search(
/* turn button into search button */
if (searchprop) {
uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
+ uiButSearch *search_but;
- but->type = UI_BTYPE_SEARCH_MENU;
+ but = ui_but_change_type(but, UI_BTYPE_SEARCH_MENU);
+ search_but = (uiButSearch *)but;
+ search_but->rnasearchpoin = *searchptr;
+ search_but->rnasearchprop = searchprop;
but->hardmax = MAX2(but->hardmax, 256.0f);
- but->rnasearchpoin = *searchptr;
- but->rnasearchprop = searchprop;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
if (RNA_property_is_unlink(prop)) {
but->flag |= UI_BUT_VALUE_CLEAR;
@@ -2707,6 +2712,8 @@ void ui_but_add_search(
* so other code might have already set but->type to search menu... */
but->flag |= UI_BUT_DISABLED;
}
+
+ return but;
}
void uiItemPointerR_prop(uiLayout *layout,
@@ -2939,29 +2946,28 @@ void uiItemMContents(uiLayout *layout, const char *menuname)
void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index)
{
uiBlock *block = layout->root->block;
- uiBut *but = NULL;
-
uiLayout *col;
+
UI_block_layout_set_current(block, layout);
col = uiLayoutColumn(layout, false);
col->space = 0;
col->emboss = UI_EMBOSS_NONE;
if (ELEM(NULL, ptr, prop) || !RNA_property_animateable(ptr, prop)) {
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_BLANK1,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- "");
+ uiBut *but = uiDefIconBut(block,
+ UI_BTYPE_DECORATOR,
+ 0,
+ ICON_BLANK1,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
but->flag |= UI_BUT_DISABLED;
return;
}
@@ -2971,27 +2977,28 @@ void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop,
/* Loop for the array-case, but only do in case of an expanded array. */
for (int i = 0; i < (is_expand ? RNA_property_array_length(ptr, prop) : 1); i++) {
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_DOT,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Animate property"));
- UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL);
- but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
+ uiButDecorator *decorator_but = (uiButDecorator *)uiDefIconBut(block,
+ UI_BTYPE_DECORATOR,
+ 0,
+ ICON_DOT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Animate property"));
+
+ UI_but_func_set(&decorator_but->but, ui_but_anim_decorate_cb, decorator_but, NULL);
+ decorator_but->but.flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
/* Reusing RNA search members, setting actual RNA data has many side-effects. */
- but->rnasearchpoin = *ptr;
- but->rnasearchprop = prop;
+ decorator_but->rnapoin = *ptr;
+ decorator_but->rnaprop = prop;
/* ui_def_but_rna() sets non-array buttons to have a RNA index of 0. */
- but->custom_data = POINTER_FROM_INT((!is_array || is_expand) ? i : index);
+ decorator_but->rnaindex = (!is_array || is_expand) ? i : index;
}
}
@@ -4819,8 +4826,6 @@ void ui_layout_list_set_labels_active(uiLayout *layout)
uiLayout *uiLayoutListBox(uiLayout *layout,
uiList *ui_list,
- PointerRNA *ptr,
- PropertyRNA *prop,
PointerRNA *actptr,
PropertyRNA *actprop)
{
@@ -4829,8 +4834,6 @@ uiLayout *uiLayoutListBox(uiLayout *layout,
but->custom_data = ui_list;
- but->rnasearchpoin = *ptr;
- but->rnasearchprop = prop;
but->rnapoin = *actptr;
but->rnaprop = actprop;
@@ -5407,6 +5410,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
else {
BLI_addtail(&layout->items, bitem);
}
+ but->layout = layout;
if (layout->context) {
but->context = layout->context;
@@ -5418,6 +5422,30 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
}
}
+bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
+{
+ ListBase *child_list = layout->child_items_layout ? &layout->child_items_layout->items :
+ &layout->items;
+
+ LISTBASE_FOREACH (uiItem *, item, child_list) {
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
+
+ if (bitem->but == old_but_ptr) {
+ bitem->but = new_but;
+ return true;
+ }
+ }
+ else {
+ if (ui_layout_replace_but_ptr((uiLayout *)item, old_but_ptr, new_but)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void uiLayoutSetFixedSize(uiLayout *layout, bool fixed_size)
{
if (fixed_size) {
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 7ac3c90dcd2..5a49f3e70d0 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1148,10 +1148,11 @@ static bool jump_to_target_button(bContext *C, bool poll)
/* For string properties with prop_search, look up the search collection item. */
if (type == PROP_STRING) {
const uiBut *but = UI_context_active_but_get(C);
+ const uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but :
+ NULL;
- if (but->type == UI_BTYPE_SEARCH_MENU && but->search &&
- but->search->update_fn == ui_rna_collection_search_update_fn) {
- uiRNACollectionSearch *coll_search = but->search->arg;
+ if (search_but && search_but->items_update_fn == ui_rna_collection_search_update_fn) {
+ uiRNACollectionSearch *coll_search = search_but->arg;
char str_buf[MAXBONENAME];
char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL);
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 10b219202e5..edb5d51a392 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -113,7 +113,7 @@ bool UI_but_is_utf8(const uiBut *but)
#ifdef USE_UI_POPOVER_ONCE
bool ui_but_is_popover_once_compat(const uiBut *but)
{
- return ((but->type == UI_BTYPE_BUT) || ui_but_is_toggle(but));
+ return (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR) || ui_but_is_toggle(but));
}
#endif
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 80155e3e871..2010d89165e 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -302,8 +302,11 @@ bool ui_searchbox_inside(ARegion *region, int x, int y)
bool ui_searchbox_apply(uiBut *but, ARegion *region)
{
uiSearchboxData *data = region->regiondata;
+ uiButSearch *search_but = (uiButSearch *)but;
- but->func_arg2 = NULL;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ search_but->item_active = NULL;
if (data->active != -1) {
const char *name = data->items.names[data->active] +
@@ -316,7 +319,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
- but->func_arg2 = data->items.pointers[data->active];
+ search_but->item_active = data->items.pointers[data->active];
return true;
}
@@ -340,8 +343,13 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- if (but->search && but->search->tooltip_fn) {
- return but->search->tooltip_fn(C, region, but->search->arg, but->func_arg2);
+ if (but->type != UI_BTYPE_SEARCH_MENU) {
+ continue;
+ }
+
+ uiButSearch *search_but = (uiButSearch *)but;
+ if (search_but->item_tooltip_fn) {
+ return search_but->item_tooltip_fn(C, region, search_but->arg, search_but->item_active);
}
}
}
@@ -352,10 +360,13 @@ bool ui_searchbox_event(
bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event)
{
uiSearchboxData *data = region->regiondata;
+ uiButSearch *search_but = (uiButSearch *)but;
int type = event->type, val = event->val;
bool handled = false;
bool tooltip_timer_started = false;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
if (type == MOUSEPAN) {
ui_pan_to_scroll(event, &type, &val);
}
@@ -373,7 +384,7 @@ bool ui_searchbox_event(
break;
case RIGHTMOUSE:
if (val) {
- if (but->search->context_menu_fn) {
+ if (search_but->item_context_menu_fn) {
if (data->active != -1) {
/* Check the cursor is over the active element
* (a little confusing if this isn't the case, although it does work). */
@@ -383,7 +394,7 @@ bool ui_searchbox_event(
&rect, event->x - region->winrct.xmin, event->y - region->winrct.ymin)) {
void *active = data->items.pointers[data->active];
- if (but->search->context_menu_fn(C, but->search->arg, active, event)) {
+ if (search_but->item_context_menu_fn(C, search_but->arg, active, event)) {
handled = true;
}
}
@@ -417,7 +428,7 @@ bool ui_searchbox_event(
if (is_inside) {
if (data->active != -1) {
ScrArea *area = CTX_wm_area(C);
- but->func_arg2 = data->items.pointers[data->active];
+ search_but->item_active = data->items.pointers[data->active];
WM_tooltip_timer_init(C, CTX_wm_window(C), area, butregion, wm_searchbox_tooltip_init);
tooltip_timer_started = true;
}
@@ -437,18 +448,24 @@ bool ui_searchbox_event(
}
/** Wrap #uiButSearchUpdateFn callback. */
-static void ui_searchbox_update_fn(bContext *C, uiBut *but, const char *str, uiSearchItems *items)
+static void ui_searchbox_update_fn(bContext *C,
+ uiButSearch *search_but,
+ const char *str,
+ uiSearchItems *items)
{
wmWindow *win = CTX_wm_window(C);
WM_tooltip_clear(C, win);
- but->search->update_fn(C, but->search->arg, str, items);
+ search_but->items_update_fn(C, search_but->arg, str, items);
}
/* region is the search box itself */
void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset)
{
+ uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
/* reset vars */
data->items.totitem = 0;
data->items.more = 0;
@@ -460,9 +477,9 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
data->active = -1;
/* handle active */
- if (but->search->update_fn && but->func_arg2) {
- data->items.active = but->func_arg2;
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ if (search_but->items_update_fn && search_but->item_active) {
+ data->items.active = search_but->item_active;
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
data->items.active = NULL;
/* found active item, calculate real offset by centering it */
@@ -491,8 +508,8 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
}
/* callback */
- if (but->search->update_fn) {
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ if (search_but->items_update_fn) {
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
}
/* handle case where editstr is equal to one of items */
@@ -523,13 +540,16 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str)
{
+ uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
int match = AUTOCOMPLETE_NO_MATCH;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
if (str[0]) {
data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
match = UI_autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
@@ -673,10 +693,11 @@ static void ui_searchbox_region_free_cb(ARegion *region)
region->regiondata = NULL;
}
-ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
wmWindow *win = CTX_wm_window(C);
const uiStyle *style = UI_style_get();
+ uiBut *but = &search_but->but;
static ARegionType type;
ARegion *region;
uiSearchboxData *data;
@@ -725,7 +746,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
data->use_sep = true;
}
- data->sep_string = but->search->sep_string;
+ data->sep_string = search_but->item_sep_string;
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
@@ -945,12 +966,12 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
}
}
-ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
ARegion *region;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- region = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
+ region = ui_searchbox_create_generic(C, butregion, search_but);
region->type->draw = ui_searchbox_region_draw_cb__operator;
@@ -967,12 +988,12 @@ static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion
/* Currently unused. */
}
-ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
ARegion *region;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- region = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
+ region = ui_searchbox_create_generic(C, butregion, search_but);
if (false) {
region->type->draw = ui_searchbox_region_draw_cb__menu;
@@ -983,8 +1004,9 @@ ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but)
/* sets red alert if button holds a string it can't find */
/* XXX weak: search_func adds all partial matches... */
-void ui_but_search_refresh(uiBut *but)
+void ui_but_search_refresh(uiButSearch *search_but)
{
+ uiBut *but = &search_but->but;
uiSearchItems *items;
int x1;
@@ -1004,7 +1026,7 @@ void ui_but_search_refresh(uiBut *but)
items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
}
- ui_searchbox_update_fn(but->block->evil_C, but, but->drawstr, items);
+ ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items);
/* only redalert when we are sure of it, this can miss cases when >10 matches */
if (items->totitem == 0) {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index fcafa88a806..8c1d070b5e4 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -6210,7 +6210,7 @@ void uiTemplateList(uiLayout *layout,
switch (layout_type) {
case UILST_LAYOUT_DEFAULT:
/* layout */
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
glob = uiLayoutColumn(box, true);
row = uiLayoutRow(glob, false);
col = uiLayoutColumn(row, true);
@@ -6348,7 +6348,7 @@ void uiTemplateList(uiLayout *layout,
}
break;
case UILST_LAYOUT_GRID:
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
glob = uiLayoutColumn(box, true);
row = uiLayoutRow(glob, false);
col = uiLayoutColumn(row, true);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index bbf29365710..01f89a8bdb1 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1400,7 +1400,7 @@ static void widget_draw_icon(
alpha *= but->a2;
}
}
- else if (ELEM(but->type, UI_BTYPE_BUT)) {
+ else if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR)) {
if (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
alpha *= 0.5f;
}
@@ -4552,6 +4552,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
#ifdef USE_UI_TOOLBAR_HACK
if ((but->icon != ICON_NONE) && UI_but_is_tool(but)) {
wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);