UI: number button arrows appear on hover, highlight clickable areas.

This commit is contained in:
2018-04-22 13:57:50 +02:00
parent 15ca90489f
commit 20a713b7ff
3 changed files with 143 additions and 21 deletions

View File

@@ -221,6 +221,9 @@ enum {
UI_BUT_ALIGN_ALL = (UI_BUT_ALIGN | UI_BUT_ALIGN_STITCH_TOP | UI_BUT_ALIGN_STITCH_LEFT),
UI_BUT_BOX_ITEM = (1 << 20), /* This but is "inside" a box item (currently used to change theme colors). */
UI_BUT_ACTIVE_LEFT = (1 << 21), /* Active left part of number button */
UI_BUT_ACTIVE_RIGHT = (1 << 22), /* Active left part of number button */
};
/* scale fixed button widths by this to account for DPI */

View File

@@ -4167,6 +4167,36 @@ static bool ui_numedit_but_NUM(
return changed;
}
static void ui_numedit_set_active(uiBut *but)
{
int oldflag = but->drawflag;
but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT);
uiHandleButtonData *data = but->active;
if (!data) {
return;
}
/* we can click on the side arrows to increment/decrement,
* or click inside to edit the value directly */
int mx = data->window->eventstate->x;
int my = data->window->eventstate->x;
ui_window_to_block(data->region, but->block, &mx, &my);
float handle_width = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect) * 0.7f);
if (mx < (but->rect.xmin + handle_width)) {
but->drawflag |= UI_BUT_ACTIVE_LEFT;
}
else if (mx > (but->rect.xmax - handle_width)) {
but->drawflag |= UI_BUT_ACTIVE_RIGHT;
}
if (but->drawflag != oldflag) {
ED_region_tag_redraw(data->region);
}
}
static int ui_do_but_NUM(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
@@ -4180,6 +4210,7 @@ static int ui_do_but_NUM(
my = screen_my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
ui_numedit_set_active(but);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
int type = event->type, val = event->val;
@@ -4289,16 +4320,13 @@ static int ui_do_but_NUM(
/* we can click on the side arrows to increment/decrement,
* or click inside to edit the value directly */
float tempf, softmin, softmax;
float handlewidth;
int temp;
softmin = but->softmin;
softmax = but->softmax;
handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect));
if (!ui_but_is_float(but)) {
if (mx < (but->rect.xmin + handlewidth)) {
if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value - 1;
@@ -4309,7 +4337,7 @@ static int ui_do_but_NUM(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (mx > (but->rect.xmax - handlewidth)) {
else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value + 1;
@@ -4325,7 +4353,7 @@ static int ui_do_but_NUM(
}
}
else {
if (mx < (but->rect.xmin + handlewidth)) {
if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1);
@@ -4334,7 +4362,7 @@ static int ui_do_but_NUM(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (mx > but->rect.xmax - handlewidth) {
else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1);
@@ -7792,6 +7820,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE);
}
else if (but->type == UI_BTYPE_NUM) {
ui_numedit_set_active(but);
}
}
static void button_activate_exit(
@@ -8229,7 +8260,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
case EVT_BUT_CANCEL:
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
retval = WM_UI_HANDLER_CONTINUE;
break;
case MOUSEMOVE:
{
@@ -8269,7 +8299,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
}
retval = WM_UI_HANDLER_CONTINUE;
break;
}
/* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
@@ -8280,10 +8309,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
UI_but_tooltip_timer_remove(C, but);
ATTR_FALLTHROUGH;
default:
/* handle button type specific events */
retval = ui_do_button(C, block, but, event);
break;
}
/* handle button type specific events */
retval = ui_do_button(C, block, but, event);
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
switch (event->type) {

View File

@@ -72,8 +72,13 @@ enum {
/* Show that holding the button opens a menu. */
UI_STATE_HOLD_ACTION = UI_BUT_UPDATE_DELAY,
UI_STATE_TEXT_INPUT = UI_BUT_UNDO,
UI_STATE_ACTIVE_LEFT = UI_BUT_VALUE_CLEAR,
UI_STATE_ACTIVE_RIGHT = UI_BUT_TEXTEDIT_UPDATE,
UI_STATE_FLAGS_ALL = (UI_STATE_HOLD_ACTION | UI_STATE_TEXT_INPUT),
UI_STATE_FLAGS_ALL = (UI_STATE_HOLD_ACTION |
UI_STATE_TEXT_INPUT |
UI_STATE_ACTIVE_LEFT |
UI_STATE_ACTIVE_RIGHT),
};
/* Prevent accidental use. */
#define UI_BUT_UPDATE_DELAY ((void)0)
@@ -836,7 +841,12 @@ static void shape_preset_init_trias_ex(
float centx, centy, sizex, sizey, minsize;
int a, i1 = 0, i2 = 1;
minsize = min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
if (where == 'r' || where == 'l') {
minsize = BLI_rcti_size_y(rect);
}
else {
minsize = BLI_rcti_size_x(rect);
}
/* center position and size */
centx = (float)rect->xmin + 0.4f * minsize;
@@ -2444,6 +2454,13 @@ static void ui_widget_color_disabled(uiWidgetType *wt)
wt->wcol_theme = &wcol_theme_s;
}
static void widget_active_color(char cp[3])
{
cp[0] = cp[0] >= 240 ? 255 : cp[0] + 15;
cp[1] = cp[1] >= 240 ? 255 : cp[1] + 15;
cp[2] = cp[2] >= 240 ? 255 : cp[2] + 15;
}
/* copy colors from theme, and set changes in it based on state */
static void widget_state(uiWidgetType *wt, int state)
{
@@ -2489,9 +2506,7 @@ static void widget_state(uiWidgetType *wt, int state)
widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden, wcol_state->blend);
if (state & UI_ACTIVE) { /* mouse over? */
wt->wcol.inner[0] = wt->wcol.inner[0] >= 240 ? 255 : wt->wcol.inner[0] + 15;
wt->wcol.inner[1] = wt->wcol.inner[1] >= 240 ? 255 : wt->wcol.inner[1] + 15;
wt->wcol.inner[2] = wt->wcol.inner[2] >= 240 ? 255 : wt->wcol.inner[2] + 15;
widget_active_color(wt->wcol.inner);
}
}
@@ -3187,6 +3202,7 @@ static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int
{
uiWidgetBase wtb;
const float rad = wcol->roundness * BLI_rcti_size_y(rect);
const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
if (state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
@@ -3202,12 +3218,76 @@ static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int
}
/* decoration */
if (!(state & UI_STATE_TEXT_INPUT)) {
shape_preset_init_number_arrows(&wtb.tria1, rect, 0.6f, 'l');
shape_preset_init_number_arrows(&wtb.tria2, rect, 0.6f, 'r');
}
if ((state & UI_ACTIVE) && !(state & UI_STATE_TEXT_INPUT)) {
uiWidgetColors wcol_zone;
uiWidgetBase wtb_zone;
rcti rect_zone;
int roundboxalign_zone;
widgetbase_draw(&wtb, wcol);
/* left arrow zone */
widget_init(&wtb_zone);
wtb_zone.draw_outline = false;
wtb_zone.draw_emboss = false;
wcol_zone = *wcol;
copy_v3_v3_char(wcol_zone.item, wcol->text);
if (state & UI_STATE_ACTIVE_LEFT) {
widget_active_color(wcol_zone.inner);
}
rect_zone = *rect;
rect_zone.xmax = rect->xmin + handle_width + U.pixelsize;
roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
shape_preset_init_number_arrows(&wtb_zone.tria1, &rect_zone, 0.6f, 'l');
widgetbase_draw(&wtb_zone, &wcol_zone);
/* right arrow zone */
widget_init(&wtb_zone);
wtb_zone.draw_outline = false;
wtb_zone.draw_emboss = false;
wtb_zone.tria1.type = ROUNDBOX_TRIA_ARROWS;
wcol_zone = *wcol;
copy_v3_v3_char(wcol_zone.item, wcol->text);
if (state & UI_STATE_ACTIVE_RIGHT) {
widget_active_color(wcol_zone.inner);
}
rect_zone = *rect;
rect_zone.xmin = rect->xmax - handle_width - U.pixelsize;
roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
shape_preset_init_number_arrows(&wtb_zone.tria2, &rect_zone, 0.6f, 'r');
widgetbase_draw(&wtb_zone, &wcol_zone);
/* middle highlight zone */
widget_init(&wtb_zone);
wtb_zone.draw_outline = false;
wtb_zone.draw_emboss = false;
wcol_zone = *wcol;
copy_v3_v3_char(wcol_zone.item, wcol->text);
if (!(state & (UI_STATE_ACTIVE_LEFT|UI_STATE_ACTIVE_RIGHT))) {
widget_active_color(wcol_zone.inner);
}
rect_zone = *rect;
rect_zone.xmin = rect->xmin + handle_width - U.pixelsize;
rect_zone.xmax = rect->xmax - handle_width + U.pixelsize;
round_box_edges(&wtb_zone, 0, &rect_zone, 0);
widgetbase_draw(&wtb_zone, &wcol_zone);
/* outline */
wtb.draw_inner = false;
widgetbase_draw(&wtb, wcol);
}
else {
/* inner and outline */
widgetbase_draw(&wtb, wcol);
}
if (!(state & UI_STATE_TEXT_INPUT)) {
const float textofs = 0.425f * BLI_rcti_size_y(rect);
@@ -4453,6 +4533,15 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
state |= UI_STATE_HOLD_ACTION;
}
if (state & UI_ACTIVE) {
if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
state |= UI_STATE_ACTIVE_LEFT;
}
else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
state |= UI_STATE_ACTIVE_RIGHT;
}
}
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE))
if (but->dt != UI_EMBOSS_PULLDOWN)
disabled = true;