Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_region_search.c
| Show First 20 Lines • Show All 331 Lines • ▼ Show 20 Lines | case MOUSEMOVE: | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* region is the search box itself */ | /* region is the search box itself */ | ||||
| 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; | |||||
| uiSearchboxData *data = region->regiondata; | uiSearchboxData *data = region->regiondata; | ||||
| 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 == false) { | if (reset == false) { | ||||
| 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; | ||||
| /* handle active */ | /* handle active */ | ||||
| if (but->search_func && but->func_arg2) { | if (search_but->item_collect_func && but->func_arg2) { | ||||
| data->items.active = but->func_arg2; | data->items.active = but->func_arg2; | ||||
| but->search_func(C, but->search_arg, but->editstr, &data->items); | search_but->item_collect_func(C, search_but->item_collect_arg, but->editstr, &data->items); | ||||
| data->items.active = NULL; | data->items.active = NULL; | ||||
| /* 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 */ | ||||
| if (data->items.offset_i < data->items.maxitem) { | if (data->items.offset_i < data->items.maxitem) { | ||||
| data->active = data->items.offset_i; | data->active = data->items.offset_i; | ||||
| data->items.offset_i = 0; | data->items.offset_i = 0; | ||||
| Show All 12 Lines | if (search_but->item_collect_func && but->func_arg2) { | ||||
| } | } | ||||
| } | } | ||||
| data->items.offset = data->items.offset_i; | data->items.offset = data->items.offset_i; | ||||
| data->items.totitem = 0; | data->items.totitem = 0; | ||||
| } | } | ||||
| } | } | ||||
| /* callback */ | /* callback */ | ||||
| if (but->search_func) { | if (search_but->item_collect_func) { | ||||
| but->search_func(C, but->search_arg, but->editstr, &data->items); | search_but->item_collect_func(C, search_but->item_collect_arg, but->editstr, &data->items); | ||||
| } | } | ||||
| /* handle case where editstr is equal to one of items */ | /* handle case where editstr is equal to one of items */ | ||||
| if (reset && data->active == -1) { | if (reset && data->active == -1) { | ||||
| int a; | int a; | ||||
| for (a = 0; a < data->items.totitem; a++) { | for (a = 0; a < data->items.totitem; a++) { | ||||
| const char *name = data->items.names[a]; | const char *name = data->items.names[a]; | ||||
| Show All 11 Lines | void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) | ||||
| /* validate selected item */ | /* validate selected item */ | ||||
| ui_searchbox_select(C, region, but, 0); | ui_searchbox_select(C, region, but, 0); | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| } | } | ||||
| int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str) | int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str) | ||||
| { | { | ||||
| uiButSearch *search_but = (uiButSearch *)but; | |||||
| uiSearchboxData *data = region->regiondata; | uiSearchboxData *data = region->regiondata; | ||||
| int match = AUTOCOMPLETE_NO_MATCH; | int match = AUTOCOMPLETE_NO_MATCH; | ||||
| BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); | |||||
| if (str[0]) { | if (str[0]) { | ||||
| data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but)); | 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); | search_but->item_collect_func(C, search_but->item_collect_arg, but->editstr, &data->items); | ||||
| match = UI_autocomplete_end(data->items.autocpl, str); | match = UI_autocomplete_end(data->items.autocpl, str); | ||||
| data->items.autocpl = NULL; | data->items.autocpl = NULL; | ||||
| } | } | ||||
| return match; | return match; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | static void ui_searchbox_region_free_cb(ARegion *region) | ||||
| MEM_freeN(data->items.pointers); | MEM_freeN(data->items.pointers); | ||||
| MEM_freeN(data->items.icons); | MEM_freeN(data->items.icons); | ||||
| MEM_freeN(data->items.states); | MEM_freeN(data->items.states); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| region->regiondata = NULL; | region->regiondata = NULL; | ||||
| } | } | ||||
| ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but) | ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but) | ||||
| { | { | ||||
| 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; | |||||
| static ARegionType type; | static ARegionType type; | ||||
| ARegion *region; | ARegion *region; | ||||
| uiSearchboxData *data; | uiSearchboxData *data; | ||||
| float aspect = but->block->aspect; | float aspect = but->block->aspect; | ||||
| rctf rect_fl; | rctf rect_fl; | ||||
| rcti rect_i; | rcti rect_i; | ||||
| const int margin = UI_POPUP_MARGIN; | const int margin = UI_POPUP_MARGIN; | ||||
| int winx /*, winy */, ofsx, ofsy; | int winx /*, winy */, ofsx, ofsy; | ||||
| Show All 32 Lines | ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but) | ||||
| /* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of | /* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of | ||||
| * buttons are about data without having that pointer defined, let's rather try with optype!). | * buttons are about data without having that pointer defined, let's rather try with optype!). | ||||
| * One can also enforce that behavior by setting | * One can also enforce that behavior by setting | ||||
| * UI_BUT_HAS_SHORTCUT drawflag of search button. */ | * UI_BUT_HAS_SHORTCUT drawflag of search button. */ | ||||
| if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) { | if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) { | ||||
| data->use_sep = true; | data->use_sep = true; | ||||
| } | } | ||||
| data->sep_string = but->search_sep_string; | data->sep_string = search_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 202 Lines • ▼ Show 20 Lines | if (data->items.offset) { | ||||
| ui_searchbox_butrect(&rect, data, 0); | ui_searchbox_butrect(&rect, data, 0); | ||||
| GPU_blend(true); | GPU_blend(true); | ||||
| UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); | UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); | ||||
| GPU_blend(false); | GPU_blend(false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but) | ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but) | ||||
| { | { | ||||
| ARegion *region; | ARegion *region; | ||||
| UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT); | UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); | ||||
| region = ui_searchbox_create_generic(C, butregion, but); | region = ui_searchbox_create_generic(C, butregion, search_but); | ||||
| region->type->draw = ui_searchbox_region_draw_cb__operator; | region->type->draw = ui_searchbox_region_draw_cb__operator; | ||||
| return region; | return region; | ||||
| } | } | ||||
| void ui_searchbox_free(bContext *C, ARegion *region) | void ui_searchbox_free(bContext *C, ARegion *region) | ||||
| { | { | ||||
| ui_region_temp_remove(C, CTX_wm_screen(C), region); | ui_region_temp_remove(C, CTX_wm_screen(C), region); | ||||
| } | } | ||||
| static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion *UNUSED(region)) | static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion *UNUSED(region)) | ||||
| { | { | ||||
| /* Currently unused. */ | /* Currently unused. */ | ||||
| } | } | ||||
| ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but) | ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but) | ||||
| { | { | ||||
| ARegion *region; | ARegion *region; | ||||
| UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT); | UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT); | ||||
| region = ui_searchbox_create_generic(C, butregion, but); | region = ui_searchbox_create_generic(C, butregion, 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; | ||||
| } | } | ||||
| /* sets red alert if button holds a string it can't find */ | /* sets red alert if button holds a string it can't find */ | ||||
| /* XXX weak: search_func adds all partial matches... */ | /* XXX weak: search_func adds all partial matches... */ | ||||
| void ui_but_search_refresh(uiBut *but) | void ui_but_search_refresh(uiButSearch *search_but) | ||||
| { | { | ||||
| uiBut *but = &search_but->but; | |||||
| uiSearchItems *items; | uiSearchItems *items; | ||||
| int x1; | int x1; | ||||
| /* 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; | ||||
| } | } | ||||
| items = MEM_callocN(sizeof(uiSearchItems), "search items"); | items = MEM_callocN(sizeof(uiSearchItems), "search items"); | ||||
| /* setup search struct */ | /* setup search struct */ | ||||
| items->maxitem = 10; | items->maxitem = 10; | ||||
| items->maxstrlen = 256; | items->maxstrlen = 256; | ||||
| items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names"); | items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names"); | ||||
| for (x1 = 0; x1 < items->maxitem; x1++) { | for (x1 = 0; x1 < items->maxitem; x1++) { | ||||
| items->names[x1] = MEM_callocN(but->hardmax + 1, "search names"); | items->names[x1] = MEM_callocN(but->hardmax + 1, "search names"); | ||||
| } | } | ||||
| but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items); | search_but->item_collect_func( | ||||
| but->block->evil_C, search_but->item_collect_arg, but->drawstr, items); | |||||
| /* only redalert when we are sure of it, this can miss cases when >10 matches */ | /* only redalert 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 | |||||