diff options
Diffstat (limited to 'source/blender/editors/interface/interface_region_search.c')
-rw-r--r-- | source/blender/editors/interface/interface_region_search.c | 97 |
1 files changed, 87 insertions, 10 deletions
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index e2c87891169..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" @@ -153,7 +154,8 @@ bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int /* Limit flags that can be set so flags such as 'UI_SELECT' aren't accidentally set * which will cause problems, add others as needed. */ - BLI_assert((state & ~(UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT)) == 0); + BLI_assert( + (state & ~(UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT | UI_BUT_HAS_SEP_CHAR)) == 0); if (items->states) { items->states[items->totitem] = state; } @@ -295,10 +297,31 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region) } } -void 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); @@ -308,12 +331,36 @@ void ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, const wmEvent case WHEELUPMOUSE: case EVT_UPARROWKEY: ui_searchbox_select(C, region, but, -1); + handled = true; break; case WHEELDOWNMOUSE: case EVT_DOWNARROWKEY: ui_searchbox_select(C, region, but, 1); + handled = true; break; - case MOUSEMOVE: + case RIGHTMOUSE: + if (val) { + if (but->search->context_menu_fn) { + if (data->active != -1) { + /* Check the cursor is over the active element + * (a little confusing if this isn't the case, although it does work). */ + rcti rect; + ui_searchbox_butrect(&rect, data, data->active); + if (BLI_rcti_isect_pt( + &rect, event->x - region->winrct.xmin, event->y - region->winrct.ymin)) { + + void *active = data->items.pointers[data->active]; + if (but->search->context_menu_fn(C, but->search->arg, active, event)) { + handled = true; + } + } + } + } + } + break; + case MOUSEMOVE: { + bool is_inside = false; + if (BLI_rcti_isect_pt(®ion->winrct, event->x, event->y)) { rcti rect; int a; @@ -322,16 +369,46 @@ void 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); + handled = true; break; } } } } + + 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 */ @@ -350,9 +427,9 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re data->active = -1; /* handle active */ - if (but->search_func && but->func_arg2) { + if (but->search->update_fn && but->func_arg2) { data->items.active = but->func_arg2; - but->search_func(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 */ @@ -381,8 +458,8 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re } /* callback */ - if (but->search_func) { - but->search_func(C, but->search_arg, but->editstr, &data->items); + if (but->search->update_fn) { + ui_searchbox_update_fn(C, but, but->editstr, &data->items); } /* handle case where editstr is equal to one of items */ @@ -416,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_func(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; @@ -603,7 +680,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) { data->use_sep = true; } - data->sep_string = but->search_sep_string; + data->sep_string = but->search->sep_string; /* compute position */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { @@ -881,7 +958,7 @@ void ui_but_search_refresh(uiBut *but) items->names[x1] = MEM_callocN(but->hardmax + 1, "search names"); } - but->search_func(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) { |