diff options
author | Julian Eisel <julian@blender.org> | 2021-01-27 00:06:45 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2021-01-27 00:17:17 +0300 |
commit | d096d9c4d686471b9de2a993b76f5bd9fef9cb78 (patch) | |
tree | f61623f7e2b75d5c59553ab9ed2d4004399701dd /source | |
parent | 656f6ae6436ae10cae4820a5c957041a20d56995 (diff) |
UI: Tooltip for data-block selector menus, showing full name and library info
Long data-block names are clipped to fit into data-block selector menus. For
linked data-blocks, there's also a hint indicating the source library, which
takes further space and may get clipped too.
So this commit adds a tooltip to the menu items, which displays the full,
unclipped data-block name and the unclipped library name. Plus, the library
path is shown too, which is also useful info.
Adds helper functions for search menu item tooltips, so these are easier to add
to other search menus in future.
Part of T84188.
Diffstat (limited to 'source')
6 files changed, 137 insertions, 2 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index dd5c92e5e0f..bc053f60ca3 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -508,6 +508,7 @@ typedef bool (*uiButSearchContextMenuFn)(struct bContext *C, const struct wmEvent *event); typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C, struct ARegion *region, + const struct rcti *item_rect, void *arg, void *active); @@ -2485,6 +2486,7 @@ uiBut *UI_region_but_find_rect_over(const struct ARegion *region, const struct r uiBlock *UI_region_block_find_mouse_over(const struct ARegion *region, const int xy[2], bool only_clip); +struct ARegion *UI_region_searchbox_region_get(const struct ARegion *button_region); /* uiFontStyle.align */ typedef enum eFontStyle_Align { @@ -2564,6 +2566,21 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C, 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); +typedef struct { + /** A description for the item, e.g. what happens when selecting it. */ + char description[UI_MAX_DRAW_STR]; + /* The full name of the item, without prefixes or suffixes (e.g. hint with UI_SEP_CHARP). */ + const char *name; + /** Additional info about the item (e.g. library name of a linked data-block). */ + char hint[UI_MAX_DRAW_STR]; +} uiSearchItemTooltipData; + +struct ARegion *UI_tooltip_create_from_search_item_generic( + struct bContext *C, + const struct ARegion *searchbox_region, + const struct rcti *item_rect, + const uiSearchItemTooltipData *item_tooltip_data); + /* How long before a tool-tip shows. */ #define UI_TOOLTIP_DELAY 0.5 #define UI_TOOLTIP_DELAY_LABEL 0.2 diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index abb9d0dcc13..f9634b8f731 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -8481,6 +8481,15 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C) return NULL; } +/** + * Try to find a search-box region opened from a button in \a button_region. + */ +ARegion *UI_region_searchbox_region_get(const ARegion *button_region) +{ + uiBut *but = UI_region_active_but_get(button_region); + return (but != NULL) ? but->active->searchbox : NULL; +} + /* helper function for insert keyframe, reset to default, etc operators */ void UI_context_update_anim_flag(const bContext *C) { diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index 816162e9aa2..7f51eb90fe8 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -347,9 +347,20 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C, } 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); + if (!search_but->item_tooltip_fn) { + continue; } + + ARegion *searchbox_region = UI_region_searchbox_region_get(region); + uiSearchboxData *data = searchbox_region->regiondata; + + BLI_assert(data->items.pointers[data->active] == search_but->item_active); + + rcti rect; + ui_searchbox_butrect(&rect, data, data->active); + + return search_but->item_tooltip_fn( + C, region, &rect, search_but->arg, search_but->item_active); } } return NULL; diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 91e5b61a16d..050a14cf574 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -1477,6 +1477,74 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect); } +static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data( + const uiSearchItemTooltipData *item_tooltip_data) +{ + uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); + + if (item_tooltip_data->description[0]) { + uiTooltipField *field = text_field_add(data, + &(uiTooltipFormat){ + .style = UI_TIP_STYLE_HEADER, + .color_id = UI_TIP_LC_NORMAL, + .is_pad = true, + }); + field->text = BLI_strdup(item_tooltip_data->description); + } + + if (item_tooltip_data->name && item_tooltip_data->name[0]) { + uiTooltipField *field = text_field_add(data, + &(uiTooltipFormat){ + .style = UI_TIP_STYLE_NORMAL, + .color_id = UI_TIP_LC_VALUE, + .is_pad = true, + }); + field->text = BLI_strdup(item_tooltip_data->name); + } + if (item_tooltip_data->hint[0]) { + uiTooltipField *field = text_field_add(data, + &(uiTooltipFormat){ + .style = UI_TIP_STYLE_NORMAL, + .color_id = UI_TIP_LC_NORMAL, + .is_pad = true, + }); + field->text = BLI_strdup(item_tooltip_data->hint); + } + + if (data->fields_len == 0) { + MEM_freeN(data); + return NULL; + } + return data; +} + +/** + * Create a tooltip from search-item tooltip data \a item_tooltip data. + * To be called from a callback set with #UI_but_func_search_set_tooltip(). + * + * \param item_rect: Rectangle of the search item in search region space (#ui_searchbox_butrect()) + * which is passed to the tooltip callback. + */ +ARegion *UI_tooltip_create_from_search_item_generic( + bContext *C, + const ARegion *searchbox_region, + const rcti *item_rect, + const uiSearchItemTooltipData *item_tooltip_data) +{ + uiTooltipData *data = ui_tooltip_data_from_search_item_tooltip_data(item_tooltip_data); + if (data == NULL) { + return NULL; + } + + const float aspect = 1.0f; + const wmWindow *win = CTX_wm_window(C); + float init_position[2]; + init_position[0] = win->eventstate->x; + init_position[1] = item_rect->ymin + searchbox_region->winrct.ymin - (UI_POPUP_MARGIN / 2); + + return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect); +} + void UI_tooltip_free(bContext *C, bScreen *screen, ARegion *region) { ui_region_temp_remove(C, screen, region); diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 9f4cd32588d..25cf2e12377 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -1069,6 +1069,7 @@ static bool ui_search_menu_create_context_menu(struct bContext *C, static struct ARegion *ui_search_menu_create_tooltip(struct bContext *C, struct ARegion *region, + const rcti *UNUSED(item_rect), void *arg, void *active) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 003bb110baf..8127a32b271 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -208,6 +208,7 @@ static uiBlock *template_common_search_menu(const bContext *C, void *search_arg, uiButHandleFunc search_exec_fn, void *active_item, + uiButSearchTooltipFn item_tooltip_fn, const int preview_rows, const int preview_cols, float scale) @@ -284,6 +285,7 @@ static uiBlock *template_common_search_menu(const bContext *C, NULL, search_exec_fn, active_item); + UI_but_func_search_set_tooltip(but, item_tooltip_fn); UI_block_bounds_set_normal(block, 0.3f * U.widget_unit); UI_block_direction_set(block, UI_DIR_DOWN); @@ -485,6 +487,31 @@ static void id_search_cb_objects_from_scene(const bContext *C, id_search_cb_tagged(C, arg_template, str, items); } +static ARegion *template_ID_search_menu_item_tooltip( + bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active) +{ + TemplateID *template_ui = arg; + ID *active_id = active; + StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop); + + uiSearchItemTooltipData tooltip_data = {0}; + + tooltip_data.name = active_id->name + 2; + BLI_snprintf(tooltip_data.description, + sizeof(tooltip_data.description), + TIP_("Choose %s data-block to be assigned to this user"), + RNA_struct_ui_name(type)); + if (ID_IS_LINKED(active_id)) { + BLI_snprintf(tooltip_data.hint, + sizeof(tooltip_data.hint), + TIP_("Source library: %s\n%s"), + active_id->lib->id.name + 2, + active_id->lib->filepath); + } + + return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data); +} + /* ID Search browse menu, open */ static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem) { @@ -512,6 +539,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem) &template_ui, template_ID_set_property_exec_fn, active_item_ptr.data, + template_ID_search_menu_item_tooltip, template_ui.prv_rows, template_ui.prv_cols, template_ui.scale); @@ -1632,6 +1660,7 @@ static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_tem &template_search, template_search_exec_fn, active_ptr.data, + NULL, template_search.preview_rows, template_search.preview_cols, 1.0f); |