diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index 02f242a48bb..523ba4d58ce 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -1412,47 +1412,30 @@ const bContextStore *UI_but_context_get(const uiBut *but); void UI_but_unit_type_set(uiBut *but, int unit_type); int UI_but_unit_type_get(const uiBut *but); -enum uiStringInfoType { - /** - * Ignore this item, use when accessing the data should be done conditionally. - */ - BUT_GET_NOP = 0, - - BUT_GET_RNAPROP_IDENTIFIER, - BUT_GET_RNASTRUCT_IDENTIFIER, - BUT_GET_RNAENUM_IDENTIFIER, - BUT_GET_LABEL, - /** - * Query the result of #uiBut::tip_label_func(). - * Meant to allow overriding the label to be displayed in the tool-tip. - */ - BUT_GET_TIP_LABEL, - BUT_GET_RNA_LABEL, - BUT_GET_RNAENUM_LABEL, - /** Context specified in `CTX_*_` macros are just unreachable! */ - BUT_GET_RNA_LABEL_CONTEXT, - BUT_GET_TIP, - BUT_GET_RNA_TIP, - BUT_GET_RNAENUM_TIP, - /** Buttons assigned to an operator (common case). */ - BUT_GET_OP_KEYMAP, - /** Use for properties that are bound to one of the context cycle, etc. keys. */ - BUT_GET_PROP_KEYMAP, -}; - -struct uiStringInfo { - uiStringInfoType type; - char *strinfo; -}; +std::optional UI_but_rna_enum_item_get(bContext &C, uiBut &but); +std::string UI_but_string_get_rna_property_identifier(const uiBut &but); +std::string UI_but_string_get_rna_struct_identifier(const uiBut &but); +std::string UI_but_string_get_label(uiBut &but); /** - * \note Expects pointers to #uiStringInfo structs as parameters. - * Will fill them with translated strings, when possible. - * Strings in #uiStringInfo must be MEM_freeN'ed by caller. + * Query the result of #uiBut::tip_label_func(). + * Meant to allow overriding the label to be displayed in the tool-tip. */ -void UI_but_string_info_get(bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); -void UI_but_extra_icon_string_info_get(bContext *C, uiButExtraOpIcon *extra_icon, ...) - ATTR_SENTINEL(0); +std::string UI_but_string_get_tooltip_label(const uiBut &but); +std::string UI_but_string_get_rna_label(uiBut &but); +/** Context specified in `CTX_*_` macros are just unreachable! */ +std::string UI_but_string_get_rna_label_context(const uiBut &but); +std::string UI_but_string_get_tooltip(bContext &C, uiBut &but); +std::string UI_but_string_get_rna_tooltip(bContext &C, uiBut &but); +/** Buttons assigned to an operator (common case). */ +std::string UI_but_string_get_operator_keymap(bContext &C, uiBut &but); +/** Use for properties that are bound to one of the context cycle, etc. keys. */ +std::string UI_but_string_get_property_keymap(bContext &C, uiBut &but); + +std::string UI_but_extra_icon_string_get_label(const uiButExtraOpIcon &extra_icon); +std::string UI_but_extra_icon_string_get_tooltip(bContext &C, const uiButExtraOpIcon &extra_icon); +std::string UI_but_extra_icon_string_get_operator_keymap(const bContext &C, + const uiButExtraOpIcon &extra_icon); /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ @@ -1867,8 +1850,8 @@ PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, const char *opname, wmOperatorCallContext opcontext, int icon); -wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon); -PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon); +wmOperatorType *UI_but_extra_operator_icon_optype_get(const uiButExtraOpIcon *extra_icon); +PointerRNA *UI_but_extra_operator_icon_opptr_get(const uiButExtraOpIcon *extra_icon); /** * Get the scaled size for a preview button (typically #UI_BTyPE_PREVIEW_TILE) based on \a @@ -2241,11 +2224,11 @@ wmOperatorType *UI_but_operatortype_get_from_enum_menu(uiBut *but, PropertyRNA * /** * This is a bit of a hack but best keep it in one place at least. */ -MenuType *UI_but_menutype_get(uiBut *but); +MenuType *UI_but_menutype_get(const uiBut *but); /** * This is a bit of a hack but best keep it in one place at least. */ -PanelType *UI_but_paneltype_get(uiBut *but); +PanelType *UI_but_paneltype_get(const uiBut *but); void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout); /** * Used for popup panels only. diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index a1fccfec2a3..85ecc0913f4 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -1340,7 +1340,7 @@ static bool ui_but_event_operator_string(const bContext *C, } static bool ui_but_extra_icon_event_operator_string(const bContext *C, - uiButExtraOpIcon *extra_icon, + const uiButExtraOpIcon *extra_icon, char *buf, const size_t buf_maxncpy) { @@ -1715,12 +1715,12 @@ PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, return nullptr; } -wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon) +wmOperatorType *UI_but_extra_operator_icon_optype_get(const uiButExtraOpIcon *extra_icon) { return extra_icon ? extra_icon->optype_params->optype : nullptr; } -PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon) +PointerRNA *UI_but_extra_operator_icon_opptr_get(const uiButExtraOpIcon *extra_icon) { return extra_icon->optype_params->opptr; } @@ -6563,287 +6563,227 @@ void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN) but->hold_argN = argN; } -void UI_but_string_info_get(bContext *C, uiBut *but, ...) +std::optional UI_but_rna_enum_item_get(bContext &C, uiBut &but) { - va_list args; - uiStringInfo *si; - - PointerRNA *opptr = UI_but_operator_ptr_get(but); - - const EnumPropertyItem *items = nullptr, *item = nullptr; - int totitems; - bool free_items = false; - - va_start(args, but); - while ((si = (uiStringInfo *)va_arg(args, void *))) { - uiStringInfoType type = si->type; - std::optional tmp; - - if (type == BUT_GET_TIP_LABEL) { - if (but->tip_label_func) { - tmp = but->tip_label_func(but); - } - } - - if (type == BUT_GET_LABEL) { - if (!but->str.empty()) { - size_t str_len = but->str.size(); - if (but->flag & UI_BUT_HAS_SEP_CHAR) { - const size_t sep_index = but->str.find_first_of(UI_SEP_CHAR); - if (sep_index != std::string::npos) { - str_len = sep_index; - } - } - tmp = but->str.substr(0, str_len); - } - else { - type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */ - } - } - else if (type == BUT_GET_TIP) { - if (but->tip_func) { - tmp = but->tip_func(C, but->tip_arg, but->tip); - } - else if (but->tip && but->tip[0]) { - tmp = but->tip; - } - else { - type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ - } - } - - if (type == BUT_GET_RNAPROP_IDENTIFIER) { - if (but->rnaprop) { - tmp = RNA_property_identifier(but->rnaprop); - } - } - else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) { - if (but->rnaprop && but->rnapoin.data) { - tmp = RNA_struct_identifier(but->rnapoin.type); - } - else if (but->optype) { - tmp = but->optype->idname; - } - else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { - MenuType *mt = UI_but_menutype_get(but); - if (mt) { - tmp = mt->idname; - } - } - else if (but->type == UI_BTYPE_POPOVER) { - PanelType *pt = UI_but_paneltype_get(but); - if (pt) { - tmp = pt->idname; - } - } - } - else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) { - if (but->rnaprop) { - if (type == BUT_GET_RNA_LABEL) { - tmp = RNA_property_ui_name(but->rnaprop); - } - else { - const char *t = RNA_property_ui_description(but->rnaprop); - if (t && t[0]) { - tmp = t; - } - } - } - else if (but->optype) { - if (type == BUT_GET_RNA_LABEL) { - tmp = WM_operatortype_name(but->optype, opptr).c_str(); - } - else { - const bContextStore *previous_ctx = CTX_store_get(C); - CTX_store_set(C, but->context); - tmp = WM_operatortype_description(C, but->optype, opptr).c_str(); - CTX_store_set(C, previous_ctx); - } - } - else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { - { - MenuType *mt = UI_but_menutype_get(but); - if (mt) { - if (type == BUT_GET_RNA_LABEL) { - tmp = CTX_TIP_(mt->translation_context, mt->label); - } - else { - /* Not all menus are from Python. */ - if (mt->rna_ext.srna) { - const char *t = RNA_struct_ui_description(mt->rna_ext.srna); - if (t && t[0]) { - tmp = t; - } - } - } - } - } - - if (!tmp) { - wmOperatorType *ot = UI_but_operatortype_get_from_enum_menu(but, nullptr); - if (ot) { - if (type == BUT_GET_RNA_LABEL) { - tmp = WM_operatortype_name(ot, nullptr).c_str(); - } - else { - tmp = WM_operatortype_description(C, ot, nullptr).c_str(); - } - } - } - - if (!tmp) { - PanelType *pt = UI_but_paneltype_get(but); - if (pt) { - if (type == BUT_GET_RNA_LABEL) { - tmp = CTX_TIP_(pt->translation_context, pt->label); - } - else { - /* Not all panels are from Python. */ - if (pt->rna_ext.srna) { - /* Panels don't yet have descriptions, this may be added. */ - } - } - } - } - } - } - else if (type == BUT_GET_RNA_LABEL_CONTEXT) { - const char *_tmp = BLT_I18NCONTEXT_DEFAULT; - if (but->rnaprop) { - _tmp = RNA_property_translation_context(but->rnaprop); - } - else if (but->optype) { - _tmp = RNA_struct_translation_context(but->optype->srna); - } - else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { - MenuType *mt = UI_but_menutype_get(but); - if (mt) { - _tmp = RNA_struct_translation_context(mt->rna_ext.srna); - } - } - if (BLT_is_default_context(_tmp)) { - _tmp = BLT_I18NCONTEXT_DEFAULT_BPYRNA; - } - tmp = _tmp; - } - else if (ELEM(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { - PointerRNA *ptr = nullptr; - PropertyRNA *prop = nullptr; - int value = 0; - - /* get the enum property... */ - if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { - /* enum property */ - ptr = &but->rnapoin; - prop = but->rnaprop; - value = ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB) ? int(but->hardmax) : - int(ui_but_value_get(but)); - } - else if (but->optype) { - wmOperatorType *ot = but->optype; - - /* So the context is passed to `itemf` functions. */ - WM_operator_properties_sanitize(opptr, false); - - /* if the default property of the operator is enum and it is set, - * fetch the tooltip of the selected value so that "Snap" and "Mirror" - * operator menus in the Anim Editors will show tooltips for the different - * operations instead of the meaningless generic operator tooltip - */ - if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { - if (RNA_struct_contains_property(opptr, ot->prop)) { - ptr = opptr; - prop = ot->prop; - value = RNA_property_enum_get(opptr, ot->prop); - } - } - } - - /* get strings from matching enum item */ - if (ptr && prop) { - if (!item) { - int i; - - RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items); - for (i = 0, item = items; i < totitems; i++, item++) { - if (item->identifier[0] && item->value == value) { - break; - } - } - } - if (item && item->identifier) { - if (type == BUT_GET_RNAENUM_IDENTIFIER) { - tmp = item->identifier; - } - else if (type == BUT_GET_RNAENUM_LABEL) { - tmp = item->name; - } - else if (item->description && item->description[0]) { - tmp = item->description; - } - } - } - } - /* NOTE: Menus will already have their shortcuts displayed. - * Pie menus are an exception as they already have a shortcut on display - * however this is only used within the context of the pie menu. */ - else if (type == BUT_GET_OP_KEYMAP) { - char buf[128]; - if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { - tmp = buf; - } - } - else if (type == BUT_GET_PROP_KEYMAP) { - char buf[128]; - if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { - tmp = buf; - } - } - - si->strinfo = tmp ? BLI_strdupn(tmp->c_str(), tmp->size()) : nullptr; + PointerRNA *ptr = nullptr; + PropertyRNA *prop = nullptr; + int value = 0; + if (but.rnaprop && RNA_property_type(but.rnaprop) == PROP_ENUM) { + ptr = &but.rnapoin; + prop = but.rnaprop; + value = ELEM(but.type, UI_BTYPE_ROW, UI_BTYPE_TAB) ? int(but.hardmax) : + int(ui_but_value_get(&but)); } - va_end(args); + else if (but.optype) { + wmOperatorType *ot = but.optype; - if (free_items && items) { - MEM_freeN((void *)items); + /* So the context is passed to `itemf` functions. */ + PointerRNA *opptr = UI_but_operator_ptr_get(&but); + WM_operator_properties_sanitize(opptr, false); + + /* If the default property of the operator is an enum and is set, fetch the tooltip of the + * selected value so that "Snap" and "Mirror" operator menus in the Animation Editors will + * show tooltips for the different operations instead of the meaningless generic tooltip. */ + if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, ot->prop)) { + ptr = opptr; + prop = ot->prop; + value = RNA_property_enum_get(opptr, ot->prop); + } + } } + + if (!ptr || !prop) { + return std::nullopt; + } + + EnumPropertyItem item; + if (!RNA_property_enum_item_from_value_gettexted(&C, ptr, prop, value, &item)) { + return std::nullopt; + } + + return item; } -void UI_but_extra_icon_string_info_get(bContext *C, uiButExtraOpIcon *extra_icon, ...) +std::string UI_but_string_get_rna_property_identifier(const uiBut &but) { - va_list args; - uiStringInfo *si; + if (!but.rnaprop) { + return {}; + } + return RNA_property_identifier(but.rnaprop); +} - wmOperatorType *optype = UI_but_extra_operator_icon_optype_get(extra_icon); - PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(extra_icon); +std::string UI_but_string_get_rna_struct_identifier(const uiBut &but) +{ + if (but.rnaprop && but.rnapoin.data) { + return RNA_struct_identifier(but.rnapoin.type); + } + if (but.optype) { + return but.optype->idname; + } + if (ELEM(but.type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + if (MenuType *mt = UI_but_menutype_get(&but)) { + return mt->idname; + } + } + if (but.type == UI_BTYPE_POPOVER) { + if (PanelType *pt = UI_but_paneltype_get(&but)) { + return pt->idname; + } + } + return {}; +} - va_start(args, extra_icon); - while ((si = (uiStringInfo *)va_arg(args, void *))) { - std::string tmp; - - switch (si->type) { - case BUT_GET_LABEL: - tmp = WM_operatortype_name(optype, opptr); - break; - case BUT_GET_TIP: - tmp = WM_operatortype_description(C, optype, opptr); - break; - case BUT_GET_OP_KEYMAP: { - char buf[128]; - if (ui_but_extra_icon_event_operator_string(C, extra_icon, buf, sizeof(buf))) { - tmp = buf; - } - break; +std::string UI_but_string_get_label(uiBut &but) +{ + if (!but.str.empty()) { + size_t str_len = but.str.size(); + if (but.flag & UI_BUT_HAS_SEP_CHAR) { + const size_t sep_index = but.str.find_first_of(UI_SEP_CHAR); + if (sep_index != std::string::npos) { + str_len = sep_index; } - default: - /* Other types not supported. The caller should expect that outcome, no need to message or - * assert here. */ - break; + } + return but.str.substr(0, str_len); + } + return UI_but_string_get_rna_label(but); +} + +std::string UI_but_string_get_tooltip_label(const uiBut &but) +{ + if (!but.tip_label_func) { + return {}; + } + return but.tip_label_func(&but); +} + +std::string UI_but_string_get_rna_label(uiBut &but) +{ + if (but.rnaprop) { + return RNA_property_ui_name(but.rnaprop); + } + if (but.optype) { + PointerRNA *opptr = UI_but_operator_ptr_get(&but); + return WM_operatortype_name(but.optype, opptr).c_str(); + } + if (ELEM(but.type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { + if (MenuType *mt = UI_but_menutype_get(&but)) { + return CTX_TIP_(mt->translation_context, mt->label); } - si->strinfo = BLI_strdupn(tmp.c_str(), tmp.size()); + if (wmOperatorType *ot = UI_but_operatortype_get_from_enum_menu(&but, nullptr)) { + return WM_operatortype_name(ot, nullptr).c_str(); + } + + if (PanelType *pt = UI_but_paneltype_get(&but)) { + return CTX_TIP_(pt->translation_context, pt->label); + } } - va_end(args); + return {}; +} + +std::string UI_but_string_get_rna_label_context(const uiBut &but) +{ + if (but.rnaprop) { + return RNA_property_translation_context(but.rnaprop); + } + if (but.optype) { + return RNA_struct_translation_context(but.optype->srna); + } + if (ELEM(but.type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { + if (MenuType *mt = UI_but_menutype_get(&but)) { + return RNA_struct_translation_context(mt->rna_ext.srna); + } + } + return BLT_I18NCONTEXT_DEFAULT_BPYRNA; +} + +std::string UI_but_string_get_tooltip(bContext &C, uiBut &but) +{ + if (but.tip_func) { + return but.tip_func(&C, but.tip_arg, but.tip); + } + if (but.tip && but.tip[0]) { + return but.tip; + } + return UI_but_string_get_rna_tooltip(C, but); +} + +std::string UI_but_string_get_rna_tooltip(bContext &C, uiBut &but) +{ + if (but.rnaprop) { + const char *t = RNA_property_ui_description(but.rnaprop); + if (t && t[0]) { + return t; + } + } + else if (but.optype) { + PointerRNA *opptr = UI_but_operator_ptr_get(&but); + const bContextStore *previous_ctx = CTX_store_get(&C); + CTX_store_set(&C, but.context); + std::string tmp = WM_operatortype_description(&C, but.optype, opptr).c_str(); + CTX_store_set(&C, previous_ctx); + return tmp; + } + if (ELEM(but.type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { + if (MenuType *mt = UI_but_menutype_get(&but)) { + /* Not all menus are from Python. */ + if (mt->rna_ext.srna) { + const char *t = RNA_struct_ui_description(mt->rna_ext.srna); + if (t && t[0]) { + return t; + } + } + } + + if (wmOperatorType *ot = UI_but_operatortype_get_from_enum_menu(&but, nullptr)) { + return WM_operatortype_description(&C, ot, nullptr).c_str(); + } + } + + return {}; +} + +std::string UI_but_string_get_operator_keymap(bContext &C, uiBut &but) +{ + char buf[128]; + if (!ui_but_event_operator_string(&C, &but, buf, sizeof(buf))) { + return {}; + } + return buf; +} + +std::string UI_but_string_get_property_keymap(bContext &C, uiBut &but) +{ + char buf[128]; + if (!ui_but_event_property_operator_string(&C, &but, buf, sizeof(buf))) { + return {}; + } + return buf; +} + +std::string UI_but_extra_icon_string_get_label(const uiButExtraOpIcon &extra_icon) +{ + wmOperatorType *optype = UI_but_extra_operator_icon_optype_get(&extra_icon); + PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(&extra_icon); + return WM_operatortype_name(optype, opptr); +} + +std::string UI_but_extra_icon_string_get_tooltip(bContext &C, const uiButExtraOpIcon &extra_icon) +{ + wmOperatorType *optype = UI_but_extra_operator_icon_optype_get(&extra_icon); + PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(&extra_icon); + return WM_operatortype_description(&C, optype, opptr); +} + +std::string UI_but_extra_icon_string_get_operator_keymap(const bContext &C, + const uiButExtraOpIcon &extra_icon) +{ + char buf[128]; + if (!ui_but_extra_icon_event_operator_string(&C, &extra_icon, buf, sizeof(buf))) { + return {}; + } + return buf; } /* Program Init/Exit */ diff --git a/source/blender/editors/interface/interface_context_menu.cc b/source/blender/editors/interface/interface_context_menu.cc index 009c8d9ff72..f4ee2e8e124 100644 --- a/source/blender/editors/interface/interface_context_menu.cc +++ b/source/blender/editors/interface/interface_context_menu.cc @@ -517,16 +517,8 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev uiLayout *layout; const bContextStore *previous_ctx = CTX_store_get(C); { - uiStringInfo label = {BUT_GET_LABEL, nullptr}; - - /* highly unlikely getting the label ever fails */ - UI_but_string_info_get(C, but, &label, nullptr); - - pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE); + pup = UI_popup_menu_begin(C, UI_but_string_get_label(*but).c_str(), ICON_NONE); layout = UI_popup_menu_layout(pup); - if (label.strinfo) { - MEM_freeN(label.strinfo); - } set_layout_context_from_button(C, layout, but); uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index a1b8fb8f01e..3919328fdb2 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -6114,7 +6114,7 @@ wmOperatorType *UI_but_operatortype_get_from_enum_menu(uiBut *but, PropertyRNA * return nullptr; } -MenuType *UI_but_menutype_get(uiBut *but) +MenuType *UI_but_menutype_get(const uiBut *but) { if (but->menu_create_func == ui_item_menutype_func) { return (MenuType *)but->poin; @@ -6122,7 +6122,7 @@ MenuType *UI_but_menutype_get(uiBut *but) return nullptr; } -PanelType *UI_but_paneltype_get(uiBut *but) +PanelType *UI_but_paneltype_get(const uiBut *but) { if (but->menu_create_func == ui_item_paneltype_func) { return (PanelType *)but->poin; diff --git a/source/blender/editors/interface/interface_ops.cc b/source/blender/editors/interface/interface_ops.cc index 3b9f863d80d..cba5ef6fee1 100644 --- a/source/blender/editors/interface/interface_ops.cc +++ b/source/blender/editors/interface/interface_ops.cc @@ -2010,17 +2010,6 @@ static int edittranslation_exec(bContext *C, wmOperator *op) const char *root = U.i18ndir; const char *uilng = BLT_lang_get(); - uiStringInfo but_label = {BUT_GET_LABEL, nullptr}; - uiStringInfo rna_label = {BUT_GET_RNA_LABEL, nullptr}; - uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, nullptr}; - uiStringInfo but_tip = {BUT_GET_TIP, nullptr}; - uiStringInfo rna_tip = {BUT_GET_RNA_TIP, nullptr}; - uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, nullptr}; - uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, nullptr}; - uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, nullptr}; - uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, nullptr}; - uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, nullptr}; - if (!BLI_is_dir(root)) { BKE_report(op->reports, RPT_ERROR, @@ -2046,66 +2035,27 @@ static int edittranslation_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - UI_but_string_info_get(C, - but, - &but_label, - &rna_label, - &enum_label, - &but_tip, - &rna_tip, - &enum_tip, - &rna_struct, - &rna_prop, - &rna_enum, - &rna_ctxt, - nullptr); - WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, "lang", uilng); RNA_string_set(&ptr, "po_file", popath); - RNA_string_set(&ptr, "but_label", but_label.strinfo); - RNA_string_set(&ptr, "rna_label", rna_label.strinfo); - RNA_string_set(&ptr, "enum_label", enum_label.strinfo); - RNA_string_set(&ptr, "but_tip", but_tip.strinfo); - RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo); - RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo); - RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo); - RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo); - RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo); - RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo); - const int ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr); - /* Clean up */ - if (but_label.strinfo) { - MEM_freeN(but_label.strinfo); - } - if (rna_label.strinfo) { - MEM_freeN(rna_label.strinfo); - } - if (enum_label.strinfo) { - MEM_freeN(enum_label.strinfo); - } - if (but_tip.strinfo) { - MEM_freeN(but_tip.strinfo); - } - if (rna_tip.strinfo) { - MEM_freeN(rna_tip.strinfo); - } - if (enum_tip.strinfo) { - MEM_freeN(enum_tip.strinfo); - } - if (rna_struct.strinfo) { - MEM_freeN(rna_struct.strinfo); - } - if (rna_prop.strinfo) { - MEM_freeN(rna_prop.strinfo); - } - if (rna_enum.strinfo) { - MEM_freeN(rna_enum.strinfo); - } - if (rna_ctxt.strinfo) { - MEM_freeN(rna_ctxt.strinfo); - } + const EnumPropertyItem enum_item = UI_but_rna_enum_item_get(*C, *but).value_or( + EnumPropertyItem{}); + RNA_string_set(&ptr, "enum_label", enum_item.name); + RNA_string_set(&ptr, "enum_tip", enum_item.description); + RNA_string_set(&ptr, "rna_enum", enum_item.identifier); + + RNA_string_set(&ptr, "but_label", UI_but_string_get_label(*but).c_str()); + RNA_string_set(&ptr, "rna_label", UI_but_string_get_rna_label(*but).c_str()); + + RNA_string_set(&ptr, "but_tip", UI_but_string_get_tooltip(*C, *but).c_str()); + RNA_string_set(&ptr, "rna_tip", UI_but_string_get_rna_tooltip(*C, *but).c_str()); + + RNA_string_set(&ptr, "rna_struct", UI_but_string_get_rna_struct_identifier(*but).c_str()); + RNA_string_set(&ptr, "rna_prop", UI_but_string_get_rna_property_identifier(*but).c_str()); + RNA_string_set(&ptr, "rna_ctxt", UI_but_string_get_rna_label_context(*but).c_str()); + + const int ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr); return ret; } diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index 31f3927d37c..24f9f61e1b2 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -586,15 +586,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is * * Either way case it's useful to show the shortcut. */ - char *shortcut = nullptr; + std::string shortcut = UI_but_string_get_operator_keymap(*C, *but); - { - uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, nullptr}; - UI_but_string_info_get(C, but, &op_keymap, nullptr); - shortcut = op_keymap.strinfo; - } - - if (shortcut == nullptr) { + if (shortcut.empty()) { const ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); const char *tool_attr = BKE_paint_get_tool_prop_id_from_paintmode(paint_mode); if (tool_attr != nullptr) { @@ -619,14 +613,14 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is shortcut_brush, ARRAY_SIZE(shortcut_brush))) { - shortcut = BLI_strdup(shortcut_brush); + shortcut = shortcut_brush; } WM_operator_properties_free(&op_props); } } } - if (shortcut == nullptr) { + if (shortcut.empty()) { /* Check for direct access to the tool. */ char shortcut_toolbar[128] = ""; if (WM_key_event_operator_string(C, @@ -676,14 +670,13 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is } } - if (shortcut != nullptr) { + if (!shortcut.empty()) { UI_tooltip_text_field_add(data, - BLI_sprintfN(TIP_("Shortcut: %s"), shortcut), + BLI_sprintfN(TIP_("Shortcut: %s"), shortcut.c_str()), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, true); - MEM_freeN(shortcut); } } @@ -826,93 +819,91 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, uiButExtraOpIcon *extra_icon, const bool is_label) { - uiStringInfo but_label = {BUT_GET_LABEL, nullptr}; - uiStringInfo but_tip_label = {BUT_GET_TIP_LABEL, nullptr}; - uiStringInfo but_tip = {BUT_GET_TIP, nullptr}; - uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, nullptr}; - uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, nullptr}; - uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, nullptr}; - uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, nullptr}; - uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, nullptr}; - uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, nullptr}; - char buf[512]; wmOperatorType *optype = extra_icon ? UI_but_extra_operator_icon_optype_get(extra_icon) : but->optype; PropertyRNA *rnaprop = extra_icon ? nullptr : but->rnaprop; - /* create tooltip data */ uiTooltipData *data = MEM_cnew(__func__); /* Menus already show shortcuts, don't show them in the tool-tips. */ - if (ui_block_is_menu(but->block) && !ui_block_is_pie_menu(but->block)) { - op_keymap.type = BUT_GET_NOP; - prop_keymap.type = BUT_GET_NOP; - } + const bool is_menu = ui_block_is_menu(but->block) && !ui_block_is_pie_menu(but->block); + + std::string but_label; + std::string but_tip; + std::string but_tip_label; + std::string op_keymap; + std::string prop_keymap; + std::string rna_struct; + std::string rna_prop; + std::string enum_label; + std::string enum_tip; if (extra_icon) { if (is_label) { - UI_but_extra_icon_string_info_get( - C, extra_icon, &but_tip_label, &but_label, &enum_label, nullptr); + but_label = UI_but_extra_icon_string_get_label(*extra_icon); } else { - UI_but_extra_icon_string_info_get( - C, extra_icon, &but_label, &but_tip_label, &but_tip, &op_keymap, nullptr); + but_label = UI_but_extra_icon_string_get_label(*extra_icon); + but_tip = UI_but_extra_icon_string_get_tooltip(*C, *extra_icon); + if (!is_menu) { + op_keymap = UI_but_extra_icon_string_get_operator_keymap(*C, *extra_icon); + } } } else { + const std::optional enum_item = UI_but_rna_enum_item_get(*C, *but); if (is_label) { - UI_but_string_info_get(C, but, &but_tip_label, &but_label, &enum_label, nullptr); + but_tip_label = UI_but_string_get_tooltip_label(*but); + but_label = UI_but_string_get_label(*but); + enum_label = enum_item ? enum_item->name : ""; } else { - UI_but_string_info_get(C, - but, - &but_label, - &but_tip_label, - &but_tip, - &enum_label, - &enum_tip, - &op_keymap, - &prop_keymap, - &rna_struct, - &rna_prop, - nullptr); + but_label = UI_but_string_get_label(*but); + but_tip_label = UI_but_string_get_tooltip_label(*but); + but_tip = UI_but_string_get_tooltip(*C, *but); + enum_label = enum_item ? enum_item->name : ""; + enum_tip = enum_item ? enum_item->description : ""; + if (!is_menu) { + op_keymap = UI_but_string_get_operator_keymap(*C, *but); + prop_keymap = UI_but_string_get_property_keymap(*C, *but); + } + rna_struct = UI_but_string_get_rna_struct_identifier(*but); + rna_prop = UI_but_string_get_rna_property_identifier(*but); } } /* Label: If there is a custom tooltip label, use that to override the label to display. * Otherwise fallback to the regular label. */ - if (but_tip_label.strinfo) { + if (!but_tip_label.empty()) { UI_tooltip_text_field_add( - data, BLI_strdup(but_tip_label.strinfo), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); + data, BLI_strdup(but_tip_label.c_str()), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); } /* Regular (non-custom) label. Only show when the button doesn't already show the label. Check * prefix instead of comparing because the button may include the shortcut. Buttons with dynamic * tool-tips also don't get their default label here since they can already provide more accurate * and specific tool-tip content. */ - else if (but_label.strinfo && !STRPREFIX(but->drawstr, but_label.strinfo) && !but->tip_func) { + else if (!but_label.empty() && !STRPREFIX(but->drawstr, but_label.c_str()) && !but->tip_func) { UI_tooltip_text_field_add( - data, BLI_strdup(but_label.strinfo), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); + data, BLI_strdup(but_label.c_str()), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); } /* Tip */ - if (but_tip.strinfo) { - { - if (enum_label.strinfo) { - UI_tooltip_text_field_add(data, - BLI_sprintfN("%s: ", but_tip.strinfo), - BLI_strdup(enum_label.strinfo), - UI_TIP_STYLE_HEADER, - UI_TIP_LC_NORMAL); - } - else { - UI_tooltip_text_field_add(data, - BLI_sprintfN("%s.", but_tip.strinfo), - nullptr, - UI_TIP_STYLE_HEADER, - UI_TIP_LC_NORMAL); - } + if (!but_tip.empty()) { + if (!enum_label.empty()) { + UI_tooltip_text_field_add(data, + BLI_sprintfN("%s: ", but_tip.c_str()), + BLI_strdup(enum_label.c_str()), + UI_TIP_STYLE_HEADER, + UI_TIP_LC_NORMAL); + } + else { + UI_tooltip_text_field_add(data, + BLI_sprintfN("%s.", but_tip.c_str()), + nullptr, + UI_TIP_STYLE_HEADER, + UI_TIP_LC_NORMAL); } /* special case enum rna buttons */ @@ -925,21 +916,21 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, } } /* When there is only an enum label (no button label or tip), draw that as header. */ - else if (enum_label.strinfo && !(but_label.strinfo && but_label.strinfo[0])) { + else if (!enum_label.empty() && but_label.empty()) { UI_tooltip_text_field_add( - data, BLI_strdup(enum_label.strinfo), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); + data, BLI_strdup(enum_label.c_str()), nullptr, UI_TIP_STYLE_HEADER, UI_TIP_LC_NORMAL); } /* Enum field label & tip. */ - if (enum_tip.strinfo) { + if (!enum_tip.empty()) { UI_tooltip_text_field_add( - data, BLI_strdup(enum_tip.strinfo), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE); + data, BLI_strdup(enum_tip.c_str()), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE); } /* Operator shortcut. */ - if (op_keymap.strinfo) { + if (!op_keymap.empty()) { UI_tooltip_text_field_add(data, - BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo), + BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.c_str()), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, @@ -947,9 +938,9 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, } /* Property context-toggle shortcut. */ - if (prop_keymap.strinfo) { + if (!prop_keymap.empty()) { UI_tooltip_text_field_add(data, - BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo), + BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.c_str()), nullptr, UI_TIP_STYLE_NORMAL, UI_TIP_LC_VALUE, @@ -1065,13 +1056,13 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, } } - if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && rna_struct.strinfo) { + if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && !rna_struct.empty()) { { UI_tooltip_text_field_add( data, - (rna_prop.strinfo) ? - BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo) : - BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo), + rna_prop.empty() ? + BLI_sprintfN(TIP_("Python: %s"), rna_struct.c_str()) : + BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.c_str(), rna_prop.c_str()), nullptr, UI_TIP_STYLE_MONO, UI_TIP_LC_PYTHON, @@ -1089,35 +1080,6 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, } } - /* Free strinfo's... */ - if (but_label.strinfo) { - MEM_freeN(but_label.strinfo); - } - if (but_tip_label.strinfo) { - MEM_freeN(but_tip_label.strinfo); - } - if (but_tip.strinfo) { - MEM_freeN(but_tip.strinfo); - } - if (enum_label.strinfo) { - MEM_freeN(enum_label.strinfo); - } - if (enum_tip.strinfo) { - MEM_freeN(enum_tip.strinfo); - } - if (op_keymap.strinfo) { - MEM_freeN(op_keymap.strinfo); - } - if (prop_keymap.strinfo) { - MEM_freeN(prop_keymap.strinfo); - } - if (rna_struct.strinfo) { - MEM_freeN(rna_struct.strinfo); - } - if (rna_prop.strinfo) { - MEM_freeN(rna_prop.strinfo); - } - if (data->fields_len == 0) { MEM_freeN(data); return nullptr;