UI: Make uiBut safe for non-trivial construction

Essentially, I wanted to use a non-trivially-constructible C++ type
(`std::function`) inside `uiBut`. But this would mean we can't use
`MEM_cnew()` like allocation anymore.

Rather than writing worse code, allow non-trivial construction for
`uiBut`. Member-initializing all members is annoying since there are so
many, but rather safe than sorry. As we use more C++ types (e.g. convert
callbacks to use `std::function`), this should become less since they
initialize properly on default construction.

Also use proper C++ inheritance for `uiBut` subtypes, the old way to
allocate based on size isn't working anymore.

Differential Revision: https://developer.blender.org/D17164
This commit is contained in:
Julian Eisel 2023-01-31 17:17:34 +01:00
parent a71ae981c7
commit b4edc40fb8
15 changed files with 244 additions and 303 deletions

View File

@ -322,6 +322,8 @@ enum {
* - bit 9-15: button type (now 6 bits, 64 types)
*/
typedef enum {
UI_BUT_POIN_NONE = 0,
UI_BUT_POIN_CHAR = 32,
UI_BUT_POIN_SHORT = 64,
UI_BUT_POIN_INT = 96,

View File

@ -19,6 +19,7 @@ struct GeometryAttributeInfo;
struct StructRNA;
struct uiBlock;
struct uiBut;
struct uiSearchItems;
namespace blender::ui {

View File

@ -3474,7 +3474,7 @@ static void ui_but_free(const bContext *C, uiBut *but)
BLI_assert(UI_butstore_is_registered(but->block, but) == false);
MEM_freeN(but);
MEM_delete(but);
}
void UI_block_free(const bContext *C, uiBlock *block)
@ -3975,89 +3975,60 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
IMB_colormanagement_scene_linear_to_display_v3(pixel, display);
}
static void ui_but_alloc_info(const eButType type,
size_t *r_alloc_size,
const char **r_alloc_str,
bool *r_has_custom_type)
/**
* Factory function: Allocate button and set #uiBut.type.
*/
static uiBut *ui_but_new(const eButType type)
{
size_t alloc_size;
const char *alloc_str;
bool has_custom_type = true;
uiBut *but = nullptr;
#define NEW_BUT(type_name) MEM_new<type_name>(#type_name)
switch (type) {
case UI_BTYPE_NUM:
alloc_size = sizeof(uiButNumber);
alloc_str = "uiButNumber";
but = MEM_new<uiButNumber>("uiButNumber");
break;
case UI_BTYPE_COLOR:
alloc_size = sizeof(uiButColor);
alloc_str = "uiButColor";
but = MEM_new<uiButColor>("uiButColor");
break;
case UI_BTYPE_DECORATOR:
alloc_size = sizeof(uiButDecorator);
alloc_str = "uiButDecorator";
but = MEM_new<uiButDecorator>("uiButDecorator");
break;
case UI_BTYPE_TAB:
alloc_size = sizeof(uiButTab);
alloc_str = "uiButTab";
but = MEM_new<uiButTab>("uiButTab");
break;
case UI_BTYPE_SEARCH_MENU:
alloc_size = sizeof(uiButSearch);
alloc_str = "uiButSearch";
but = MEM_new<uiButSearch>("uiButSearch");
break;
case UI_BTYPE_PROGRESS_BAR:
alloc_size = sizeof(uiButProgressbar);
alloc_str = "uiButProgressbar";
but = MEM_new<uiButProgressbar>("uiButProgressbar");
break;
case UI_BTYPE_HSVCUBE:
alloc_size = sizeof(uiButHSVCube);
alloc_str = "uiButHSVCube";
but = MEM_new<uiButHSVCube>("uiButHSVCube");
break;
case UI_BTYPE_COLORBAND:
alloc_size = sizeof(uiButColorBand);
alloc_str = "uiButColorBand";
but = MEM_new<uiButColorBand>("uiButColorBand");
break;
case UI_BTYPE_CURVE:
alloc_size = sizeof(uiButCurveMapping);
alloc_str = "uiButCurveMapping";
but = MEM_new<uiButCurveMapping>("uiButCurveMapping");
break;
case UI_BTYPE_CURVEPROFILE:
alloc_size = sizeof(uiButCurveProfile);
alloc_str = "uiButCurveProfile";
but = MEM_new<uiButCurveProfile>("uiButCurveProfile");
break;
case UI_BTYPE_HOTKEY_EVENT:
alloc_size = sizeof(uiButHotkeyEvent);
alloc_str = "uiButHotkeyEvent";
but = MEM_new<uiButHotkeyEvent>("uiButHotkeyEvent");
break;
case UI_BTYPE_VIEW_ITEM:
alloc_size = sizeof(uiButViewItem);
alloc_str = "uiButViewItem";
but = MEM_new<uiButViewItem>("uiButViewItem");
break;
default:
alloc_size = sizeof(uiBut);
alloc_str = "uiBut";
has_custom_type = false;
but = NEW_BUT(uiBut);
break;
}
#undef NEW_BUT
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, nullptr);
return static_cast<uiBut *>(MEM_callocN(alloc_size, alloc_str));
but->type = type;
return but;
}
uiBut *ui_but_change_type(uiBut *but, eButType new_type)
@ -4067,46 +4038,41 @@ uiBut *ui_but_change_type(uiBut *but, eButType new_type)
return but;
}
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, nullptr, nullptr, &old_has_custom_type);
ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type);
const uiBut *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;
const bool has_poin_ptr_to_self = but->poin == (char *)but;
if (new_has_custom_type || old_has_custom_type) {
const uiBut *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;
const bool has_poin_ptr_to_self = but->poin == (char *)but;
but = static_cast<uiBut *>(MEM_recallocN_id(but, alloc_size, alloc_str));
but->type = new_type;
if (has_str_ptr_to_self) {
but->str = but->strdata;
}
if (has_poin_ptr_to_self) {
but->poin = (char *)but;
}
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);
ui_button_group_replace_but_ptr(uiLayoutGetBlock(but->layout), old_but_ptr, but);
}
#ifdef WITH_PYTHON
if (UI_editsource_enable_check()) {
UI_editsource_but_replace(old_but_ptr, but);
}
#endif
/* Copy construct button with the new type. */
but = ui_but_new(new_type);
*but = *old_but_ptr;
if (has_str_ptr_to_self) {
but->str = but->strdata;
}
if (has_poin_ptr_to_self) {
but->poin = (char *)but;
}
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);
ui_button_group_replace_but_ptr(uiLayoutGetBlock(but->layout), old_but_ptr, but);
}
#ifdef WITH_PYTHON
if (UI_editsource_enable_check()) {
UI_editsource_but_replace(old_but_ptr, but);
}
#endif
MEM_delete(old_but_ptr);
return but;
}
@ -4152,14 +4118,11 @@ static uiBut *ui_def_but(uiBlock *block,
}
}
uiBut *but = ui_but_alloc((eButType)(type & BUTTYPE));
uiBut *but = ui_but_new((eButType)(type & BUTTYPE));
but->type = (eButType)(type & BUTTYPE);
but->pointype = (eButPointerType)(type & UI_BUT_POIN_TYPES);
but->bit = type & UI_BUT_POIN_BIT;
but->bitnr = type & 31;
but->icon = ICON_NONE;
but->iconadd = 0;
but->retval = retval;
@ -4180,7 +4143,6 @@ static uiBut *ui_def_but(uiBlock *block,
but->disabled_info = block->lockstr;
but->emboss = block->emboss;
but->pie_dir = UI_RADIAL_NONE;
but->block = block; /* pointer back, used for front-buffer status, and picker. */
@ -6310,7 +6272,7 @@ void UI_but_func_search_set(uiBut *but,
if (search_exec_fn) {
#ifdef DEBUG
if (search_but->but.func) {
if (but->func) {
/* watch this, can be cause of much confusion, see: T47691 */
printf("%s: warning, overwriting button callback with search function callback!\n",
__func__);

View File

@ -113,41 +113,37 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
}
}
static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate)
static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but)
{
uiBut *but_iter = nullptr;
BLI_assert(UI_but_is_decorator(&but_decorate->but));
BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop);
BLI_assert(UI_but_is_decorator(but));
BLI_assert(but->rnapoin.data && but->rnaprop);
LISTBASE_CIRCULAR_BACKWARD_BEGIN (
uiBut *, &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)) {
LISTBASE_CIRCULAR_BACKWARD_BEGIN (uiBut *, &but->block->buttons, but_iter, but->prev) {
if (but_iter != (uiBut *)but &&
ui_but_rna_equals_ex(but_iter, &but->rnapoin, but->rnaprop, but->rnaindex)) {
return but_iter;
}
}
LISTBASE_CIRCULAR_BACKWARD_END(
uiBut *, &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev);
LISTBASE_CIRCULAR_BACKWARD_END(uiBut *, &but->block->buttons, but_iter, but->prev);
return nullptr;
}
void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but)
void ui_but_anim_decorate_update_from_flag(uiButDecorator *but)
{
if (!decorator_but->rnapoin.data || !decorator_but->rnaprop) {
if (!but->rnapoin.data || !but->rnaprop) {
/* Nothing to do. */
return;
}
const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(decorator_but);
uiBut *but = &decorator_but->but;
const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but);
if (!but_anim) {
printf("Could not find button with matching property to decorate (%s.%s)\n",
RNA_struct_identifier(decorator_but->rnapoin.type),
RNA_property_identifier(decorator_but->rnaprop));
RNA_struct_identifier(but->rnapoin.type),
RNA_property_identifier(but->rnaprop));
return;
}
@ -326,7 +322,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/)
}
/* FIXME(@campbellbarton): swapping active pointer is weak. */
std::swap(but_anim->active, but_decorate->but.active);
std::swap(but_anim->active, but_decorate->active);
wm->op_undo_depth++;
if (but_anim->flag & UI_BUT_DRIVEN) {
@ -350,6 +346,6 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/)
WM_operator_properties_free(&props_ptr);
}
std::swap(but_anim->active, but_decorate->but.active);
std::swap(but_anim->active, but_decorate->active);
wm->op_undo_depth--;
}

