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:
authorJulian Eisel <eiseljulian@gmail.com>2016-11-28 20:59:31 +0300
committerJulian Eisel <eiseljulian@gmail.com>2016-11-28 21:03:31 +0300
commite0307113a5dcc4a1bff2b8e639205c8d2070f52b (patch)
tree621f293ae8ba12cbf0623a5fdbe097cf14878a5e /source/blender/editors
parentdf687837f822352de3a052b0abc8e1976c583aef (diff)
UI: Add 'x' icon to text buttons to clear content
This is useful e.g. for search buttons to quickly clear the filter string. We might want to make this optional for python scripts.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c41
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c90
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_utils.c1
-rw-r--r--source/blender/editors/interface/interface_widgets.c10
9 files changed, 94 insertions, 62 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index fd5351394c3..9fbce7dd203 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -181,7 +181,7 @@ enum {
UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
UI_BUT_UPDATE_DELAY = (1 << 28), /* don't run updates while dragging (needed in rare cases). */
UI_BUT_TEXTEDIT_UPDATE = (1 << 29), /* when widget is in textedit mode, update value on each char stroke */
- UI_BUT_SEARCH_UNLINK = (1 << 30), /* show unlink for search button */
+ UI_BUT_VALUE_CLEAR = (1 << 30), /* show 'x' icon to clear/unlink value of text or search button */
};
#define UI_PANEL_WIDTH 340
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 6bba35e821f..a913421d12c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1987,22 +1987,29 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but)
/** \name Check to show extra icons
*
* Extra icons are shown on the right hand side of buttons.
+ * This could (should!) definitely become more generic, but for now this is good enough.
* \{ */
+static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
+{
+ BLI_assert(but->type == UI_BTYPE_TEXT);
+ return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr && but->drawstr[0]);
+}
+
static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
{
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
return ((but->editstr == NULL) &&
(but->drawstr[0] != '\0') &&
- (but->flag & UI_BUT_SEARCH_UNLINK));
+ (but->flag & UI_BUT_VALUE_CLEAR));
}
-static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
+static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but)
{
StructRNA *type;
short idcode;
- BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK));
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR));
if (but->rnaprop == NULL) {
return false;
@@ -2011,21 +2018,31 @@ static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
idcode = RNA_type_to_ID_code(type);
-
return ((but->editstr == NULL) &&
(idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
}
uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
{
- if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) {
- /* pass */
- }
- else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
- return UI_BUT_ICONEXTRA_UNLINK;
- }
- else if (ui_but_icon_extra_is_visible_eyedropper(but)) {
- return UI_BUT_ICONEXTRA_EYEDROPPER;
+ switch (but->type) {
+ case UI_BTYPE_TEXT:
+ if (ui_but_icon_extra_is_visible_text_clear(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ break;
+ case UI_BTYPE_SEARCH_MENU:
+ if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
+ /* pass */
+ }
+ else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) {
+ return UI_BUT_ICONEXTRA_EYEDROPPER;
+ }
+ break;
+ default:
+ break;
}
return UI_BUT_ICONEXTRA_NONE;
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index d7f06b7db13..5f7a018e4c2 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -748,7 +748,7 @@ static int datadropper_poll(bContext *C)
if ((CTX_wm_window(C) != NULL) &&
(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
(but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_SEARCH_UNLINK))
+ (but->flag & UI_BUT_VALUE_CLEAR))
{
if (prop && RNA_property_type(prop) == PROP_POINTER) {
StructRNA *type = RNA_property_pointer_type(&ptr, prop);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fc511d61e2b..33f1d5e93cb 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2563,6 +2563,18 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *bu
}
}
+static void ui_but_text_clear(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (!data->str) {
+ data->str = MEM_callocN(1, "temp str");
+ }
+ data->str[0] = 0;
+
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+}
+
/* ************* in-button text selection/editing ************* */
@@ -3842,6 +3854,21 @@ static int ui_do_but_KEYEVT(
return WM_UI_HANDLER_CONTINUE;
}
+static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
+{
+ int x = mouse_xy[0], y = mouse_xy[1];
+ rcti icon_rect;
+
+ BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
+
+ ui_window_to_block(region, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&icon_rect, &but->rect);
+ icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
+
+ return BLI_rcti_isect_pt(&icon_rect, x, y);
+}
+
static int ui_do_but_TEX(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
@@ -3855,7 +3882,14 @@ static int ui_do_but_TEX(
/* pass */
}
else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
+
+ if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
+ ui_but_text_clear(C, but, data);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
return WM_UI_HANDLER_BREAK;
}
}
@@ -3876,47 +3910,29 @@ static int ui_do_but_SEARCH_UNLINK(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
{
- uiButExtraIconType extra_icon_type;
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
+ const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE);
/* unlink icon is on right */
if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
- ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
+ (has_icon_extra == true) &&
+ (ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true))
{
- ARegion *ar = data->region;
- rcti rect;
- int x = event->x, y = event->y;
-
- ui_window_to_block(ar, but->block, &x, &y);
-
- BLI_rcti_rctf_copy(&rect, &but->rect);
-
- rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
- /* handle click on unlink/eyedropper icon */
- if (BLI_rcti_isect_pt(&rect, x, y)) {
- /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
- if (event->val == KM_RELEASE) {
- /* unlink */
- if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
- /* most likely NULL, but let's check, and give it temp zero string */
- if (data->str == NULL) {
- data->str = MEM_callocN(1, "temp str");
- }
- data->str[0] = 0;
-
- ui_apply_but_TEX(C, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- /* eyedropper */
- else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
- WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
- }
- else {
- BLI_assert(0);
- }
+ /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
+ if (event->val == KM_RELEASE) {
+ /* unlink */
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
+ ui_but_text_clear(C, but, data);
+ }
+ /* eyedropper */
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ }
+ else {
+ BLI_assert(0);
}
-
- return WM_UI_HANDLER_BREAK;
}
+ return WM_UI_HANDLER_BREAK;
}
return ui_do_but_TEX(C, block, but, data, event);
}
@@ -7091,7 +7107,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_TEXT:
case UI_BTYPE_SEARCH_MENU:
if ((but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_SEARCH_UNLINK))
+ (but->flag & UI_BUT_VALUE_CLEAR))
{
retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
if (retval & WM_UI_HANDLER_BREAK) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index fcf827bdbe6..d8f9fdcbaae 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -127,7 +127,7 @@ enum {
* (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */
typedef enum uiButExtraIconType {
UI_BUT_ICONEXTRA_NONE = 1,
- UI_BUT_ICONEXTRA_UNLINK,
+ UI_BUT_ICONEXTRA_CLEAR,
UI_BUT_ICONEXTRA_EYEDROPPER,
} uiButExtraIconType;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 875522e01c6..b128bf47b5f 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1659,7 +1659,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->rnasearchprop = searchprop;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
if (RNA_property_is_unlink(prop)) {
- but->flag |= UI_BUT_SEARCH_UNLINK;
+ but->flag |= UI_BUT_VALUE_CLEAR;
}
if (RNA_property_type(prop) == PROP_ENUM) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index cdf34642a8d..466978272bc 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -851,7 +851,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
}
else {
/* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->flag & UI_BUT_SEARCH_UNLINK) ? -1 : 0;
+ data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
}
}
@@ -922,8 +922,8 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
return true;
}
- else if (but->flag & UI_BUT_SEARCH_UNLINK) {
- /* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */
+ 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;
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 1d51c0588b6..f4df3d4ec2e 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -119,6 +119,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
else
but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ UI_but_flag_enable(but, UI_BUT_VALUE_CLEAR); /* might want to make this optional? */
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index c285d753b96..d43a94c5514 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1508,10 +1508,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* draws text and icons for buttons */
static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
const bool show_menu_icon = ui_but_draw_menu_icon(but);
float alpha = (float)wcol->text[3] / 255.0f;
char password_str[UI_MAX_DRAW_STR];
- uiButExtraIconType extra_icon_type;
ui_but_text_password_hide(password_str, but, false);
@@ -1577,15 +1577,13 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
}
- /* unlink icon for this button type */
- if ((but->type == UI_BTYPE_SEARCH_MENU) &&
- ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
- {
+ /* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */
+ if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) {
rcti temp = *rect;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
- if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
widget_draw_icon(but, ICON_X, alpha, &temp, false);
}
else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {