diff options
4 files changed, 146 insertions, 43 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index e8b71a41439..c536eff771d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -82,6 +82,7 @@ struct wmWindow; typedef struct uiBlock uiBlock; typedef struct uiBut uiBut; +typedef struct uiButExtraOpIcon uiButExtraOpIcon; typedef struct uiLayout uiLayout; typedef struct uiPopupBlockHandle uiPopupBlockHandle; /* C handle for C++ #ui::AbstractTreeView type. */ @@ -1432,6 +1433,8 @@ typedef struct uiStringInfo { * Will fill them with translated strings, when possible. * Strings in uiStringInfo must be MEM_freeN'ed by caller. */ void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); +void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *extra_icon, ...) + ATTR_SENTINEL(0); /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ @@ -1724,6 +1727,8 @@ struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, const char *opname, short opcontext, int icon); +struct wmOperatorType *UI_but_extra_operator_icon_optype_get(struct uiButExtraOpIcon *extra_icon); +struct PointerRNA *UI_but_extra_operator_icon_opptr_get(struct uiButExtraOpIcon *extra_icon); /* Autocomplete * @@ -2713,6 +2718,11 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C, struct ARegion *butregion, uiBut *but, bool is_label); +struct ARegion *UI_tooltip_create_from_button_or_extra_icon(struct bContext *C, + struct ARegion *butregion, + uiBut *but, + uiButExtraOpIcon *extra_icon, + bool is_label); struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz); void UI_tooltip_free(struct bContext *C, struct bScreen *screen, struct ARegion *region); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 92391a703ef..68595e49871 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1224,16 +1224,21 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str * \{ */ static bool ui_but_event_operator_string_from_operator(const bContext *C, - uiBut *but, + wmOperatorCallParams *op_call_params, char *buf, const size_t buf_len) { - BLI_assert(but->optype != NULL); + BLI_assert(op_call_params->optype != NULL); bool found = false; - IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; - - if (WM_key_event_operator_string( - C, but->optype->idname, but->opcontext, prop, true, buf, buf_len)) { + IDProperty *prop = (op_call_params->opptr) ? op_call_params->opptr->data : NULL; + + if (WM_key_event_operator_string(C, + op_call_params->optype->idname, + op_call_params->opcontext, + prop, + true, + buf, + buf_len)) { found = true; } return found; @@ -1318,7 +1323,12 @@ static bool ui_but_event_operator_string(const bContext *C, bool found = false; if (but->optype != NULL) { - found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len); + found = ui_but_event_operator_string_from_operator( + C, + &(wmOperatorCallParams){ + .optype = but->optype, .opptr = but->opptr, .opcontext = but->opcontext}, + buf, + buf_len); } else if (UI_but_menutype_get(but) != NULL) { found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len); @@ -1330,6 +1340,20 @@ static bool ui_but_event_operator_string(const bContext *C, return found; } +static bool ui_but_extra_icon_event_operator_string(const bContext *C, + uiButExtraOpIcon *extra_icon, + char *buf, + const size_t buf_len) +{ + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); + + if (extra_icon_optype) { + return ui_but_event_operator_string_from_operator(C, extra_icon->optype_params, buf, buf_len); + } + + return false; +} + static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but, char *buf, @@ -1713,6 +1737,16 @@ PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, return NULL; } +wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon ? extra_icon->optype_params->optype : NULL; +} + +PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon->optype_params->opptr; +} + static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but) { BLI_assert(but->type == UI_BTYPE_TEXT); @@ -7262,6 +7296,42 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } +void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *extra_icon, ...) +{ + va_list args; + uiStringInfo *si; + + wmOperatorType *optype = UI_but_extra_operator_icon_optype_get(extra_icon); + PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(extra_icon); + + va_start(args, extra_icon); + while ((si = (uiStringInfo *)va_arg(args, void *))) { + char *tmp = NULL; + + switch (si->type) { + case BUT_GET_LABEL: + tmp = BLI_strdup(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 = BLI_strdup(buf); + } + } + /* Other types not supported. The caller should expect that outcome, no need to message or + * assert here. */ + default: + break; + } + + si->strinfo = tmp; + } + va_end(args); +} + /* Program Init/Exit */ void UI_init(void) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c508cf2f36c..bf9b37c00fa 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -8235,7 +8235,11 @@ static ARegion *ui_but_tooltip_init( uiBut *but = UI_region_active_but_get(region); *r_exit_on_event = false; if (but) { - return UI_tooltip_create_from_button(C, region, but, is_label); + const wmWindow *win = CTX_wm_window(C); + uiButExtraOpIcon *extra_icon = ui_but_extra_operator_icon_mouse_over_get( + but, but->active, win->eventstate); + + return UI_tooltip_create_from_button_or_extra_icon(C, region, but, extra_icon, is_label); } return NULL; } diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index a8f289702f8..6071e14d153 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -761,7 +761,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is return data; } -static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) +static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, + uiBut *but, + uiButExtraOpIcon *extra_icon) { uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; @@ -774,20 +776,29 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) char buf[512]; + wmOperatorType *optype = extra_icon ? UI_but_extra_operator_icon_optype_get(extra_icon) : + but->optype; + PropertyRNA *rnaprop = extra_icon ? NULL : but->rnaprop; + /* create tooltip data */ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - UI_but_string_info_get(C, - but, - &but_label, - &but_tip, - &enum_label, - &enum_tip, - &op_keymap, - &prop_keymap, - &rna_struct, - &rna_prop, - NULL); + if (extra_icon) { + UI_but_extra_icon_string_info_get(C, extra_icon, &but_label, &but_tip, &op_keymap, NULL); + } + else { + UI_but_string_info_get(C, + but, + &but_label, + &but_tip, + &enum_label, + &enum_tip, + &op_keymap, + &prop_keymap, + &rna_struct, + &rna_prop, + NULL); + } /* Tip Label (only for buttons not already showing the label). * Check prefix instead of comparing because the button may include the shortcut. */ @@ -818,8 +829,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } /* special case enum rna buttons */ - if ((but->type & UI_BTYPE_ROW) && but->rnaprop && - RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) { + if ((but->type & UI_BTYPE_ROW) && rnaprop && RNA_property_flag(rnaprop) & PROP_ENUM_FLAG) { uiTooltipField *field = text_field_add(data, &(uiTooltipFormat){ .style = UI_TIP_STYLE_NORMAL, @@ -863,7 +873,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { /* better not show the value of a password */ - if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) { + if ((rnaprop && (RNA_property_subtype(rnaprop) == PROP_PASSWORD)) == 0) { /* full string */ ui_but_string_get(but, buf, sizeof(buf)); if (buf[0]) { @@ -878,15 +888,14 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } } - if (but->rnaprop) { + if (rnaprop) { const int unit_type = UI_but_unit_type_get(but); if (unit_type == PROP_UNIT_ROTATION) { - if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { - float value = RNA_property_array_check(but->rnaprop) ? - RNA_property_float_get_index( - &but->rnapoin, but->rnaprop, but->rnaindex) : - RNA_property_float_get(&but->rnapoin, but->rnaprop); + if (RNA_property_type(rnaprop) == PROP_FLOAT) { + float value = RNA_property_array_check(rnaprop) ? + RNA_property_float_get_index(&but->rnapoin, rnaprop, but->rnaindex) : + RNA_property_float_get(&but->rnapoin, rnaprop); uiTooltipField *field = text_field_add(data, &(uiTooltipFormat){ @@ -920,15 +929,15 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } } } - else if (but->optype) { - PointerRNA *opptr; - char *str; - opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */ + else if (optype) { + PointerRNA *opptr = extra_icon ? UI_but_extra_operator_icon_opptr_get(extra_icon) : + /* allocated when needed, the button owns it */ + UI_but_operator_ptr_get(but); /* so the context is passed to fieldf functions (some py fieldf functions use it) */ WM_operator_properties_sanitize(opptr, false); - str = ui_tooltip_text_python_from_op(C, but->optype, opptr); + char *str = ui_tooltip_text_python_from_op(C, optype, opptr); /* operator info */ if (U.flag & USER_TOOLTIPS_PYTHON) { @@ -973,7 +982,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } } - if ((U.flag & USER_TOOLTIPS_PYTHON) && !but->optype && rna_struct.strinfo) { + if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && rna_struct.strinfo) { { uiTooltipField *field = text_field_add(data, &(uiTooltipFormat){ @@ -1002,9 +1011,9 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) /* never fails */ /* move ownership (no need for re-alloc) */ - if (but->rnaprop) { + if (rnaprop) { field->text = RNA_path_full_property_py_ex( - CTX_data_main(C), &but->rnapoin, but->rnaprop, but->rnaindex, true); + CTX_data_main(C), &but->rnapoin, rnaprop, but->rnaindex, true); } else { field->text = RNA_path_full_struct_py(CTX_data_main(C), &but->rnapoin); @@ -1394,11 +1403,8 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, /** \name ToolTip Public API * \{ */ -/** - * \param is_label: When true, show a small tip that only shows the name, - * otherwise show the full tooltip. - */ -ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label) +ARegion *UI_tooltip_create_from_button_or_extra_icon( + bContext *C, ARegion *butregion, uiBut *but, uiButExtraOpIcon *extra_icon, bool is_label) { wmWindow *win = CTX_wm_window(C); /* aspect values that shrink text are likely unreadable */ @@ -1415,7 +1421,11 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b } if (data == NULL) { - data = ui_tooltip_data_from_button(C, but); + data = ui_tooltip_data_from_button_or_extra_icon(C, but, extra_icon); + } + + if (data == NULL) { + data = ui_tooltip_data_from_button_or_extra_icon(C, but, NULL); } if (data == NULL) { @@ -1453,6 +1463,15 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b return region; } +/** + * \param is_label: When true, show a small tip that only shows the name, otherwise show the full + * tooltip. + */ +ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label) +{ + return UI_tooltip_create_from_button_or_extra_icon(C, butregion, but, NULL, is_label); +} + ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) { wmWindow *win = CTX_wm_window(C); |