View File

@ -934,7 +934,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
uiButViewItem *view_item_but = (uiButViewItem *)ui_view_item_find_mouse_over(region,
event->xy);
if (view_item_but) {
BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM);
BLI_assert(view_item_but->type == UI_BTYPE_VIEW_ITEM);
UI_view_item_context_menu_build(C, view_item_but->view_item, uiLayoutColumn(layout, false));
uiItemS(layout);
}

View File

@ -4752,7 +4752,7 @@ static int ui_do_but_VIEW_ITEM(bContext *C,
const wmEvent *event)
{
uiButViewItem *view_item_but = (uiButViewItem *)but;
BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM);
BLI_assert(view_item_but->type == UI_BTYPE_VIEW_ITEM);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE) {
@ -4961,14 +4961,13 @@ static float ui_numedit_apply_snap(int temp,
return temp;
}
static bool ui_numedit_but_NUM(uiButNumber *number_but,
static bool ui_numedit_but_NUM(uiButNumber *but,
uiHandleButtonData *data,
int mx,
const bool is_motion,
const enum eSnapType snap,
float fac)
{
uiBut *but = &number_but->but;
float deler, tempf;
int lvalue, temp;
bool changed = false;
@ -4990,13 +4989,13 @@ static bool ui_numedit_but_NUM(uiButNumber *number_but,
const float log_min = (scale_type == PROP_SCALE_LOG) ?
max_ff(max_ff(softmin, UI_PROP_SCALE_LOG_MIN),
powf(10, -number_but->precision) * 0.5f) :
powf(10, -but->precision) * 0.5f) :
0;
/* Mouse location isn't screen clamped to the screen so use a linear mapping
* 2px == 1-int, or 1px == 1-ClickStep */
if (is_float) {
fac *= 0.01f * number_but->step_size;
fac *= 0.01f * but->step_size;
switch (scale_type) {
case PROP_SCALE_LINEAR: {
tempf = float(data->startvalue) + float(mx - data->dragstartx) * fac;
@ -5170,7 +5169,7 @@ static bool ui_numedit_but_NUM(uiButNumber *number_but,
}
case PROP_SCALE_LOG: {
const float log_min = max_ff(max_ff(softmin, UI_PROP_SCALE_LOG_MIN),
powf(10.0f, -number_but->precision) * 0.5f);
powf(10.0f, -but->precision) * 0.5f);
const float base = softmax / log_min;
tempf = powf(base, data->dragf) * log_min;
if (tempf <= log_min) {
@ -6148,8 +6147,8 @@ static bool ui_numedit_but_UNITVEC(
static void ui_palette_set_active(uiButColor *color_but)
{
if (color_but->is_pallete_color) {
Palette *palette = (Palette *)color_but->but.rnapoin.owner_id;
PaletteColor *color = static_cast<PaletteColor *>(color_but->but.rnapoin.data);
Palette *palette = (Palette *)color_but->rnapoin.owner_id;
PaletteColor *color = static_cast<PaletteColor *>(color_but->rnapoin.data);
palette->active_color = BLI_findindex(&palette->colors, color);
}
}

View File

@ -152,24 +152,25 @@ enum {
#define PIE_MAX_ITEMS 8
struct uiBut {
uiBut *next, *prev;
uiBut *next = nullptr, *prev = nullptr;
/** Pointer back to the layout item holding this button. */
uiLayout *layout;
int flag, drawflag;
eButType type;
eButPointerType pointype;
short bit, bitnr, retval, strwidth, alignnr;
short ofs, pos, selsta, selend;
uiLayout *layout = nullptr;
int flag = 0;
int drawflag = 0;
eButType type = eButType(0);
eButPointerType pointype = UI_BUT_POIN_NONE;
short bit = 0, bitnr = 0, retval = 0, strwidth = 0, alignnr = 0;
short ofs = 0, pos = 0, selsta = 0, selend = 0;
char *str;
char strdata[UI_MAX_NAME_STR];
char drawstr[UI_MAX_DRAW_STR];
char *str = nullptr;
char strdata[UI_MAX_NAME_STR] = "";
char drawstr[UI_MAX_DRAW_STR] = "";
rctf rect; /* block relative coords */
rctf rect = {}; /* block relative coords */
char *poin;
float hardmin, hardmax, softmin, softmax;
char *poin = nullptr;
float hardmin = 0, hardmax = 0, softmin = 0, softmax = 0;
/* both these values use depends on the button type
* (polymorphic struct or union would be nicer for this stuff) */
@ -180,7 +181,7 @@ struct uiBut {
* - UI_BTYPE_SCROLL: Use as scroll size.
* - UI_BTYPE_SEARCH_MENU: Use as number or rows.
*/
float a1;
float a1 = 0;
/**
* For #uiBut.type:
@ -188,210 +189,193 @@ struct uiBut {
* - UI_BTYPE_LABEL: If `(a1 == 1.0f)` use a2 as a blending factor.
* - UI_BTYPE_SEARCH_MENU: Use as number or columns.
*/
float a2;
float a2 = 0;
uchar col[4];
uchar col[4] = {0};
/** See \ref UI_but_func_identity_compare_set(). */
uiButIdentityCompareFunc identity_cmp_func;
uiButIdentityCompareFunc identity_cmp_func = nullptr;
uiButHandleFunc func;
void *func_arg1;
void *func_arg2;
uiButHandleFunc func = nullptr;
void *func_arg1 = nullptr;
void *func_arg2 = nullptr;
uiButHandleNFunc funcN;
void *func_argN;
uiButHandleNFunc funcN = nullptr;
void *func_argN = nullptr;
bContextStore *context;
bContextStore *context = nullptr;
uiButCompleteFunc autocomplete_func;
void *autofunc_arg;
uiButCompleteFunc autocomplete_func = nullptr;
void *autofunc_arg = nullptr;
uiButHandleRenameFunc rename_func;
void *rename_arg1;
void *rename_orig;
uiButHandleRenameFunc rename_func = nullptr;
void *rename_arg1 = nullptr;
void *rename_orig = nullptr;
/** Run an action when holding the button down. */
uiButHandleHoldFunc hold_func;
void *hold_argN;
uiButHandleHoldFunc hold_func = nullptr;
void *hold_argN = nullptr;
const char *tip;
uiButToolTipFunc tip_func;
void *tip_arg;
uiFreeArgFunc tip_arg_free;
const char *tip = nullptr;
uiButToolTipFunc tip_func = nullptr;
void *tip_arg = nullptr;
uiFreeArgFunc tip_arg_free = nullptr;
/** info on why button is disabled, displayed in tooltip */
const char *disabled_info;
const char *disabled_info = nullptr;
BIFIconID icon;
BIFIconID icon = ICON_NONE;
/** Copied from the #uiBlock.emboss */
eUIEmbossType emboss;
eUIEmbossType emboss = UI_EMBOSS;
/** direction in a pie menu, used for collision detection. */
RadialDirection pie_dir;
RadialDirection pie_dir = UI_RADIAL_NONE;
/** could be made into a single flag */
bool changed;
bool changed = false;
/** so buttons can support unit systems which are not RNA */
uchar unit_type;
short iconadd;
uchar unit_type = 0;
short iconadd = 0;
/** #UI_BTYPE_BLOCK data */
uiBlockCreateFunc block_create_func;
uiBlockCreateFunc block_create_func = nullptr;
/** #UI_BTYPE_PULLDOWN / #UI_BTYPE_MENU data */
uiMenuCreateFunc menu_create_func;
uiMenuCreateFunc menu_create_func = nullptr;
uiMenuStepFunc menu_step_func;
uiMenuStepFunc menu_step_func = nullptr;
/* RNA data */
PointerRNA rnapoin;
PropertyRNA *rnaprop;
int rnaindex;
PointerRNA rnapoin = {};
PropertyRNA *rnaprop = nullptr;
int rnaindex = -1;
/* Operator data */
wmOperatorType *optype;
PointerRNA *opptr;
wmOperatorCallContext opcontext;
wmOperatorType *optype = nullptr;
PointerRNA *opptr = nullptr;
wmOperatorCallContext opcontext = WM_OP_INVOKE_DEFAULT;
/** When non-zero, this is the key used to activate a menu items (`a-z` always lower case). */
uchar menu_key;
uchar menu_key = 0;
ListBase extra_op_icons; /** #uiButExtraOpIcon */
ListBase extra_op_icons = {nullptr, nullptr}; /** #uiButExtraOpIcon */
/* Drag-able data, type is WM_DRAG_... */
char dragtype;
short dragflag;
void *dragpoin;
ImBuf *imb;
float imb_scale;
char dragtype = WM_DRAG_ID;
short dragflag = 0;
void *dragpoin = nullptr;
ImBuf *imb = nullptr;
float imb_scale = 0;
/** Active button data (set when the user is hovering or interacting with a button). */
uiHandleButtonData *active;
uiHandleButtonData *active = nullptr;
/** Custom button data (borrowed, not owned). */
void *custom_data;
void *custom_data = nullptr;
char *editstr;
double *editval;
float *editvec;
char *editstr = nullptr;
double *editval = nullptr;
float *editvec = nullptr;
uiButPushedStateFunc pushed_state_func;
const void *pushed_state_arg;
uiButPushedStateFunc pushed_state_func = nullptr;
const void *pushed_state_arg = nullptr;
/** Little indicator (e.g., counter) displayed on top of some icons. */
IconTextOverlay icon_overlay_text;
IconTextOverlay icon_overlay_text = {};
/* pointer back */
uiBlock *block;
uiBlock *block = nullptr;
uiBut() = default;
/** Performs a mostly shallow copy for now. Only contained C++ types are deep copied. */
uiBut(const uiBut &other) = default;
/** Mostly shallow copy, just like copy constructor above. */
uiBut &operator=(const uiBut &other) = default;
};
/** Derived struct for #UI_BTYPE_NUM */
struct uiButNumber {
uiBut but;
float step_size;
float precision;
struct uiButNumber : public uiBut {
float step_size = 0;
float precision = 0;
};
/** Derived struct for #UI_BTYPE_COLOR */
struct uiButColor {
uiBut but;
bool is_pallete_color;
int palette_color_index;
struct uiButColor : public uiBut {
bool is_pallete_color = false;
int palette_color_index = -1;
};
/** Derived struct for #UI_BTYPE_TAB */
struct uiButTab {
uiBut but;
struct MenuType *menu;
struct uiButTab : public uiBut {
struct MenuType *menu = nullptr;
};
/** Derived struct for #UI_BTYPE_SEARCH_MENU */
struct uiButSearch {
uiBut but;
struct uiButSearch : public uiBut {
uiButSearchCreateFn popup_create_fn = nullptr;
uiButSearchUpdateFn items_update_fn = nullptr;
uiButSearchListenFn listen_fn = nullptr;
uiButSearchCreateFn popup_create_fn;
uiButSearchUpdateFn items_update_fn;
uiButSearchListenFn listen_fn;
void *item_active = nullptr;
void *item_active;
void *arg = nullptr;
uiFreeArgFunc arg_free_fn = nullptr;
void *arg;
uiFreeArgFunc arg_free_fn;
uiButSearchContextMenuFn item_context_menu_fn = nullptr;
uiButSearchTooltipFn item_tooltip_fn = nullptr;
uiButSearchContextMenuFn item_context_menu_fn;
uiButSearchTooltipFn item_tooltip_fn;
const char *item_sep_string = nullptr;
const char *item_sep_string;
PointerRNA rnasearchpoin;
PropertyRNA *rnasearchprop;
PointerRNA rnasearchpoin = {};
PropertyRNA *rnasearchprop = nullptr;
/**
* The search box only provides suggestions, it does not force
* the string to match one of the search items when applying.
*/
bool results_are_suggestions;
bool results_are_suggestions = false;
};
/** Derived struct for #UI_BTYPE_DECORATOR */
struct uiButDecorator {
uiBut but;
struct PointerRNA rnapoin;
struct PropertyRNA *rnaprop;
int rnaindex;
struct uiButDecorator : public uiBut {
struct PointerRNA rnapoin = {};
struct PropertyRNA *rnaprop = nullptr;
int rnaindex = -1;
};
/** Derived struct for #UI_BTYPE_PROGRESS_BAR. */
struct uiButProgressbar {
uiBut but;
struct uiButProgressbar : public uiBut {
/* 0..1 range */
float progress;
float progress = 0;
};
struct uiButViewItem {
uiBut but;
struct uiButViewItem : public uiBut {
/* C-Handle to the view item this button was created for. */
uiViewItemHandle *view_item;
uiViewItemHandle *view_item = nullptr;
};
/** Derived struct for #UI_BTYPE_HSVCUBE. */
struct uiButHSVCube {
uiBut but;
eButGradientType gradient_type;
struct uiButHSVCube : public uiBut {
eButGradientType gradient_type = UI_GRAD_SV;
};
/** Derived struct for #UI_BTYPE_COLORBAND. */
struct uiButColorBand {
uiBut but;
ColorBand *edit_coba;
struct uiButColorBand : public uiBut {
ColorBand *edit_coba = nullptr;
};
/** Derived struct for #UI_BTYPE_CURVEPROFILE. */
struct uiButCurveProfile {
uiBut but;
struct CurveProfile *edit_profile;
struct uiButCurveProfile : public uiBut {
struct CurveProfile *edit_profile = nullptr;
};
/** Derived struct for #UI_BTYPE_CURVE. */
struct uiButCurveMapping {
uiBut but;
struct CurveMapping *edit_cumap;
eButGradientType gradient_type;
struct uiButCurveMapping : public uiBut {
struct CurveMapping *edit_cumap = nullptr;
eButGradientType gradient_type = UI_GRAD_SV;
};
/** Derived struct for #UI_BTYPE_HOTKEY_EVENT. */
struct uiButHotkeyEvent {
uiBut but;
short modifier_key;
struct uiButHotkeyEvent : public uiBut {
short modifier_key = 0;
};
/**

View File

@ -3139,28 +3139,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++) {
uiButDecorator *decorator_but = (uiButDecorator *)uiDefIconBut(block,
UI_BTYPE_DECORATOR,
0,
ICON_DOT,
0,
0,
UI_UNIT_X,
UI_UNIT_Y,
nullptr,
0.0,
0.0,
0.0,
0.0,
TIP_("Animate property"));
uiButDecorator *but = (uiButDecorator *)uiDefIconBut(block,
UI_BTYPE_DECORATOR,
0,
ICON_DOT,
0,
0,
UI_UNIT_X,
UI_UNIT_Y,
nullptr,
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, nullptr);
decorator_but->but.flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
UI_but_func_set(but, ui_but_anim_decorate_cb, but, nullptr);
but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
/* Reusing RNA search members, setting actual RNA data has many side-effects. */
decorator_but->rnapoin = *ptr;
decorator_but->rnaprop = prop;
but->rnapoin = *ptr;
but->rnaprop = prop;
/* ui_def_but_rna() sets non-array buttons to have a RNA index of 0. */
decorator_but->rnaindex = (!is_array || is_expand) ? i : index;
but->rnaindex = (!is_array || is_expand) ? i : index;
}
}

View File

@ -1658,8 +1658,8 @@ static void ui_editsource_active_but_set(uiBut *but)
{
BLI_assert(ui_editsource_info == nullptr);
ui_editsource_info = MEM_cnew<uiEditSourceStore>(__func__);
memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));
ui_editsource_info = MEM_new<uiEditSourceStore>(__func__);
ui_editsource_info->but_orig = *but;
ui_editsource_info->hash = BLI_ghash_ptr_new(__func__);
}

View File

@ -397,7 +397,7 @@ static void ui_colorpicker_circle(uiBlock *block,
0,
"Lightness");
hsv_but->gradient_type = UI_GRAD_L_ALT;
UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
UI_but_func_set(hsv_but, ui_colorpicker_rgba_update_cb, hsv_but, nullptr);
}
else {
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
@ -417,9 +417,9 @@ static void ui_colorpicker_circle(uiBlock *block,
0,
TIP_("Value"));
hsv_but->gradient_type = UI_GRAD_V_ALT;
UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
UI_but_func_set(hsv_but, ui_colorpicker_rgba_update_cb, hsv_but, nullptr);
}
hsv_but->but.custom_data = cpicker;
hsv_but->custom_data = cpicker;
}
static void ui_colorpicker_square(uiBlock *block,
@ -450,8 +450,8 @@ static void ui_colorpicker_square(uiBlock *block,
0,
TIP_("Color"));
hsv_but->gradient_type = type;
UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
hsv_but->but.custom_data = cpicker;
UI_but_func_set(hsv_but, ui_colorpicker_rgba_update_cb, hsv_but, nullptr);
hsv_but->custom_data = cpicker;
/* value */
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
@ -471,8 +471,8 @@ static void ui_colorpicker_square(uiBlock *block,
0,
TIP_("Value"));
hsv_but->gradient_type = (eButGradientType)(type + 3);
UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
hsv_but->but.custom_data = cpicker;
UI_but_func_set(hsv_but, ui_colorpicker_rgba_update_cb, hsv_but, nullptr);
hsv_but->custom_data = cpicker;
}
/* a HS circle, V slider, rgb/hsv/hex sliders */

View File

@ -433,17 +433,17 @@ bool ui_searchbox_event(
/** Wrap #uiButSearchUpdateFn callback. */
static void ui_searchbox_update_fn(bContext *C,
uiButSearch *search_but,
uiButSearch *but,
const char *str,
uiSearchItems *items)
{
/* While the button is in text editing mode (searchbox open), remove tooltips on every update. */
if (search_but->but.editstr) {
if (but->editstr) {
wmWindow *win = CTX_wm_window(C);
WM_tooltip_clear(C, win);
}
const bool is_first_search = !search_but->but.changed;
search_but->items_update_fn(C, search_but->arg, str, items, is_first_search);
const bool is_first_search = !but->changed;
but->items_update_fn(C, but->arg, str, items, is_first_search);
}
void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset)
@ -464,7 +464,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
data->active = -1;
/* On init, find and center active item. */
const bool is_first_search = !search_but->but.changed;
const bool is_first_search = !but->changed;
if (is_first_search && 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);
@ -704,12 +704,11 @@ static void ui_searchbox_region_listen_fn(const wmRegionListenerParams *params)
static ARegion *ui_searchbox_create_generic_ex(bContext *C,
ARegion *butregion,
uiButSearch *search_but,
uiButSearch *but,
const bool use_shortcut_sep)
{
wmWindow *win = CTX_wm_window(C);
const uiStyle *style = UI_style_get();
uiBut *but = &search_but->but;
const float aspect = but->block->aspect;
const int margin = UI_POPUP_MARGIN;
@ -726,8 +725,8 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
/* Create search-box data. */
uiSearchboxData *data = MEM_cnew<uiSearchboxData>(__func__);
data->search_arg = search_but->arg;
data->search_listener = search_but->listen_fn;
data->search_arg = but->arg;
data->search_listener = but->listen_fn;
/* Set font, get the bounding-box. */
data->fstyle = style->widget; /* copy struct */
@ -751,7 +750,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
if (but->optype != nullptr || use_shortcut_sep) {
data->use_shortcut_sep = true;
}
data->sep_string = search_but->item_sep_string;
data->sep_string = but->item_sep_string;
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
@ -1013,10 +1012,8 @@ ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *
return region;
}
void ui_but_search_refresh(uiButSearch *search_but)
void ui_but_search_refresh(uiButSearch *but)
{
uiBut *but = &search_but->but;
/* possibly very large lists (such as ID datablocks) only
* only validate string RNA buts (not pointers) */
if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
@ -1033,9 +1030,9 @@ void ui_but_search_refresh(uiButSearch *search_but)
items->names[i] = (char *)MEM_callocN(but->hardmax + 1, __func__);
}
ui_searchbox_update_fn((bContext *)but->block->evil_C, search_but, but->drawstr, items);
ui_searchbox_update_fn((bContext *)but->block->evil_C, but, but->drawstr, items);
if (!search_but->results_are_suggestions) {
if (!but->results_are_suggestions) {
/* Only red-alert when we are sure of it, this can miss cases when >10 matches. */
if (items->totitem == 0) {
UI_but_flag_enable(but, UI_BUT_REDALERT);

View File

@ -1677,12 +1677,12 @@ static void template_ID_tabs(const bContext *C,
0.0f,
0.0f,
"");
UI_but_funcN_set(&tab->but, template_ID_set_property_exec_fn, MEM_dupallocN(template_id), id);
UI_but_drag_set_id(&tab->but, id);
tab->but.custom_data = (void *)id;
UI_but_funcN_set(tab, template_ID_set_property_exec_fn, MEM_dupallocN(template_id), id);
UI_but_drag_set_id(tab, id);
tab->custom_data = (void *)id;
tab->menu = mt;
UI_but_drawflag_enable(&tab->but, but_align);
UI_but_drawflag_enable(tab, but_align);
}
BLI_freelistN(&ordered);
@ -5639,7 +5639,7 @@ void uiTemplateColorPicker(uiLayout *layout,
hsv_but->gradient_type = UI_GRAD_HV;
break;
}
but = &hsv_but->but;
but = hsv_but;
break;
/* user default */
@ -5785,7 +5785,7 @@ void uiTemplateColorPicker(uiLayout *layout,
break;
}
hsv_but->but.custom_data = cpicker;
hsv_but->custom_data = cpicker;
}
}
@ -6286,7 +6286,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
nullptr);
but_progress->progress = progress;
UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg, MEM_freeN);
UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg, MEM_freeN);
}
if (!wm->is_interface_locked) {

View File

@ -3152,7 +3152,7 @@ void ui_hsvcube_pos_from_vals(
case UI_GRAD_V_ALT:
x = 0.5f;
/* exception only for value strip - use the range set in but->min/max */
y = (hsv[2] - hsv_but->but.softmin) / (hsv_but->but.softmax - hsv_but->but.softmin);
y = (hsv[2] - hsv_but->softmin) / (hsv_but->softmax - hsv_but->softmin);
break;
}

View File

@ -130,7 +130,7 @@ void AbstractGridViewItem::add_grid_tile_button(uiBlock &block)
"");
view_item_but_->view_item = reinterpret_cast<uiViewItemHandle *>(this);
UI_but_func_set(&view_item_but_->but, grid_tile_click_fn, view_item_but_, nullptr);
UI_but_func_set(view_item_but_, grid_tile_click_fn, view_item_but_, nullptr);
}
void AbstractGridViewItem::on_activate()

View File

@ -136,7 +136,7 @@ void AbstractTreeViewItem::add_treerow_button(uiBlock &block)
&block, UI_BTYPE_VIEW_ITEM, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nullptr, 0, 0, 0, 0, "");
view_item_but_->view_item = reinterpret_cast<uiViewItemHandle *>(this);
UI_but_func_set(&view_item_but_->but, tree_row_click_fn, view_item_but_, nullptr);
UI_but_func_set(view_item_but_, tree_row_click_fn, view_item_but_, nullptr);
}
void AbstractTreeViewItem::add_indent(uiLayout &row) const
@ -322,8 +322,8 @@ bool AbstractTreeViewItem::is_hovered() const
/* The new layout hasn't finished construction yet, so the final state of the button is unknown.
* Get the matching button from the previous redraw instead. */
uiButViewItem *old_item_but = ui_block_view_find_matching_view_item_but_in_old_block(
view_item_but_->but.block, this_item_handle);
return old_item_but && (old_item_but->but.flag & UI_ACTIVE);
view_item_but_->block, this_item_handle);
return old_item_but && (old_item_but->flag & UI_ACTIVE);
}
bool AbstractTreeViewItem::is_collapsed() const