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/UI_interface.h10
-rw-r--r--source/blender/editors/interface/interface.c218
-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.c60
-rw-r--r--source/blender/editors/interface/interface_intern.h90
-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.c72
-rw-r--r--source/blender/editors/interface/interface_utils.c2
-rw-r--r--source/blender/editors/interface/interface_widgets.c12
13 files changed, 468 insertions, 235 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 184032df3c6..e8352bc6b21 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)
@@ -388,8 +390,6 @@ enum {
UI_GRAD_L_ALT = 10,
};
-#define UI_PALETTE_COLOR 20
-
/* Drawing
*
* Functions to draw various shapes, taking theme settings into account.
@@ -500,7 +500,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 +537,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 +1929,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..a84ca33a7d7 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]) */
@@ -815,10 +820,10 @@ static bool ui_but_update_from_old_block(const bContext *C,
oldbut->hardmax = but->hardmax;
}
- /* Selectively copy a1, a2 since their use differs across all button types
- * (and we'll probably split these out later) */
- if (ELEM(oldbut->type, UI_BTYPE_PROGRESS_BAR)) {
- oldbut->a1 = but->a1;
+ if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
+ uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
+ uiButProgressbar *progress_but = (uiButProgressbar *)but;
+ progress_oldbut->progress = progress_but->progress;
}
if (!BLI_listbase_is_empty(&block->butstore)) {
@@ -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:
@@ -2323,7 +2329,8 @@ bool ui_but_supports_cycling(const uiBut *but)
{
return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) ||
(but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
- (but->type == UI_BTYPE_COLOR && but->a1 != -1) || (but->menu_step_func != NULL));
+ (but->type == UI_BTYPE_COLOR && ((uiButColor *)but)->is_pallete_color) ||
+ (but->menu_step_func != NULL));
}
double ui_but_value_get(uiBut *but)
@@ -2945,10 +2952,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 +2963,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 +3242,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 +3284,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 +3763,107 @@ 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_COLOR:
+ alloc_size = sizeof(uiButColor);
+ alloc_str = "uiButColor";
+ break;
+ 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;
+ case UI_BTYPE_PROGRESS_BAR:
+ alloc_size = sizeof(uiButProgressbar);
+ alloc_str = "uiButProgressbar";
+ 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 +4011,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 +6506,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 +6563,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 efbfcf8d19d..791e7ad7bb7 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 */
}
@@ -5698,21 +5713,24 @@ static bool ui_numedit_but_UNITVEC(
return changed;
}
-static void ui_palette_set_active(uiBut *but)
+static void ui_palette_set_active(uiButColor *color_but)
{
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
- Palette *palette = (Palette *)but->rnapoin.owner_id;
- PaletteColor *color = but->rnapoin.data;
+ if (color_but->is_pallete_color) {
+ Palette *palette = (Palette *)color_but->but.rnapoin.owner_id;
+ PaletteColor *color = color_but->but.rnapoin.data;
palette->active_color = BLI_findindex(&palette->colors, color);
}
}
static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
+ BLI_assert(but->type == UI_BTYPE_COLOR);
+ uiButColor *color_but = (uiButColor *)but;
+
if (data->state == BUTTON_STATE_HIGHLIGHT) {
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
if (ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
@@ -5722,7 +5740,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
#ifdef USE_DRAG_TOGGLE
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -5731,7 +5749,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
#endif
/* regular open menu */
if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
@@ -5762,8 +5780,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
ui_apply_but(C, but->block, but, data, true);
return WM_UI_HANDLER_BREAK;
}
- if ((int)(but->a1) == UI_PALETTE_COLOR && event->type == EVT_DELKEY &&
- event->val == KM_PRESS) {
+ if (color_but->is_pallete_color && (event->type == EVT_DELKEY) && (event->val == KM_PRESS)) {
Palette *palette = (Palette *)but->rnapoin.owner_id;
PaletteColor *color = but->rnapoin.data;
@@ -5794,7 +5811,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
+ if (color_but->is_pallete_color) {
if (!event->ctrl) {
float color[3];
Paint *paint = BKE_paint_get_active_from_context(C);
@@ -7522,6 +7539,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:
@@ -7597,13 +7615,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_BUT(C, but, data, event);
break;
case UI_BTYPE_COLOR:
- if (but->a1 == -1) {
- /* signal to prevent calling up color picker */
- retval = ui_do_but_EXIT(C, but, data, event);
- }
- else {
- retval = ui_do_but_COLOR(C, but, data, event);
- }
+ retval = ui_do_but_COLOR(C, but, data, event);
break;
case UI_BTYPE_UNITVEC:
retval = ui_do_but_UNITVEC(C, block, but, data, event);
@@ -8430,7 +8442,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..41110883729 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;
@@ -185,8 +177,6 @@ struct uiBut {
* - UI_BTYPE_LABEL: Use `(a1 == 1.0f)` to use a2 as a blending factor (imaginative!).
* - UI_BTYPE_SCROLL: Use as scroll size.
* - UI_BTYPE_SEARCH_MENU: Use as number or rows.
- * - UI_BTYPE_COLOR: Use as indication of color palette.
- * - UI_BTYPE_PROGRESS_BAR: Use to store progress (0..1).
*/
float a1;
@@ -196,7 +186,6 @@ struct uiBut {
* - UI_BTYPE_NUM: Use to store RNA 'precision' value, for dragging and click-step.
* - UI_BTYPE_LABEL: If `(a1 == 1.0f)` use a2 as a blending factor.
* - UI_BTYPE_SEARCH_MENU: Use as number or columns.
- * - UI_BTYPE_COLOR: Use as index in palette (not so good, needs refactor).
*/
float a2;
@@ -214,8 +203,6 @@ struct uiBut {
uiButCompleteFunc autocomplete_func;
void *autofunc_arg;
- struct uiButSearchData *search;
-
uiButHandleRenameFunc rename_func;
void *rename_arg1;
void *rename_orig;
@@ -256,9 +243,6 @@ struct uiBut {
struct PropertyRNA *rnaprop;
int rnaindex;
- struct PointerRNA rnasearchpoin;
- struct PropertyRNA *rnasearchprop;
-
/* Operator data */
struct wmOperatorType *optype;
struct PointerRNA *opptr;
@@ -294,11 +278,56 @@ struct uiBut {
uiBlock *block;
};
+/** Derived struct for #UI_BTYPE_COLOR */
+typedef struct uiButColor {
+ uiBut but;
+
+ bool is_pallete_color;
+ int palette_color_index;
+} uiButColor;
+
+/** 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;
+
+typedef struct uiButProgressbar {
+ uiBut but;
+
+ /* 0..1 range */
+ float progress;
+} uiButProgressbar;
+
/**
* Additional, superimposed icon for a button, invoking an operator.
*/
@@ -493,6 +522,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 +693,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 +712,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 +956,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 +982,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..c7d3d7bf501 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -5512,22 +5512,24 @@ void uiTemplatePalette(uiLayout *layout,
}
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
- uiDefButR(block,
- UI_BTYPE_COLOR,
- 0,
- "",
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- &color_ptr,
- "color",
- -1,
- 0.0,
- 1.0,
- UI_PALETTE_COLOR,
- col_id,
- "");
+ uiButColor *color_but = (uiButColor *)uiDefButR(block,
+ UI_BTYPE_COLOR,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &color_ptr,
+ "color",
+ -1,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ "");
+ color_but->is_pallete_color = true;
+ color_but->palette_color_index = col_id;
row_cols++;
col_id++;
}
@@ -6210,7 +6212,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 +6350,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);
@@ -6789,22 +6791,24 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
tip_arg->wm = wm;
tip_arg->owner = owner;
- uiBut *but_progress = uiDefIconTextBut(block,
- UI_BTYPE_PROGRESS_BAR,
- 0,
- 0,
- text,
- UI_UNIT_X,
- 0,
- UI_UNIT_X * 6.0f,
- UI_UNIT_Y,
- NULL,
- 0.0f,
- 0.0f,
- progress,
- 0,
- NULL);
- UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg);
+ uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block,
+ UI_BTYPE_PROGRESS_BAR,
+ 0,
+ 0,
+ text,
+ UI_UNIT_X,
+ 0,
+ UI_UNIT_X * 6.0f,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0,
+ NULL);
+
+ but_progress->progress = progress;
+ UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg);
}
if (!wm->is_interface_locked) {
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 208fd7136da..4a1c7be918e 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -148,7 +148,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
if (RNA_property_array_check(prop) && index == -1) {
if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
but = uiDefButR_prop(
- block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, 0, 0, NULL);
}
else {
return NULL;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 52835b5474e..d38decd28d1 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;
}
@@ -3609,6 +3609,7 @@ static void widget_scroll(
static void widget_progressbar(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
+ uiButProgressbar *but_progressbar = (uiButProgressbar *)but;
uiWidgetBase wtb, wtb_bar;
rcti rect_prog = *rect, rect_bar = *rect;
@@ -3616,7 +3617,7 @@ static void widget_progressbar(
widget_init(&wtb_bar);
/* round corners */
- float value = but->a1;
+ float value = but_progressbar->progress;
float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
float w = value * BLI_rcti_size_x(&rect_prog);
@@ -3768,6 +3769,8 @@ static void widget_numslider(
static void widget_swatch(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
+ BLI_assert(but->type == UI_BTYPE_COLOR);
+ uiButColor *color_but = (uiButColor *)but;
uiWidgetBase wtb;
float rad, col[4];
@@ -3822,8 +3825,8 @@ static void widget_swatch(
}
widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers);
- if (but->a1 == UI_PALETTE_COLOR &&
- ((Palette *)but->rnapoin.owner_id)->active_color == (int)but->a2) {
+ if (color_but->is_pallete_color &&
+ ((Palette *)but->rnapoin.owner_id)->active_color == color_but->palette_color_index) {
float width = rect->xmax - rect->xmin;
float height = rect->ymax - rect->ymin;
/* find color luminance and change it slightly */
@@ -4552,6 +4555,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);