UI: Make uiBut safe for non-trivial construction
No user-visible changes expected. Essentially, this makes it possible to use C++ types like `std::function` inside `uiBut`. This has plenty of benefits, for example this should help significantly reducing unsafe `void *` use (since a `std::function` can hold arbitrary data while preserving types). ---- 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 Reviewed by: Hans Goudey
This commit is contained in:
@@ -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,195 @@ 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 = 0;
|
||||
|
||||
/* 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;
|
||||
/** Derived struct for #UI_BTYPE_DECORATOR
|
||||
* Decorators have own RNA data, using the normal #uiBut RNA members has many side-effects.
|
||||
*/
|
||||
struct uiButDecorator : public uiBut {
|
||||
struct PointerRNA decorated_rnapoin = {};
|
||||
struct PropertyRNA *decorated_rnaprop = nullptr;
|
||||
int decorated_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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user