Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_region_search.cc
| Show First 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | if (handled && (tooltip_timer_started == false)) { | ||||
| WM_tooltip_clear(C, win); | WM_tooltip_clear(C, win); | ||||
| } | } | ||||
| return handled; | return handled; | ||||
| } | } | ||||
| /** Wrap #uiButSearchUpdateFn callback. */ | /** Wrap #uiButSearchUpdateFn callback. */ | ||||
| static void ui_searchbox_update_fn(bContext *C, | static void ui_searchbox_update_fn(bContext *C, | ||||
| uiButSearch *search_but, | uiButSearch *but, | ||||
| const char *str, | const char *str, | ||||
| uiSearchItems *items) | uiSearchItems *items) | ||||
| { | { | ||||
| /* While the button is in text editing mode (searchbox open), remove tooltips on every update. */ | /* While the button is in text editing mode (searchbox open), remove tooltips on every update. */ | ||||
| if (search_but->but.editstr) { | if (but->editstr) { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| WM_tooltip_clear(C, win); | WM_tooltip_clear(C, win); | ||||
| } | } | ||||
| const bool is_first_search = !search_but->but.changed; | const bool is_first_search = !but->changed; | ||||
| search_but->items_update_fn(C, search_but->arg, str, items, is_first_search); | but->items_update_fn(C, but->arg, str, items, is_first_search); | ||||
| } | } | ||||
| void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) | void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) | ||||
| { | { | ||||
| uiButSearch *search_but = (uiButSearch *)but; | uiButSearch *search_but = (uiButSearch *)but; | ||||
| uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); | uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); | ||||
| BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); | BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); | ||||
| /* reset vars */ | /* reset vars */ | ||||
| data->items.totitem = 0; | data->items.totitem = 0; | ||||
| data->items.more = 0; | data->items.more = 0; | ||||
| if (!reset) { | if (!reset) { | ||||
| data->items.offset_i = data->items.offset; | data->items.offset_i = data->items.offset; | ||||
| } | } | ||||
| else { | else { | ||||
| data->items.offset_i = data->items.offset = 0; | data->items.offset_i = data->items.offset = 0; | ||||
| data->active = -1; | data->active = -1; | ||||
| /* On init, find and center active item. */ | /* On init, find and center active item. */ | ||||
| const bool is_first_search = !search_but->but.changed; | const bool is_first_search = !but->changed; | ||||
| if (is_first_search && search_but->items_update_fn && search_but->item_active) { | if (is_first_search && search_but->items_update_fn && search_but->item_active) { | ||||
| data->items.active = search_but->item_active; | data->items.active = search_but->item_active; | ||||
| ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); | ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); | ||||
| data->items.active = nullptr; | data->items.active = nullptr; | ||||
| /* found active item, calculate real offset by centering it */ | /* found active item, calculate real offset by centering it */ | ||||
| if (data->items.totitem) { | if (data->items.totitem) { | ||||
| /* first case, begin of list */ | /* first case, begin of list */ | ||||
| ▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | static void ui_searchbox_region_listen_fn(const wmRegionListenerParams *params) | ||||
| uiSearchboxData *data = static_cast<uiSearchboxData *>(params->region->regiondata); | uiSearchboxData *data = static_cast<uiSearchboxData *>(params->region->regiondata); | ||||
| if (data->search_listener) { | if (data->search_listener) { | ||||
| data->search_listener(params, data->search_arg); | data->search_listener(params, data->search_arg); | ||||
| } | } | ||||
| } | } | ||||
| static ARegion *ui_searchbox_create_generic_ex(bContext *C, | static ARegion *ui_searchbox_create_generic_ex(bContext *C, | ||||
| ARegion *butregion, | ARegion *butregion, | ||||
| uiButSearch *search_but, | uiButSearch *but, | ||||
| const bool use_shortcut_sep) | const bool use_shortcut_sep) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| const uiStyle *style = UI_style_get(); | const uiStyle *style = UI_style_get(); | ||||
| uiBut *but = &search_but->but; | |||||
| const float aspect = but->block->aspect; | const float aspect = but->block->aspect; | ||||
| const int margin = UI_POPUP_MARGIN; | const int margin = UI_POPUP_MARGIN; | ||||
| /* create area region */ | /* create area region */ | ||||
| ARegion *region = ui_region_temp_add(CTX_wm_screen(C)); | ARegion *region = ui_region_temp_add(CTX_wm_screen(C)); | ||||
| static ARegionType type; | static ARegionType type; | ||||
| memset(&type, 0, sizeof(ARegionType)); | memset(&type, 0, sizeof(ARegionType)); | ||||
| type.draw = ui_searchbox_region_draw_fn; | type.draw = ui_searchbox_region_draw_fn; | ||||
| type.free = ui_searchbox_region_free_fn; | type.free = ui_searchbox_region_free_fn; | ||||
| type.listener = ui_searchbox_region_listen_fn; | type.listener = ui_searchbox_region_listen_fn; | ||||
| type.regionid = RGN_TYPE_TEMPORARY; | type.regionid = RGN_TYPE_TEMPORARY; | ||||
| region->type = &type; | region->type = &type; | ||||
| /* Create search-box data. */ | /* Create search-box data. */ | ||||
| uiSearchboxData *data = MEM_cnew<uiSearchboxData>(__func__); | uiSearchboxData *data = MEM_cnew<uiSearchboxData>(__func__); | ||||
| data->search_arg = search_but->arg; | data->search_arg = but->arg; | ||||
| data->search_listener = search_but->listen_fn; | data->search_listener = but->listen_fn; | ||||
| /* Set font, get the bounding-box. */ | /* Set font, get the bounding-box. */ | ||||
| data->fstyle = style->widget; /* copy struct */ | data->fstyle = style->widget; /* copy struct */ | ||||
| ui_fontscale(&data->fstyle.points, aspect); | ui_fontscale(&data->fstyle.points, aspect); | ||||
| UI_fontstyle_set(&data->fstyle); | UI_fontstyle_set(&data->fstyle); | ||||
| region->regiondata = data; | region->regiondata = data; | ||||
| /* Special case, hard-coded feature, not draw backdrop when called from menus, | /* Special case, hard-coded feature, not draw backdrop when called from menus, | ||||
| * assume for design that popup already added it. */ | * assume for design that popup already added it. */ | ||||
| if (but->block->flag & UI_BLOCK_SEARCH_MENU) { | if (but->block->flag & UI_BLOCK_SEARCH_MENU) { | ||||
| data->noback = true; | data->noback = true; | ||||
| } | } | ||||
| if (but->a1 > 0 && but->a2 > 0) { | if (but->a1 > 0 && but->a2 > 0) { | ||||
| data->preview = true; | data->preview = true; | ||||
| data->prv_rows = but->a1; | data->prv_rows = but->a1; | ||||
| data->prv_cols = but->a2; | data->prv_cols = but->a2; | ||||
| } | } | ||||
| if (but->optype != nullptr || use_shortcut_sep) { | if (but->optype != nullptr || use_shortcut_sep) { | ||||
| data->use_shortcut_sep = true; | data->use_shortcut_sep = true; | ||||
| } | } | ||||
| data->sep_string = search_but->item_sep_string; | data->sep_string = but->item_sep_string; | ||||
| /* compute position */ | /* compute position */ | ||||
| if (but->block->flag & UI_BLOCK_SEARCH_MENU) { | if (but->block->flag & UI_BLOCK_SEARCH_MENU) { | ||||
| const int search_but_h = BLI_rctf_size_y(&but->rect) + 10; | const int search_but_h = BLI_rctf_size_y(&but->rect) + 10; | ||||
| /* this case is search menu inside other menu */ | /* this case is search menu inside other menu */ | ||||
| /* we copy region size */ | /* we copy region size */ | ||||
| region->winrct = butregion->winrct; | region->winrct = butregion->winrct; | ||||
| ▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but) | ||||
| if (false) { | if (false) { | ||||
| region->type->draw = ui_searchbox_region_draw_cb__menu; | region->type->draw = ui_searchbox_region_draw_cb__menu; | ||||
| } | } | ||||
| return region; | return region; | ||||
| } | } | ||||
| void ui_but_search_refresh(uiButSearch *search_but) | void ui_but_search_refresh(uiButSearch *but) | ||||
| { | { | ||||
| uiBut *but = &search_but->but; | |||||
| /* possibly very large lists (such as ID datablocks) only | /* possibly very large lists (such as ID datablocks) only | ||||
| * only validate string RNA buts (not pointers) */ | * only validate string RNA buts (not pointers) */ | ||||
| if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) { | if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) { | ||||
| return; | return; | ||||
| } | } | ||||
| uiSearchItems *items = MEM_cnew<uiSearchItems>(__func__); | uiSearchItems *items = MEM_cnew<uiSearchItems>(__func__); | ||||
| /* setup search struct */ | /* setup search struct */ | ||||
| items->maxitem = 10; | items->maxitem = 10; | ||||
| items->maxstrlen = 256; | items->maxstrlen = 256; | ||||
| items->names = (char **)MEM_callocN(items->maxitem * sizeof(void *), __func__); | items->names = (char **)MEM_callocN(items->maxitem * sizeof(void *), __func__); | ||||
| for (int i = 0; i < items->maxitem; i++) { | for (int i = 0; i < items->maxitem; i++) { | ||||
| items->names[i] = (char *)MEM_callocN(but->hardmax + 1, __func__); | items->names[i] = (char *)MEM_callocN(but->hardmax + 1, __func__); | ||||
| } | } | ||||
| ui_searchbox_update_fn((bContext *)but->block->evil_C, search_but, but->drawstr, items); | ui_searchbox_update_fn((bContext *)but->block->evil_C, but, but->drawstr, items); | ||||
| if (!search_but->results_are_suggestions) { | if (!but->results_are_suggestions) { | ||||
| /* Only red-alert when we are sure of it, this can miss cases when >10 matches. */ | /* Only red-alert when we are sure of it, this can miss cases when >10 matches. */ | ||||
| if (items->totitem == 0) { | if (items->totitem == 0) { | ||||
| UI_but_flag_enable(but, UI_BUT_REDALERT); | UI_but_flag_enable(but, UI_BUT_REDALERT); | ||||
| } | } | ||||
| else if (items->more == 0) { | else if (items->more == 0) { | ||||
| if (UI_search_items_find_index(items, but->drawstr) == -1) { | if (UI_search_items_find_index(items, but->drawstr) == -1) { | ||||
| UI_but_flag_enable(but, UI_BUT_REDALERT); | UI_but_flag_enable(but, UI_BUT_REDALERT); | ||||
| } | } | ||||
| Show All 11 Lines | |||||