Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface_region_search.c')
-rw-r--r--source/blender/editors/interface/interface_region_search.c1275
1 files changed, 639 insertions, 636 deletions
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 9aebf1183e0..c37775febda 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -46,7 +46,6 @@
#include "RNA_access.h"
-
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
@@ -59,606 +58,608 @@
#include "interface_regions_intern.h"
#include "GPU_state.h"
-#define MENU_BORDER (int)(0.3f * U.widget_unit)
+#define MENU_BORDER (int)(0.3f * U.widget_unit)
/* -------------------------------------------------------------------- */
/** \name Search Box Creation
* \{ */
struct uiSearchItems {
- int maxitem, totitem, maxstrlen;
+ int maxitem, totitem, maxstrlen;
- int offset, offset_i; /* offset for inserting in array */
- int more; /* flag indicating there are more items */
+ int offset, offset_i; /* offset for inserting in array */
+ int more; /* flag indicating there are more items */
- char **names;
- void **pointers;
- int *icons;
+ char **names;
+ void **pointers;
+ int *icons;
- AutoComplete *autocpl;
- void *active;
+ AutoComplete *autocpl;
+ void *active;
};
typedef struct uiSearchboxData {
- rcti bbox;
- uiFontStyle fstyle;
- uiSearchItems items;
- /** index in items array */
- int active;
- /** when menu opened with enough space for this */
- bool noback;
- /** draw thumbnail previews, rather than list */
- bool preview;
- /** use the UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data) */
- bool use_sep;
- int prv_rows, prv_cols;
+ rcti bbox;
+ uiFontStyle fstyle;
+ uiSearchItems items;
+ /** index in items array */
+ int active;
+ /** when menu opened with enough space for this */
+ bool noback;
+ /** draw thumbnail previews, rather than list */
+ bool preview;
+ /** use the UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data) */
+ bool use_sep;
+ int prv_rows, prv_cols;
} uiSearchboxData;
-#define SEARCH_ITEMS 10
+#define SEARCH_ITEMS 10
/* exported for use by search callbacks */
/* returns zero if nothing to add */
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid)
{
- /* hijack for autocomplete */
- if (items->autocpl) {
- UI_autocomplete_update_name(items->autocpl, name);
- return true;
- }
-
- /* hijack for finding active item */
- if (items->active) {
- if (poin == items->active) {
- items->offset_i = items->totitem;
- }
- items->totitem++;
- return true;
- }
-
- if (items->totitem >= items->maxitem) {
- items->more = 1;
- return false;
- }
-
- /* skip first items in list */
- if (items->offset_i > 0) {
- items->offset_i--;
- return true;
- }
-
- if (items->names) {
- BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
- }
- if (items->pointers) {
- items->pointers[items->totitem] = poin;
- }
- if (items->icons) {
- items->icons[items->totitem] = iconid;
- }
-
- items->totitem++;
-
- return true;
+ /* hijack for autocomplete */
+ if (items->autocpl) {
+ UI_autocomplete_update_name(items->autocpl, name);
+ return true;
+ }
+
+ /* hijack for finding active item */
+ if (items->active) {
+ if (poin == items->active) {
+ items->offset_i = items->totitem;
+ }
+ items->totitem++;
+ return true;
+ }
+
+ if (items->totitem >= items->maxitem) {
+ items->more = 1;
+ return false;
+ }
+
+ /* skip first items in list */
+ if (items->offset_i > 0) {
+ items->offset_i--;
+ return true;
+ }
+
+ if (items->names) {
+ BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
+ }
+ if (items->pointers) {
+ items->pointers[items->totitem] = poin;
+ }
+ if (items->icons) {
+ items->icons[items->totitem] = iconid;
+ }
+
+ items->totitem++;
+
+ return true;
}
int UI_searchbox_size_y(void)
{
- return SEARCH_ITEMS * UI_UNIT_Y + 2 * UI_POPUP_MENU_TOP;
+ return SEARCH_ITEMS * UI_UNIT_Y + 2 * UI_POPUP_MENU_TOP;
}
int UI_searchbox_size_x(void)
{
- return 12 * UI_UNIT_X;
+ return 12 * UI_UNIT_X;
}
int UI_search_items_find_index(uiSearchItems *items, const char *name)
{
- int i;
- for (i = 0; i < items->totitem; i++) {
- if (STREQ(name, items->names[i])) {
- return i;
- }
- }
- return -1;
+ int i;
+ for (i = 0; i < items->totitem; i++) {
+ if (STREQ(name, items->names[i])) {
+ return i;
+ }
+ }
+ return -1;
}
/* ar is the search box itself */
static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* apply step */
- data->active += step;
-
- if (data->items.totitem == 0) {
- data->active = -1;
- }
- else if (data->active >= data->items.totitem) {
- if (data->items.more) {
- data->items.offset++;
- data->active = data->items.totitem - 1;
- ui_searchbox_update(C, ar, but, false);
- }
- else {
- data->active = data->items.totitem - 1;
- }
- }
- else if (data->active < 0) {
- if (data->items.offset) {
- data->items.offset--;
- data->active = 0;
- ui_searchbox_update(C, ar, but, false);
- }
- else {
- /* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
- }
- }
-
- ED_region_tag_redraw(ar);
+ uiSearchboxData *data = ar->regiondata;
+
+ /* apply step */
+ data->active += step;
+
+ if (data->items.totitem == 0) {
+ data->active = -1;
+ }
+ else if (data->active >= data->items.totitem) {
+ if (data->items.more) {
+ data->items.offset++;
+ data->active = data->items.totitem - 1;
+ ui_searchbox_update(C, ar, but, false);
+ }
+ else {
+ data->active = data->items.totitem - 1;
+ }
+ }
+ else if (data->active < 0) {
+ if (data->items.offset) {
+ data->items.offset--;
+ data->active = 0;
+ ui_searchbox_update(C, ar, but, false);
+ }
+ else {
+ /* only let users step into an 'unset' state for unlink buttons */
+ data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
+ }
+ }
+
+ ED_region_tag_redraw(ar);
}
static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr)
{
- /* thumbnail preview */
- if (data->preview) {
- int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols;
- int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows;
- int row, col;
-
- *r_rect = data->bbox;
-
- col = itemnr % data->prv_cols;
- row = itemnr / data->prv_cols;
-
- r_rect->xmin += MENU_BORDER + (col * butw);
- r_rect->xmax = r_rect->xmin + butw;
-
- r_rect->ymax -= MENU_BORDER + (row * buth);
- r_rect->ymin = r_rect->ymax - buth;
- }
- /* list view */
- else {
- int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS;
-
- *r_rect = data->bbox;
- r_rect->xmin = data->bbox.xmin + 3.0f;
- r_rect->xmax = data->bbox.xmax - 3.0f;
-
- r_rect->ymax = data->bbox.ymax - UI_POPUP_MENU_TOP - itemnr * buth;
- r_rect->ymin = r_rect->ymax - buth;
- }
-
+ /* thumbnail preview */
+ if (data->preview) {
+ int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols;
+ int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows;
+ int row, col;
+
+ *r_rect = data->bbox;
+
+ col = itemnr % data->prv_cols;
+ row = itemnr / data->prv_cols;
+
+ r_rect->xmin += MENU_BORDER + (col * butw);
+ r_rect->xmax = r_rect->xmin + butw;
+
+ r_rect->ymax -= MENU_BORDER + (row * buth);
+ r_rect->ymin = r_rect->ymax - buth;
+ }
+ /* list view */
+ else {
+ int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS;
+
+ *r_rect = data->bbox;
+ r_rect->xmin = data->bbox.xmin + 3.0f;
+ r_rect->xmax = data->bbox.xmax - 3.0f;
+
+ r_rect->ymax = data->bbox.ymax - UI_POPUP_MENU_TOP - itemnr * buth;
+ r_rect->ymin = r_rect->ymax - buth;
+ }
}
int ui_searchbox_find_index(ARegion *ar, const char *name)
{
- uiSearchboxData *data = ar->regiondata;
- return UI_search_items_find_index(&data->items, name);
+ uiSearchboxData *data = ar->regiondata;
+ return UI_search_items_find_index(&data->items, name);
}
/* x and y in screencoords */
bool ui_searchbox_inside(ARegion *ar, int x, int y)
{
- uiSearchboxData *data = ar->regiondata;
+ uiSearchboxData *data = ar->regiondata;
- return BLI_rcti_isect_pt(&data->bbox, x - ar->winrct.xmin, y - ar->winrct.ymin);
+ return BLI_rcti_isect_pt(&data->bbox, x - ar->winrct.xmin, y - ar->winrct.ymin);
}
/* string validated to be of correct length (but->hardmax) */
bool ui_searchbox_apply(uiBut *but, ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
+ uiSearchboxData *data = ar->regiondata;
- but->func_arg2 = NULL;
+ but->func_arg2 = NULL;
- if (data->active != -1) {
- const char *name = data->items.names[data->active];
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ if (data->active != -1) {
+ const char *name = data->items.names[data->active];
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
- BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
+ BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
- but->func_arg2 = data->items.pointers[data->active];
+ but->func_arg2 = data->items.pointers[data->active];
- return true;
- }
- else if (but->flag & UI_BUT_VALUE_CLEAR) {
- /* It is valid for _VALUE_CLEAR flavor to have no active element
- * (it's a valid way to unlink). */
- but->editstr[0] = '\0';
+ return true;
+ }
+ else if (but->flag & UI_BUT_VALUE_CLEAR) {
+ /* It is valid for _VALUE_CLEAR flavor to have no active element
+ * (it's a valid way to unlink). */
+ but->editstr[0] = '\0';
- return true;
- }
- else {
- return false;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *event)
{
- uiSearchboxData *data = ar->regiondata;
- int type = event->type, val = event->val;
-
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- }
-
- switch (type) {
- case WHEELUPMOUSE:
- case UPARROWKEY:
- ui_searchbox_select(C, ar, but, -1);
- break;
- case WHEELDOWNMOUSE:
- case DOWNARROWKEY:
- ui_searchbox_select(C, ar, but, 1);
- break;
- case MOUSEMOVE:
- if (BLI_rcti_isect_pt(&ar->winrct, event->x, event->y)) {
- rcti rect;
- int a;
-
- for (a = 0; a < data->items.totitem; a++) {
- ui_searchbox_butrect(&rect, data, a);
- if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
- if (data->active != a) {
- data->active = a;
- ui_searchbox_select(C, ar, but, 0);
- break;
- }
- }
- }
- }
- break;
- }
+ uiSearchboxData *data = ar->regiondata;
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
+ switch (type) {
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ ui_searchbox_select(C, ar, but, -1);
+ break;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ ui_searchbox_select(C, ar, but, 1);
+ break;
+ case MOUSEMOVE:
+ if (BLI_rcti_isect_pt(&ar->winrct, event->x, event->y)) {
+ rcti rect;
+ int a;
+
+ for (a = 0; a < data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
+ if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
+ if (data->active != a) {
+ data->active = a;
+ ui_searchbox_select(C, ar, but, 0);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
}
/* ar is the search box itself */
void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* reset vars */
- data->items.totitem = 0;
- data->items.more = 0;
- if (reset == false) {
- data->items.offset_i = data->items.offset;
- }
- else {
- data->items.offset_i = data->items.offset = 0;
- data->active = -1;
-
- /* handle active */
- if (but->search_func && but->func_arg2) {
- data->items.active = but->func_arg2;
- but->search_func(C, but->search_arg, but->editstr, &data->items);
- data->items.active = NULL;
-
- /* found active item, calculate real offset by centering it */
- if (data->items.totitem) {
- /* first case, begin of list */
- if (data->items.offset_i < data->items.maxitem) {
- data->active = data->items.offset_i;
- data->items.offset_i = 0;
- }
- else {
- /* second case, end of list */
- if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
- data->active = data->items.offset_i - data->items.totitem + data->items.maxitem;
- data->items.offset_i = data->items.totitem - data->items.maxitem;
- }
- else {
- /* center active item */
- data->items.offset_i -= data->items.maxitem / 2;
- data->active = data->items.maxitem / 2;
- }
- }
- }
- data->items.offset = data->items.offset_i;
- data->items.totitem = 0;
- }
- }
-
- /* callback */
- if (but->search_func) {
- but->search_func(C, but->search_arg, but->editstr, &data->items);
- }
-
- /* handle case where editstr is equal to one of items */
- if (reset && data->active == -1) {
- int a;
-
- for (a = 0; a < data->items.totitem; a++) {
- const char *name = data->items.names[a];
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
- if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
- data->active = a;
- break;
- }
- }
- if (data->items.totitem == 1 && but->editstr[0]) {
- data->active = 0;
- }
- }
-
- /* validate selected item */
- ui_searchbox_select(C, ar, but, 0);
-
- ED_region_tag_redraw(ar);
+ uiSearchboxData *data = ar->regiondata;
+
+ /* reset vars */
+ data->items.totitem = 0;
+ data->items.more = 0;
+ if (reset == false) {
+ data->items.offset_i = data->items.offset;
+ }
+ else {
+ data->items.offset_i = data->items.offset = 0;
+ data->active = -1;
+
+ /* handle active */
+ if (but->search_func && but->func_arg2) {
+ data->items.active = but->func_arg2;
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
+ data->items.active = NULL;
+
+ /* found active item, calculate real offset by centering it */
+ if (data->items.totitem) {
+ /* first case, begin of list */
+ if (data->items.offset_i < data->items.maxitem) {
+ data->active = data->items.offset_i;
+ data->items.offset_i = 0;
+ }
+ else {
+ /* second case, end of list */
+ if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
+ data->active = data->items.offset_i - data->items.totitem + data->items.maxitem;
+ data->items.offset_i = data->items.totitem - data->items.maxitem;
+ }
+ else {
+ /* center active item */
+ data->items.offset_i -= data->items.maxitem / 2;
+ data->active = data->items.maxitem / 2;
+ }
+ }
+ }
+ data->items.offset = data->items.offset_i;
+ data->items.totitem = 0;
+ }
+ }
+
+ /* callback */
+ if (but->search_func) {
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
+ }
+
+ /* handle case where editstr is equal to one of items */
+ if (reset && data->active == -1) {
+ int a;
+
+ for (a = 0; a < data->items.totitem; a++) {
+ const char *name = data->items.names[a];
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
+ data->active = a;
+ break;
+ }
+ }
+ if (data->items.totitem == 1 && but->editstr[0]) {
+ data->active = 0;
+ }
+ }
+
+ /* validate selected item */
+ ui_searchbox_select(C, ar, but, 0);
+
+ ED_region_tag_redraw(ar);
}
int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
{
- uiSearchboxData *data = ar->regiondata;
- int match = AUTOCOMPLETE_NO_MATCH;
+ uiSearchboxData *data = ar->regiondata;
+ int match = AUTOCOMPLETE_NO_MATCH;
- if (str[0]) {
- data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
+ 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);
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
- match = UI_autocomplete_end(data->items.autocpl, str);
- data->items.autocpl = NULL;
- }
+ match = UI_autocomplete_end(data->items.autocpl, str);
+ data->items.autocpl = NULL;
+ }
- return match;
+ return match;
}
static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* pixel space */
- wmOrtho2_region_pixelspace(ar);
-
- if (data->noback == false) {
- ui_draw_widget_menu_back(&data->bbox, true);
- }
-
- /* draw text */
- if (data->items.totitem) {
- rcti rect;
- int a;
-
- if (data->preview) {
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- /* ensure icon is up-to-date */
- ui_icon_ensure_deferred(C, data->items.icons[a], data->preview);
-
- ui_searchbox_butrect(&rect, data, a);
-
- /* widget itself */
- ui_draw_preview_item(
- &data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0);
- }
-
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
- GPU_blend(false);
- }
-
- }
- else {
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- ui_searchbox_butrect(&rect, data, a);
-
- /* widget itself */
- ui_draw_menu_item(
- &data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0, data->use_sep);
-
- }
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
- }
- }
- }
+ uiSearchboxData *data = ar->regiondata;
+
+ /* pixel space */
+ wmOrtho2_region_pixelspace(ar);
+
+ if (data->noback == false) {
+ ui_draw_widget_menu_back(&data->bbox, true);
+ }
+
+ /* draw text */
+ if (data->items.totitem) {
+ rcti rect;
+ int a;
+
+ if (data->preview) {
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ /* ensure icon is up-to-date */
+ ui_icon_ensure_deferred(C, data->items.icons[a], data->preview);
+
+ ui_searchbox_butrect(&rect, data, a);
+
+ /* widget itself */
+ ui_draw_preview_item(&data->fstyle,
+ &rect,
+ data->items.names[a],
+ data->items.icons[a],
+ (a == data->active) ? UI_ACTIVE : 0);
+ }
+
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
+ else {
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
+
+ /* widget itself */
+ ui_draw_menu_item(&data->fstyle,
+ &rect,
+ data->items.names[a],
+ data->items.icons[a],
+ (a == data->active) ? UI_ACTIVE : 0,
+ data->use_sep);
+ }
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
+ }
}
static void ui_searchbox_region_free_cb(ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
- int a;
-
- /* free search data */
- for (a = 0; a < data->items.maxitem; a++) {
- MEM_freeN(data->items.names[a]);
- }
- MEM_freeN(data->items.names);
- MEM_freeN(data->items.pointers);
- MEM_freeN(data->items.icons);
-
- MEM_freeN(data);
- ar->regiondata = NULL;
+ uiSearchboxData *data = ar->regiondata;
+ int a;
+
+ /* free search data */
+ for (a = 0; a < data->items.maxitem; a++) {
+ MEM_freeN(data->items.names[a]);
+ }
+ MEM_freeN(data->items.names);
+ MEM_freeN(data->items.pointers);
+ MEM_freeN(data->items.icons);
+
+ MEM_freeN(data);
+ ar->regiondata = NULL;
}
ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but)
{
- wmWindow *win = CTX_wm_window(C);
- uiStyle *style = UI_style_get();
- static ARegionType type;
- ARegion *ar;
- uiSearchboxData *data;
- float aspect = but->block->aspect;
- rctf rect_fl;
- rcti rect_i;
- const int margin = UI_POPUP_MARGIN;
- int winx /*, winy */, ofsx, ofsy;
- int i;
-
- /* create area region */
- ar = ui_region_temp_add(CTX_wm_screen(C));
-
- memset(&type, 0, sizeof(ARegionType));
- type.draw = ui_searchbox_region_draw_cb;
- type.free = ui_searchbox_region_free_cb;
- type.regionid = RGN_TYPE_TEMPORARY;
- ar->type = &type;
-
- /* create searchbox data */
- data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
-
- /* set font, get bb */
- data->fstyle = style->widget; /* copy struct */
- ui_fontscale(&data->fstyle.points, aspect);
- UI_fontstyle_set(&data->fstyle);
-
- ar->regiondata = data;
-
- /* special case, hardcoded feature, not draw backdrop when called from menus,
- * assume for design that popup already added it */
- if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- data->noback = true;
- }
-
- if (but->a1 > 0 && but->a2 > 0) {
- data->preview = true;
- data->prv_rows = but->a1;
- data->prv_cols = but->a2;
- }
-
- /* 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!). One can also enforce that behavior by
- * setting UI_BUT_HAS_SHORTCUT drawflag of search button. */
- if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
- data->use_sep = true;
- }
-
- /* compute position */
- if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- const int search_but_h = BLI_rctf_size_y(&but->rect) + 10;
- /* this case is search menu inside other menu */
- /* we copy region size */
-
- ar->winrct = butregion->winrct;
-
- /* widget rect, in region coords */
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
- data->bbox.ymin = margin;
- data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - margin;
-
- /* check if button is lower half */
- if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
- data->bbox.ymin += search_but_h;
- }
- else {
- data->bbox.ymax -= search_but_h;
- }
- }
- else {
- const int searchbox_width = UI_searchbox_size_x();
-
- rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
- rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
- rect_fl.ymax = but->rect.ymin;
- rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y();
-
- ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
- ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
-
- BLI_rctf_translate(&rect_fl, ofsx, ofsy);
-
- /* minimal width */
- if (BLI_rctf_size_x(&rect_fl) < searchbox_width) {
- rect_fl.xmax = rect_fl.xmin + searchbox_width;
- }
-
- /* copy to int, gets projected if possible too */
- BLI_rcti_rctf_copy(&rect_i, &rect_fl);
-
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- UI_view2d_view_to_region_rcti(&butregion->v2d, &rect_fl, &rect_i);
- }
-
- BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
-
- winx = WM_window_pixels_x(win);
- // winy = WM_window_pixels_y(win); /* UNUSED */
- //wm_window_get_size(win, &winx, &winy);
-
- if (rect_i.xmax > winx) {
- /* super size */
- if (rect_i.xmax > winx + rect_i.xmin) {
- rect_i.xmax = winx;
- rect_i.xmin = 0;
- }
- else {
- rect_i.xmin -= rect_i.xmax - winx;
- rect_i.xmax = winx;
- }
- }
-
- if (rect_i.ymin < 0) {
- int newy1 = but->rect.ymax + ofsy;
-
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- newy1 = UI_view2d_view_to_region_y(&butregion->v2d, newy1);
- }
-
- newy1 += butregion->winrct.ymin;
-
- rect_i.ymax = BLI_rcti_size_y(&rect_i) + newy1;
- rect_i.ymin = newy1;
- }
-
- /* widget rect, in region coords */
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin;
- data->bbox.ymin = margin;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin;
-
- /* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - margin;
- ar->winrct.xmax = rect_i.xmax + margin;
- ar->winrct.ymin = rect_i.ymin - margin;
- ar->winrct.ymax = rect_i.ymax;
- }
-
- /* adds subwindow */
- ED_region_init(ar);
-
- /* notify change and redraw */
- ED_region_tag_redraw(ar);
-
- /* prepare search data */
- if (data->preview) {
- data->items.maxitem = data->prv_rows * data->prv_cols;
- }
- else {
- data->items.maxitem = SEARCH_ITEMS;
- }
- data->items.maxstrlen = but->hardmax;
- data->items.totitem = 0;
- data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
- data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
- data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
- for (i = 0; i < data->items.maxitem; i++) {
- data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
- }
-
- return ar;
+ wmWindow *win = CTX_wm_window(C);
+ uiStyle *style = UI_style_get();
+ static ARegionType type;
+ ARegion *ar;
+ uiSearchboxData *data;
+ float aspect = but->block->aspect;
+ rctf rect_fl;
+ rcti rect_i;
+ const int margin = UI_POPUP_MARGIN;
+ int winx /*, winy */, ofsx, ofsy;
+ int i;
+
+ /* create area region */
+ ar = ui_region_temp_add(CTX_wm_screen(C));
+
+ memset(&type, 0, sizeof(ARegionType));
+ type.draw = ui_searchbox_region_draw_cb;
+ type.free = ui_searchbox_region_free_cb;
+ type.regionid = RGN_TYPE_TEMPORARY;
+ ar->type = &type;
+
+ /* create searchbox data */
+ data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
+
+ /* set font, get bb */
+ data->fstyle = style->widget; /* copy struct */
+ ui_fontscale(&data->fstyle.points, aspect);
+ UI_fontstyle_set(&data->fstyle);
+
+ ar->regiondata = data;
+
+ /* special case, hardcoded feature, not draw backdrop when called from menus,
+ * assume for design that popup already added it */
+ if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ data->noback = true;
+ }
+
+ if (but->a1 > 0 && but->a2 > 0) {
+ data->preview = true;
+ data->prv_rows = but->a1;
+ data->prv_cols = but->a2;
+ }
+
+ /* 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!). One can also enforce that behavior by
+ * setting UI_BUT_HAS_SHORTCUT drawflag of search button. */
+ if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
+ data->use_sep = true;
+ }
+
+ /* compute position */
+ if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ const int search_but_h = BLI_rctf_size_y(&but->rect) + 10;
+ /* this case is search menu inside other menu */
+ /* we copy region size */
+
+ ar->winrct = butregion->winrct;
+
+ /* widget rect, in region coords */
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - margin;
+
+ /* check if button is lower half */
+ if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
+ data->bbox.ymin += search_but_h;
+ }
+ else {
+ data->bbox.ymax -= search_but_h;
+ }
+ }
+ else {
+ const int searchbox_width = UI_searchbox_size_x();
+
+ rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
+ rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
+ rect_fl.ymax = but->rect.ymin;
+ rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y();
+
+ ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
+ ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
+
+ BLI_rctf_translate(&rect_fl, ofsx, ofsy);
+
+ /* minimal width */
+ if (BLI_rctf_size_x(&rect_fl) < searchbox_width) {
+ rect_fl.xmax = rect_fl.xmin + searchbox_width;
+ }
+
+ /* copy to int, gets projected if possible too */
+ BLI_rcti_rctf_copy(&rect_i, &rect_fl);
+
+ if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
+ UI_view2d_view_to_region_rcti(&butregion->v2d, &rect_fl, &rect_i);
+ }
+
+ BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
+
+ winx = WM_window_pixels_x(win);
+ // winy = WM_window_pixels_y(win); /* UNUSED */
+ //wm_window_get_size(win, &winx, &winy);
+
+ if (rect_i.xmax > winx) {
+ /* super size */
+ if (rect_i.xmax > winx + rect_i.xmin) {
+ rect_i.xmax = winx;
+ rect_i.xmin = 0;
+ }
+ else {
+ rect_i.xmin -= rect_i.xmax - winx;
+ rect_i.xmax = winx;
+ }
+ }
+
+ if (rect_i.ymin < 0) {
+ int newy1 = but->rect.ymax + ofsy;
+
+ if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
+ newy1 = UI_view2d_view_to_region_y(&butregion->v2d, newy1);
+ }
+
+ newy1 += butregion->winrct.ymin;
+
+ rect_i.ymax = BLI_rcti_size_y(&rect_i) + newy1;
+ rect_i.ymin = newy1;
+ }
+
+ /* widget rect, in region coords */
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin;
+
+ /* region bigger for shadow */
+ ar->winrct.xmin = rect_i.xmin - margin;
+ ar->winrct.xmax = rect_i.xmax + margin;
+ ar->winrct.ymin = rect_i.ymin - margin;
+ ar->winrct.ymax = rect_i.ymax;
+ }
+
+ /* adds subwindow */
+ ED_region_init(ar);
+
+ /* notify change and redraw */
+ ED_region_tag_redraw(ar);
+
+ /* prepare search data */
+ if (data->preview) {
+ data->items.maxitem = data->prv_rows * data->prv_cols;
+ }
+ else {
+ data->items.maxitem = SEARCH_ITEMS;
+ }
+ data->items.maxstrlen = but->hardmax;
+ data->items.totitem = 0;
+ data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
+ data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
+ data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
+ for (i = 0; i < data->items.maxitem; i++) {
+ data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
+ }
+
+ return ar;
}
/**
@@ -669,152 +670,154 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
*/
static void str_tolower_titlecaps_ascii(char *str, const size_t len)
{
- size_t i;
- bool prev_delim = true;
-
- for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'A' && str[i] <= 'Z') {
- if (prev_delim == false) {
- str[i] += 'a' - 'A';
- }
- }
- else if (str[i] == '_') {
- str[i] = ' ';
- }
-
- prev_delim = ELEM(str[i], ' ') || (str[i] >= '0' && str[i] <= '9');
- }
-
+ size_t i;
+ bool prev_delim = true;
+
+ for (i = 0; (i < len) && str[i]; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ if (prev_delim == false) {
+ str[i] += 'a' - 'A';
+ }
+ }
+ else if (str[i] == '_') {
+ str[i] = ' ';
+ }
+
+ prev_delim = ELEM(str[i], ' ') || (str[i] >= '0' && str[i] <= '9');
+ }
}
static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* pixel space */
- wmOrtho2_region_pixelspace(ar);
-
- if (data->noback == false) {
- ui_draw_widget_menu_back(&data->bbox, true);
- }
-
- /* draw text */
- if (data->items.totitem) {
- rcti rect;
- int a;
-
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- rcti rect_pre, rect_post;
- ui_searchbox_butrect(&rect, data, a);
-
- rect_pre = rect;
- rect_post = rect;
-
- rect_pre.xmax = rect_post.xmin = rect.xmin + ((rect.xmax - rect.xmin) / 4);
-
- /* widget itself */
- /* NOTE: i18n messages extracting tool does the same, please keep it in sync. */
- {
- wmOperatorType *ot = data->items.pointers[a];
-
- int state = (a == data->active) ? UI_ACTIVE : 0;
- char text_pre[128];
- char *text_pre_p = strstr(ot->idname, "_OT_");
- if (text_pre_p == NULL) {
- text_pre[0] = '\0';
- }
- else {
- int text_pre_len;
- text_pre_p += 1;
- text_pre_len = BLI_strncpy_rlen(
- text_pre, ot->idname, min_ii(sizeof(text_pre), text_pre_p - ot->idname));
- text_pre[text_pre_len] = ':';
- text_pre[text_pre_len + 1] = '\0';
- str_tolower_titlecaps_ascii(text_pre, sizeof(text_pre));
- }
-
- rect_pre.xmax += 4; /* sneaky, avoid showing ugly margin */
- ui_draw_menu_item(
- &data->fstyle, &rect_pre, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre),
- data->items.icons[a], state, false);
- ui_draw_menu_item(&data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep);
- }
-
- }
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
- }
- }
+ uiSearchboxData *data = ar->regiondata;
+
+ /* pixel space */
+ wmOrtho2_region_pixelspace(ar);
+
+ if (data->noback == false) {
+ ui_draw_widget_menu_back(&data->bbox, true);
+ }
+
+ /* draw text */
+ if (data->items.totitem) {
+ rcti rect;
+ int a;
+
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ rcti rect_pre, rect_post;
+ ui_searchbox_butrect(&rect, data, a);
+
+ rect_pre = rect;
+ rect_post = rect;
+
+ rect_pre.xmax = rect_post.xmin = rect.xmin + ((rect.xmax - rect.xmin) / 4);
+
+ /* widget itself */
+ /* NOTE: i18n messages extracting tool does the same, please keep it in sync. */
+ {
+ wmOperatorType *ot = data->items.pointers[a];
+
+ int state = (a == data->active) ? UI_ACTIVE : 0;
+ char text_pre[128];
+ char *text_pre_p = strstr(ot->idname, "_OT_");
+ if (text_pre_p == NULL) {
+ text_pre[0] = '\0';
+ }
+ else {
+ int text_pre_len;
+ text_pre_p += 1;
+ text_pre_len = BLI_strncpy_rlen(
+ text_pre, ot->idname, min_ii(sizeof(text_pre), text_pre_p - ot->idname));
+ text_pre[text_pre_len] = ':';
+ text_pre[text_pre_len + 1] = '\0';
+ str_tolower_titlecaps_ascii(text_pre, sizeof(text_pre));
+ }
+
+ rect_pre.xmax += 4; /* sneaky, avoid showing ugly margin */
+ ui_draw_menu_item(&data->fstyle,
+ &rect_pre,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre),
+ data->items.icons[a],
+ state,
+ false);
+ ui_draw_menu_item(
+ &data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep);
+ }
+ }
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
}
ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but)
{
- ARegion *ar;
+ ARegion *ar;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- ar = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
+ ar = ui_searchbox_create_generic(C, butregion, but);
- ar->type->draw = ui_searchbox_region_draw_cb__operator;
+ ar->type->draw = ui_searchbox_region_draw_cb__operator;
- return ar;
+ return ar;
}
void ui_searchbox_free(bContext *C, ARegion *ar)
{
- ui_region_temp_remove(C, CTX_wm_screen(C), ar);
+ ui_region_temp_remove(C, CTX_wm_screen(C), ar);
}
/* sets red alert if button holds a string it can't find */
/* XXX weak: search_func adds all partial matches... */
void ui_but_search_refresh(uiBut *but)
{
- uiSearchItems *items;
- int x1;
-
- /* possibly very large lists (such as ID datablocks) only
- * only validate string RNA buts (not pointers) */
- if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
- return;
- }
-
- items = MEM_callocN(sizeof(uiSearchItems), "search items");
-
- /* setup search struct */
- items->maxitem = 10;
- items->maxstrlen = 256;
- items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
- for (x1 = 0; x1 < items->maxitem; x1++) {
- items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
- }
-
- but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items);
-
- /* only redalert when we are sure of it, this can miss cases when >10 matches */
- if (items->totitem == 0) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
- else if (items->more == 0) {
- if (UI_search_items_find_index(items, but->drawstr) == -1) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
- }
-
- for (x1 = 0; x1 < items->maxitem; x1++) {
- MEM_freeN(items->names[x1]);
- }
- MEM_freeN(items->names);
- MEM_freeN(items);
+ uiSearchItems *items;
+ int x1;
+
+ /* possibly very large lists (such as ID datablocks) only
+ * only validate string RNA buts (not pointers) */
+ if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
+ return;
+ }
+
+ items = MEM_callocN(sizeof(uiSearchItems), "search items");
+
+ /* setup search struct */
+ items->maxitem = 10;
+ items->maxstrlen = 256;
+ items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
+ for (x1 = 0; x1 < items->maxitem; x1++) {
+ items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
+ }
+
+ but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items);
+
+ /* only redalert when we are sure of it, this can miss cases when >10 matches */
+ if (items->totitem == 0) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+ else if (items->more == 0) {
+ if (UI_search_items_find_index(items, but->drawstr) == -1) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+ }
+
+ for (x1 = 0; x1 < items->maxitem; x1++) {
+ MEM_freeN(items->names[x1]);
+ }
+ MEM_freeN(items->names);
+ MEM_freeN(items);
}
/** \} */