102#define SEARCH_ITEMS 10
109 const uint8_t name_prefix_offset)
123 if (poin == items->
active) {
151 if (name_prefix_offset != 0) {
190 for (const int i : range) {
191 const blender::StringRefNull name = items.names[i];
192 const int icon = items.icons ? items.icons[i] : ICON_NONE;
193 const float text_width = BLF_width(BLF_default(), name.c_str(), name.size(), nullptr);
194 const float icon_with_padding = icon == ICON_NONE ? 0.0f : UI_ICON_SIZE + UI_UNIT_X;
195 const float padding = UI_UNIT_X;
196 item_widths[i] = int(text_width + padding + icon_with_padding);
202 for (
const int width : item_widths) {
203 box_width = std::max(box_width, width);
230 update_fn(
C, arg,
"", &items,
true);
265 if (
data->items.totitem == 0) {
268 else if (
data->active >=
data->items.totitem) {
269 if (
data->items.more) {
270 data->items.offset++;
271 data->active =
data->items.totitem - 1;
275 data->active =
data->items.totitem - 1;
278 else if (
data->active < 0) {
279 if (
data->items.offset) {
280 data->items.offset--;
303 *r_rect =
data->bbox;
306 row = itemnr /
data->prv_cols;
311 r_rect->
ymax -= tria_h + row * buth;
318 *r_rect =
data->bbox;
323 r_rect->
ymax =
data->bbox.ymax - tria_h - itemnr * buth;
350 if (
data->active != -1) {
353 (
data->items.name_prefix_offsets ?
354 data->items.name_prefix_offsets[
data->active] :
377 *r_exit_on_event =
true;
380 for (
const std::unique_ptr<uiBut> &but : block->buttons) {
410 int type =
event->
type, val =
event->val;
411 bool handled =
false;
412 bool tooltip_timer_started =
false;
434 if (
data->active != -1) {
467 for (a = 0; a <
data->items.totitem; a++) {
473 if (
data->active != a) {
485 if (
data->active != -1) {
489 tooltip_timer_started =
true;
498 if (handled && (tooltip_timer_started ==
false)) {
517 const bool is_first_search = !but->
changed;
529 data->items.totitem = 0;
530 data->items.more = 0;
532 data->items.offset_i =
data->items.offset;
535 data->items.offset_i =
data->items.offset = 0;
539 const bool is_first_search = !but->
changed;
543 data->items.active =
nullptr;
546 if (
data->items.totitem) {
548 if (
data->items.offset_i <
data->items.maxitem) {
549 data->active =
data->items.offset_i;
550 data->items.offset_i = 0;
554 if (
data->items.totitem -
data->items.offset_i <=
data->items.maxitem) {
555 data->active =
data->items.offset_i -
data->items.totitem +
data->items.maxitem;
556 data->items.offset_i =
data->items.totitem -
data->items.maxitem;
560 data->items.offset_i -=
data->items.maxitem / 2;
561 data->active =
data->items.maxitem / 2;
565 data->items.offset =
data->items.offset_i;
566 data->items.totitem = 0;
577 for (
int a = 0; a <
data->items.totitem; a++) {
578 const char *
name =
data->items.names[a] +
580 (
data->items.name_prefix_offsets ?
data->items.name_prefix_offsets[a] :
611 maxncpy = strlen(
str) + 1024;
618 data->items.autocpl =
nullptr;
634 const float aspect =
U.inv_scale_factor / zoom;
650 const float aspect =
U.inv_scale_factor / zoom;
663 if (
data->noback ==
false) {
668 if (
data->items.totitem) {
673 for (
int a = 0; a <
data->items.totitem; a++) {
674 const int but_flag = ((a ==
data->active) ?
UI_HOVER : 0) |
data->items.but_flags[a];
685 data->items.names[a],
686 data->items.icons[a],
692 if (
data->items.more ||
data->items.offset) {
693 rcti rect_first_item;
698 if (
data->items.offset) {
700 rect_first_item.
xmax = rect_max_item.
xmax;
704 if (
data->items.more) {
706 rect_max_item.
xmin = rect_first_item.
xmin;
712 const int search_sep_len =
data->sep_string ? strlen(
data->sep_string) : 0;
714 for (
int a = 0; a <
data->items.totitem; a++) {
715 const int but_flag = ((a ==
data->active) ?
UI_HOVER : 0) |
data->items.but_flags[a];
716 const char *
name =
data->items.names[a];
717 int icon =
data->items.icons[a];
718 char *name_sep_test =
nullptr;
721 if (
data->use_shortcut_sep) {
732 if ((search_sep_len == 0) ||
733 !(name_sep_test = strstr(
data->items.names[a],
data->sep_string)))
735 if (!icon &&
data->items.has_icon) {
754 char *name_sep =
nullptr;
756 name_sep = name_sep_test;
757 name_sep_test = strstr(name_sep + search_sep_len,
data->sep_string);
758 }
while (name_sep_test !=
nullptr);
760 name_sep += search_sep_len;
761 const char name_sep_prev = *name_sep;
774 *name_sep = name_sep_prev;
775 rect.
xmin += name_width;
778 if (icon == ICON_BLANK1) {
781 if (icon != ICON_NONE) {
799 if (
data->items.more) {
803 if (
data->items.offset) {
817 IFACE_(
"No results found"),
830 for (
int a = 0; a <
data->items.maxitem; a++) {
838 if (
data->items.name_prefix_offsets !=
nullptr) {
849 if (
data->search_listener) {
858 if (
data->size_set) {
876 const float zoom =
data->zoom;
883 data->bbox.ymin = margin;
888 data->bbox.ymin += search_but_h;
891 data->bbox.ymax -= search_but_h;
910 rect_fl.
xmax = rect_fl.
xmin + searchbox_width;
927 if (rect_i.
xmax > winx) {
929 if (rect_i.
xmax > winx + rect_i.
xmin) {
939 if (rect_i.
ymin < 0) {
953 data->bbox.xmin = margin;
955 data->bbox.ymin = margin;
968 data->size_set =
true;
974 const bool use_shortcut_sep)
994 data->search_but = but;
995 data->butregion = butregion;
996 data->size_set =
false;
998 data->zoom = 1.0f / aspect;
1010 data->noback =
true;
1014 data->preview =
true;
1019 if (but->
optype !=
nullptr || use_shortcut_sep) {
1020 data->use_shortcut_sep =
true;
1031 if (
data->preview) {
1039 data->items.totitem = 0;
1041 data->items.pointers = (
void **)
MEM_callocN(
data->items.maxitem *
sizeof(
void *), __func__);
1044 data->items.name_prefix_offsets =
nullptr;
1045 for (
int i = 0;
i <
data->items.maxitem;
i++) {
1065 bool prev_delim =
true;
1067 for (
size_t i = 0; (
i <
len) &&
str[
i];
i++) {
1068 if (
str[
i] >=
'A' &&
str[
i] <=
'Z') {
1069 if (prev_delim ==
false) {
1070 str[
i] +=
'a' -
'A';
1073 else if (
str[
i] ==
'_') {
1088 if (
data->noback ==
false) {
1093 if (
data->items.totitem) {
1097 for (
int a = 0; a <
data->items.totitem; a++) {
1098 rcti rect_pre, rect_post;
1109 const int but_flag = ((a ==
data->active) ?
UI_HOVER : 0) |
data->items.but_flags[a];
1113 const char *text_pre_p = strstr(
ot->idname,
"_OT_");
1114 if (text_pre_p ==
nullptr) {
1121 text_pre,
ot->idname,
min_ii(
sizeof(text_pre), text_pre_p -
ot->idname));
1122 text_pre[text_pre_len] =
':';
1123 text_pre[text_pre_len + 1] =
'\0';
1133 data->items.icons[a],
1142 data->items.names[a],
1151 if (
data->items.more) {
1155 if (
data->items.offset) {
1168 IFACE_(
"No results found"),
1231 else if (items->
more == 0) {
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
#define LISTBASE_FOREACH(type, var, list)
MINLINE int min_ii(int a, int b)
void BLI_rctf_translate(struct rctf *rect, float x, float y)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
void BLI_rcti_translate(struct rcti *rect, int x, int y)
bool BLI_rcti_isect_pt(const struct rcti *rect, int x, int y)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
char size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STREQLEN(a, b, n)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void ED_region_floating_init(ARegion *region)
void ED_region_tag_redraw(ARegion *region)
void GPU_blend(GPUBlend blend)
Read Guarded memory(de)allocation.
ARegion * UI_region_searchbox_region_get(const ARegion *button_region)
#define AUTOCOMPLETE_NO_MATCH
int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
const uiStyle * UI_style_get()
void UI_fontstyle_set(const uiFontStyle *fs)
#define UI_SEARCHBOX_BOUNDS
void UI_autocomplete_update_name(AutoComplete *autocpl, blender::StringRef name)
void(*)(const bContext *C, void *arg, const char *str, uiSearchItems *items, bool is_first) uiButSearchUpdateFn
AutoComplete * UI_autocomplete_begin(const char *startname, size_t maxncpy)
void UI_but_flag_enable(uiBut *but, int flag)
void(*)(const wmRegionListenerParams *params, void *arg) uiButSearchListenFn
#define UI_SEARCHBOX_TRIA_H
#define UI_NO_ICON_OVERLAY_TEXT
void UI_icon_draw_ex(float x, float y, int icon_id, float aspect, float alpha, float desaturate, const uchar mono_color[4], bool mono_border, const IconTextOverlay *text_overlay, const bool inverted=false)
float UI_view2d_view_to_region_y(const View2D *v2d, float y)
void UI_view2d_view_to_region_rcti(const View2D *v2d, const rctf *rect_src, rcti *rect_dst) ATTR_NONNULL()
BMesh const char void * data
void reset()
clear internal cached data and reset random seed
IndexRange index_range() const
static bool is_inside(int x, int y, int cols, int rows)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
int ui_but_string_get_maxncpy(uiBut *but)
void ui_fontscale(float *points, float aspect)
void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big)
#define UI_POPUP_MENU_TOP
void ui_draw_preview_item(const uiFontStyle *fstyle, rcti *rect, float zoom, const char *name, int iconid, int but_flag, eFontStyle_Align text_align)
void ui_draw_widget_menu_back(const rcti *rect, bool use_shadow)
void ui_draw_menu_item(const uiFontStyle *fstyle, rcti *rect, rcti *back_rect, float zoom, bool use_unpadded, const char *name, int iconid, int but_flag, uiMenuItemSeparatorType separator_type, int *r_xmax)
@ UI_MENU_ITEM_SEPARATOR_NONE
@ UI_MENU_ITEM_SEPARATOR_HINT
@ UI_MENU_ITEM_SEPARATOR_SHORTCUT
static void ui_searchbox_draw_clip_tri_up(rcti *rect, const float zoom)
int ui_searchbox_find_index(ARegion *region, const char *name)
void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset)
static void str_tolower_titlecaps_ascii(char *str, const size_t len)
static ARegion * ui_searchbox_create_generic_ex(bContext *C, ARegion *butregion, uiButSearch *but, const bool use_shortcut_sep)
void ui_but_search_refresh(uiButSearch *but)
static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr)
static void ui_searchbox_select(bContext *C, ARegion *region, uiBut *but, int step)
ARegion * ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but)
ARegion * ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
ARegion * ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
int UI_searchbox_size_x_guess(const bContext *C, const uiButSearchUpdateFn update_fn, void *arg)
void ui_searchbox_free(bContext *C, ARegion *region)
static void ui_searchbox_update_fn(bContext *C, uiButSearch *but, const char *str, uiSearchItems *items)
int UI_searchbox_size_x()
bool ui_searchbox_apply(uiBut *but, ARegion *region)
static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
static int ui_searchbox_size_x_from_items(const uiSearchItems &items)
int UI_search_items_find_index(const uiSearchItems *items, const char *name)
int UI_searchbox_size_y()
static void ui_searchbox_region_draw_cb__menu(const bContext *, ARegion *)
static void ui_searchbox_region_layout_fn(const bContext *C, ARegion *region)
bool ui_searchbox_event(bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event)
static void ui_searchbox_draw_clip_tri_down(rcti *rect, const float zoom)
static ARegion * wm_searchbox_tooltip_init(bContext *C, ARegion *region, int *, double *, bool *r_exit_on_event)
static void ui_searchbox_region_draw_cb__operator(const bContext *, ARegion *region)
static void ui_searchbox_region_free_fn(ARegion *region)
bool ui_searchbox_inside(ARegion *region, const int xy[2])
bool UI_search_item_add(uiSearchItems *items, const StringRef name, void *poin, int iconid, const int but_flag, const uint8_t name_prefix_offset)
int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str)
static void ui_searchbox_region_listen_fn(const wmRegionListenerParams *params)
ARegion * ui_region_temp_add(bScreen *screen)
void ui_region_temp_remove(bContext *C, bScreen *screen, ARegion *region)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
PropertyType RNA_property_type(PropertyRNA *prop)
void(* listener)(const wmRegionListenerParams *params)
void(* draw)(const bContext *C, ARegion *region)
void(* layout)(const bContext *C, ARegion *region)
ARegionRuntimeHandle * runtime
uiButSearchUpdateFn items_update_fn
bool results_are_suggestions
uiButSearchListenFn listen_fn
const char * item_sep_string
uiButSearchTooltipFn item_tooltip_fn
uiButSearchContextMenuFn item_context_menu_fn
uint8_t * name_prefix_offsets
uiButSearchListenFn search_listener
void wmOrtho2_region_pixelspace(const ARegion *region)
int WM_window_native_pixel_x(const wmWindow *win)