UI: number button arrows appear on hover, highlight clickable areas.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user