46#define MENU_BORDER int(0.3f * U.widget_unit)
98#define SEARCH_ITEMS 10
105 const uint8_t name_prefix_offset)
119 if (poin == items->
active) {
147 if (name_prefix_offset != 0) {
182 for (
int i = 0; i < items->
totitem; i++) {
189 for (
int i = 0; i < items->
totitem; i++) {
206 if (data->items.totitem == 0) {
209 else if (data->active >= data->items.totitem) {
210 if (data->items.more) {
211 data->items.offset++;
212 data->active = data->items.totitem - 1;
216 data->active = data->items.totitem - 1;
219 else if (data->active < 0) {
220 if (data->items.offset) {
221 data->items.offset--;
242 *r_rect = data->bbox;
244 col = itemnr % data->prv_cols;
245 row = itemnr / data->prv_cols;
257 *r_rect = data->bbox;
258 r_rect->
xmin = data->bbox.xmin + 3.0f;
259 r_rect->
xmax = data->bbox.xmax - 3.0f;
288 if (data->active != -1) {
289 const char *name = data->items.names[data->active] +
291 (data->items.name_prefix_offsets ?
292 data->items.name_prefix_offsets[data->active] :
295 const char *name_sep = data->use_shortcut_sep ? strrchr(name,
UI_SEP_CHAR) :
nullptr;
300 BLI_strncpy(but->
editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
303 search_but->
item_active = data->items.pointers[data->active];
313 bContext *C,
ARegion *region,
int * ,
double * ,
bool *r_exit_on_event)
315 *r_exit_on_event =
true;
348 int type =
event->
type, val =
event->val;
349 bool handled =
false;
350 bool tooltip_timer_started =
false;
372 if (data->active != -1) {
378 &rect, event->
xy[0] - region->winrct.xmin, event->
xy[1] - region->winrct.ymin))
381 void *active = data->items.pointers[data->active];
397 for (a = 0; a < data->items.totitem; a++) {
400 &rect, event->
xy[0] - region->winrct.xmin, event->
xy[1] - region->winrct.ymin))
403 if (data->active != a) {
415 if (data->active != -1) {
417 search_but->
item_active = data->items.pointers[data->active];
419 tooltip_timer_started =
true;
428 if (handled && (tooltip_timer_started ==
false)) {
447 const bool is_first_search = !but->
changed;
459 data->items.totitem = 0;
460 data->items.more = 0;
462 data->items.offset_i = data->items.offset;
465 data->items.offset_i = data->items.offset = 0;
469 const bool is_first_search = !but->
changed;
473 data->items.active =
nullptr;
476 if (data->items.totitem) {
478 if (data->items.offset_i < data->items.maxitem) {
479 data->active = data->items.offset_i;
480 data->items.offset_i = 0;
484 if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
485 data->active = data->items.offset_i - data->items.totitem + data->items.maxitem;
486 data->items.offset_i = data->items.totitem - data->items.maxitem;
490 data->items.offset_i -= data->items.maxitem / 2;
491 data->active = data->items.maxitem / 2;
495 data->items.offset = data->items.offset_i;
496 data->items.totitem = 0;
506 if (
reset && data->active == -1) {
507 for (
int a = 0; a < data->items.totitem; a++) {
508 const char *name = data->items.names[a] +
510 (data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
512 const char *name_sep = data->use_shortcut_sep ? strrchr(name,
UI_SEP_CHAR) :
nullptr;
513 if (
STREQLEN(but->
editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
518 if (data->items.totitem == 1 && but->
editstr[0]) {
543 data->items.autocpl =
nullptr;
556 if (data->noback ==
false) {
561 if (data->items.totitem) {
566 for (
int a = 0; a < data->items.totitem; a++) {
567 const int but_flag = ((a == data->active) ?
UI_HOVER : 0) | data->items.but_flags[a];
577 data->items.names[a],
578 data->items.icons[a],
584 if (data->items.more) {
590 if (data->items.offset) {
598 const int search_sep_len = data->sep_string ? strlen(data->sep_string) : 0;
600 for (
int a = 0; a < data->items.totitem; a++) {
601 const int but_flag = ((a == data->active) ?
UI_HOVER : 0) | data->items.but_flags[a];
602 const char *name = data->items.names[a];
603 int icon = data->items.icons[a];
604 char *name_sep_test =
nullptr;
607 if (data->use_shortcut_sep) {
618 if ((search_sep_len == 0) ||
619 !(name_sep_test = strstr(data->items.names[a], data->sep_string)))
621 if (!icon && data->items.has_icon) {
627 ui_draw_menu_item(&data->fstyle, &rect, name, icon, but_flag, separator_type,
nullptr);
631 char *name_sep =
nullptr;
633 name_sep = name_sep_test;
634 name_sep_test = strstr(name_sep + search_sep_len, data->sep_string);
635 }
while (name_sep_test !=
nullptr);
637 name_sep += search_sep_len;
638 const char name_sep_prev = *name_sep;
648 *name_sep = name_sep_prev;
649 rect.
xmin += name_width;
652 if (icon == ICON_BLANK1) {
659 &data->fstyle, &rect, name_sep, icon, but_flag, separator_type,
nullptr);
663 if (data->items.more) {
669 if (data->items.offset) {
682 IFACE_(
"No results found"),
695 for (
int a = 0; a < data->items.maxitem; a++) {
703 if (data->items.name_prefix_offsets !=
nullptr) {
704 MEM_freeN(data->items.name_prefix_offsets);
708 region->regiondata =
nullptr;
714 if (data->search_listener) {
725 for (
int a = 0; a < data->items.totitem; a++) {
732 return separator_type;
739 if (data->size_set) {
745 ARegion *butregion = data->butregion;
755 region->winrct = butregion->
winrct;
758 data->bbox.
xmin = margin;
760 data->bbox.ymin = margin;
765 data->bbox.ymin += search_but_h;
768 data->bbox.ymax -= search_but_h;
776 searchbox_width += 12 * data->fstyle.points *
UI_SCALE_FAC;
792 rect_fl.
xmax = rect_fl.
xmin + searchbox_width;
809 if (rect_i.
xmax > winx) {
811 if (rect_i.
xmax > winx + rect_i.
xmin) {
821 if (rect_i.
ymin < 0) {
835 data->bbox.xmin = margin;
837 data->bbox.ymin = margin;
841 region->winrct.xmin = rect_i.
xmin - margin;
842 region->winrct.xmax = rect_i.
xmax + margin;
843 region->winrct.ymin = rect_i.
ymin - margin;
844 region->winrct.ymax = rect_i.
ymax;
847 region->winx = region->winrct.xmax - region->winrct.xmin + 1;
848 region->winy = region->winrct.ymax - region->winrct.ymin + 1;
850 data->size_set =
true;
856 const bool use_shortcut_sep)
871 region->type = &type;
875 data->search_arg = but->
arg;
876 data->search_but = but;
877 data->butregion = butregion;
878 data->size_set =
false;
882 data->fstyle = style->
widget;
886 region->regiondata =
data;
895 data->preview =
true;
900 if (but->
optype !=
nullptr || use_shortcut_sep) {
901 data->use_shortcut_sep =
true;
913 data->items.maxitem = data->prv_rows * data->prv_cols;
920 data->items.totitem = 0;
921 data->items.names = (
char **)
MEM_callocN(data->items.maxitem *
sizeof(
void *), __func__);
922 data->items.pointers = (
void **)
MEM_callocN(data->items.maxitem *
sizeof(
void *), __func__);
923 data->items.icons = (
int *)
MEM_callocN(data->items.maxitem *
sizeof(
int), __func__);
924 data->items.but_flags = (
int *)
MEM_callocN(data->items.maxitem *
sizeof(
int), __func__);
925 data->items.name_prefix_offsets =
nullptr;
926 for (
int i = 0; i < data->items.maxitem; i++) {
927 data->items.names[i] = (
char *)
MEM_callocN(data->items.maxstrlen + 1, __func__);
946 bool prev_delim =
true;
948 for (
size_t i = 0; (i <
len) &&
str[i]; i++) {
949 if (
str[i] >=
'A' &&
str[i] <=
'Z') {
950 if (prev_delim ==
false) {
954 else if (
str[i] ==
'_') {
958 prev_delim =
ELEM(
str[i],
' ') || (
str[i] >=
'0' &&
str[i] <=
'9');
969 if (data->noback ==
false) {
974 if (data->items.totitem) {
978 for (
int a = 0; a < data->items.totitem; a++) {
979 rcti rect_pre, rect_post;
990 const int but_flag = ((a == data->active) ?
UI_HOVER : 0) | data->items.but_flags[a];
994 const char *text_pre_p = strstr(
ot->
idname,
"_OT_");
995 if (text_pre_p ==
nullptr) {
1003 text_pre[text_pre_len] =
':';
1004 text_pre[text_pre_len + 1] =
'\0';
1012 data->items.icons[a],
1018 data->items.names[a],
1027 if (data->items.more) {
1033 if (data->items.offset) {
1045 IFACE_(
"No results found"),
1097 for (
int i = 0; i < items->
maxitem; i++) {
1108 else if (items->
more == 0) {
1115 for (
int i = 0; i < items->
maxitem; i++) {
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)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char char size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STREQLEN(a, b, n)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
ID and Library types, which are fundamental for SDNA.
void ED_region_floating_init(ARegion *region)
void ED_region_tag_redraw(ARegion *region)
void GPU_blend(eGPUBlend 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)
AutoComplete * UI_autocomplete_begin(const char *startname, size_t maxncpy)
void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
void UI_but_flag_enable(uiBut *but, int flag)
void(*)(const wmRegionListenerParams *params, void *arg) uiButSearchListenFn
void UI_icon_draw(float x, float y, int icon_id)
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()
void reset()
clear internal cached data and reset random seed
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static bool is_inside(int x, int y, int cols, int rows)
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_widget_menu_back(const rcti *rect, bool use_shadow)
void ui_draw_preview_item(const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int but_flag, eFontStyle_Align text_align)
void ui_draw_menu_item(const uiFontStyle *fstyle, rcti *rect, 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
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, const int but_flag, const uint8_t name_prefix_offset)
int ui_searchbox_find_index(ARegion *region, const char *name)
static uiMenuItemSeparatorType ui_searchbox_item_separator(uiSearchboxData *data)
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)
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)
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 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])
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_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
PropertyType RNA_property_type(PropertyRNA *prop)
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)