diff options
6 files changed, 131 insertions, 10 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 4aca3b41381..8c591a2d0d4 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -516,6 +516,10 @@ typedef bool (*uiButSearchContextMenuFn)(struct bContext *C, void *arg, void *active, const struct wmEvent *event); +typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C, + struct ARegion *region, + void *arg, + void *active); /* Must return allocated string. */ typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip); @@ -1584,6 +1588,7 @@ void UI_but_func_search_set(uiBut *but, uiButHandleFunc search_exec_fn, void *active); void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn); +void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn); void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string); /* height in pixels, it's using hardcoded values still */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 18df67be545..04c259ab092 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -6431,6 +6431,12 @@ void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string search->sep_string = search_sep_string; } +void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn) +{ + struct uiButSearchData *search = but->search; + search->tooltip_fn = tooltip_fn; +} + /* Callbacks for operator search button. */ static void operator_enum_search_update_fn(const struct bContext *C, void *but, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 7020446e9a6..8acfc9e915c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3462,7 +3462,7 @@ static void ui_do_but_textedit( /* pass */ } else { - ui_searchbox_event(C, data->searchbox, but, event); + ui_searchbox_event(C, data->searchbox, but, data->region, event); } #else ui_searchbox_event(C, data->searchbox, but, event); @@ -3476,7 +3476,7 @@ static void ui_do_but_textedit( /* Support search context menu. */ if (event->type == RIGHTMOUSE) { if (data->searchbox) { - if (ui_searchbox_event(C, data->searchbox, but, event)) { + if (ui_searchbox_event(C, data->searchbox, but, data->region, event)) { /* Only break if the event was handled. */ break; } @@ -3591,7 +3591,7 @@ static void ui_do_but_textedit( #ifdef USE_KEYNAV_LIMIT ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event); #endif - ui_searchbox_event(C, data->searchbox, but, event); + ui_searchbox_event(C, data->searchbox, but, data->region, event); break; } if (event->type == WHEELDOWNMOUSE) { @@ -3608,7 +3608,7 @@ static void ui_do_but_textedit( #ifdef USE_KEYNAV_LIMIT ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event); #endif - ui_searchbox_event(C, data->searchbox, but, event); + ui_searchbox_event(C, data->searchbox, but, data->region, event); break; } if (event->type == WHEELUPMOUSE) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index b69d8fb7245..26e8447a0b6 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -151,6 +151,7 @@ struct uiButSearchData { void *arg; uiButSearchArgFreeFn arg_free_fn; uiButSearchContextMenuFn context_menu_fn; + uiButSearchTooltipFn tooltip_fn; const char *sep_string; }; @@ -663,6 +664,7 @@ int ui_searchbox_autocomplete(struct bContext *C, struct ARegion *region, uiBut bool ui_searchbox_event(struct bContext *C, struct ARegion *region, uiBut *but, + struct ARegion *butregion, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *region); void ui_searchbox_free(struct bContext *C, struct ARegion *region); diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index cefb584eed4..0007f6ab9a2 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -35,6 +35,7 @@ #include "BLI_math.h" +#include "BLI_listbase.h" #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -296,11 +297,31 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region) } } -bool ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, const wmEvent *event) +static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C, + struct ARegion *region, + int *UNUSED(r_pass), + double *UNUSED(pass_delay), + bool *r_exit_on_event) +{ + *r_exit_on_event = true; + + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { + if (but->search && but->search->tooltip_fn) { + return but->search->tooltip_fn(C, region, but->search->arg, but->func_arg2); + } + } + } + return NULL; +} + +bool ui_searchbox_event( + bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event) { uiSearchboxData *data = region->regiondata; int type = event->type, val = event->val; bool handled = false; + bool tooltip_timer_started = false; if (type == MOUSEPAN) { ui_pan_to_scroll(event, &type, &val); @@ -337,7 +358,9 @@ bool ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, const wmEvent } } break; - case MOUSEMOVE: + case MOUSEMOVE: { + bool is_inside = false; + if (BLI_rcti_isect_pt(®ion->winrct, event->x, event->y)) { rcti rect; int a; @@ -346,6 +369,7 @@ bool ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, const wmEvent ui_searchbox_butrect(&rect, data, a); if (BLI_rcti_isect_pt( &rect, event->x - region->winrct.xmin, event->y - region->winrct.ymin)) { + is_inside = true; if (data->active != a) { data->active = a; ui_searchbox_select(C, region, but, 0); @@ -355,11 +379,38 @@ bool ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, const wmEvent } } } + + if (U.flag & USER_TOOLTIPS) { + if (is_inside) { + if (data->active != -1) { + ScrArea *area = CTX_wm_area(C); + but->func_arg2 = data->items.pointers[data->active]; + WM_tooltip_timer_init(C, CTX_wm_window(C), area, butregion, wm_searchbox_tooltip_init); + tooltip_timer_started = true; + } + } + } + break; + } + } + + if (handled && (tooltip_timer_started == false)) { + wmWindow *win = CTX_wm_window(C); + WM_tooltip_clear(C, win); } + return handled; } +/** Wrap #uiButSearchUpdateFn callback. */ +static void ui_searchbox_update_fn(bContext *C, uiBut *but, const char *str, uiSearchItems *items) +{ + wmWindow *win = CTX_wm_window(C); + WM_tooltip_clear(C, win); + but->search->update_fn(C, but->search->arg, str, items); +} + /* region is the search box itself */ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) { @@ -378,7 +429,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re /* handle active */ if (but->search->update_fn && but->func_arg2) { data->items.active = but->func_arg2; - but->search->update_fn(C, but->search->arg, but->editstr, &data->items); + ui_searchbox_update_fn(C, but, but->editstr, &data->items); data->items.active = NULL; /* found active item, calculate real offset by centering it */ @@ -408,7 +459,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re /* callback */ if (but->search->update_fn) { - but->search->update_fn(C, but->search->arg, but->editstr, &data->items); + ui_searchbox_update_fn(C, but, but->editstr, &data->items); } /* handle case where editstr is equal to one of items */ @@ -442,7 +493,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *st if (str[0]) { data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but)); - but->search->update_fn(C, but->search->arg, but->editstr, &data->items); + ui_searchbox_update_fn(C, but, but->editstr, &data->items); match = UI_autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; @@ -907,7 +958,7 @@ void ui_but_search_refresh(uiBut *but) items->names[x1] = MEM_callocN(but->hardmax + 1, "search names"); } - but->search->update_fn(but->block->evil_C, but->search->arg, but->drawstr, items); + ui_searchbox_update_fn(but->block->evil_C, but, but->drawstr, items); /* only redalert when we are sure of it, this can miss cases when >10 matches */ if (items->totitem == 0) { diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 9d7f813d204..d34a9552622 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -38,6 +38,7 @@ #include "BLI_ghash.h" #include "BLI_linklist.h" #include "BLI_listbase.h" +#include "BLI_math_matrix.h" #include "BLI_memarena.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -996,6 +997,61 @@ static bool ui_search_menu_create_context_menu(struct bContext *C, /** \} */ /* -------------------------------------------------------------------- */ +/** \name Tooltip + * \{ */ + +static struct ARegion *ui_search_menu_create_tooltip(struct bContext *C, + struct ARegion *region, + void *arg, + void *active) +{ + struct MenuSearch_Data *data = arg; + struct MenuSearch_Item *item = active; + + memset(&data->context_menu_data, 0x0, sizeof(data->context_menu_data)); + uiBut *but = &data->context_menu_data.but; + uiBlock *block = &data->context_menu_data.block; + unit_m4(block->winmat); + block->aspect = 1; + + but->block = block; + + /* Place the fake button at the cursor so the tool-tip is places properly. */ + float tip_init[2]; + const wmEvent *event = CTX_wm_window(C)->eventstate; + tip_init[0] = event->x; + tip_init[1] = event->y - (UI_UNIT_Y / 2); + ui_window_to_block_fl(region, block, &tip_init[0], &tip_init[1]); + + but->rect.xmin = tip_init[0]; + but->rect.xmax = tip_init[0]; + but->rect.ymin = tip_init[1]; + but->rect.ymax = tip_init[1]; + + if (menu_items_to_ui_button(item, but)) { + ScrArea *area_prev = CTX_wm_area(C); + ARegion *region_prev = CTX_wm_region(C); + + if (item->wm_context != NULL) { + CTX_wm_area_set(C, item->wm_context->area); + CTX_wm_region_set(C, item->wm_context->region); + } + + ARegion *region_tip = UI_tooltip_create_from_button(C, region, but, false); + + if (item->wm_context != NULL) { + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, region_prev); + } + return region_tip; + } + + return NULL; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Menu Search Template Public API * \{ */ @@ -1019,6 +1075,7 @@ void UI_but_func_menu_search(uiBut *but) NULL); UI_but_func_search_set_context_menu(but, ui_search_menu_create_context_menu); + UI_but_func_search_set_tooltip(but, ui_search_menu_create_tooltip); UI_but_func_search_set_sep_string(but, MENU_SEP); } |