diff options
Diffstat (limited to 'src/gui')
| -rw-r--r-- | src/gui/button.cpp | 24 | ||||
| -rw-r--r-- | src/gui/floatinput.cpp | 88 | ||||
| -rw-r--r-- | src/gui/list.cpp | 32 |
3 files changed, 129 insertions, 15 deletions
diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 2b57772..e66130b 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -5,15 +5,31 @@ void gui_button_draw_fn( void* ptr ) { I32 x = gui_relx( btn ); I32 y = gui_rely( btn ); + I32 mx, my; + gui_cursor_pos( &mx, &my ); + U8 inbounds = mx >= x && mx <= x + btn->w && my >= y && my <= y + btn->h; + U8 active = btn->held && inbounds && gui_mbutton_down( GUI_MBTNLEFT ); + U8 hover = inbounds && !active; + + CLR border = gui_is_fg_window( btn )? ui_clr.border : ui_clr.border_inactive; + + CLR fill = ui_clr.bg_sec; + CLR txt = ui_clr.txt; + if( active ) { + fill = CLR::blend( ui_clr.bg_sec, ui_clr.border, 0.22f ); + } + if( hover ) { + fill = ui_clr.border; + txt = CLR::BLACK(); + } - CLR col = gui_is_fg_window( btn )? ui_clr.border : ui_clr.border_inactive; - gui_draw_frect( x, y, btn->w, btn->h, col ); - gui_draw_frect( x+1, y+1, btn->w-2, btn->h-2, ui_clr.bg_sec ); + gui_draw_frect( x, y, btn->w, btn->h, border ); + gui_draw_frect( x+1, y+1, btn->w-2, btn->h-2, fill ); I32 middle = x + btn->w/2; I32 middle_y = y + btn->h/2 - 7; - gui_draw_str( middle, middle_y, ALIGN_C, FNT_JPN12, ui_clr.txt, btn->name ); + gui_draw_str( middle, middle_y, ALIGN_C, FNT_JPN12, txt, btn->name ); } void gui_button_input_fn( void* ptr ) { diff --git a/src/gui/floatinput.cpp b/src/gui/floatinput.cpp index 9f7fdfe..5746758 100644 --- a/src/gui/floatinput.cpp +++ b/src/gui/floatinput.cpp @@ -1,6 +1,60 @@ #include "base.h" #include <math.h> +const I32 FLOATINPUT_STEPPER_W = 11; + +static U8 gui_floatinput_has_stepper( GUI_FLOATINPUT* input ) { + return input->w >= 46; +} + +static I32 gui_floatinput_content_w( GUI_FLOATINPUT* input ) { + I32 reserve = gui_floatinput_has_stepper( input ) ? ( FLOATINPUT_STEPPER_W + 1 ) : 0; + I32 cw = input->w - reserve; + return cw < 1 ? 1 : cw; +} + +static void gui_floatinput_clamp_and_snap( GUI_FLOATINPUT* input ) { + if( isfinite( input->min ) && *input->pval < input->min ) + *input->pval = input->wraparound ? input->max : input->min; + if( isfinite( input->max ) && *input->pval > input->max ) + *input->pval = input->wraparound ? input->min : input->max; + + F32 step = input->step; + if( !isfinite( step ) || fabsf( step ) < 0.000001f ) + return; + + F32 rmn = remainderf( *input->pval, step ); + *input->pval -= rmn; +} + +static void gui_floatinput_draw_stepper( GUI_FLOATINPUT* input ) { + if( !gui_floatinput_has_stepper( input ) ) + return; + + I32 x = gui_relx( input ); + I32 y = gui_rely( input ); + I32 w = input->w; + I32 h = input->h; + I32 sx = x + w - FLOATINPUT_STEPPER_W; + I32 sy = y + 1; + I32 sh = h - 2; + I32 top_h = sh / 2; + I32 bot_h = sh - top_h; + + CLR border = gui_is_fg_window( input )? ui_clr.border : ui_clr.border_inactive; + gui_draw_frect( sx, sy, FLOATINPUT_STEPPER_W, sh, border ); + gui_draw_frect( sx + 1, sy + 1, FLOATINPUT_STEPPER_W - 2, sh - 2, ui_clr.bg_alt ); + gui_draw_line( sx + 1, sy + top_h, sx + FLOATINPUT_STEPPER_W - 1, sy + top_h, border ); + + I32 th = 0; + gui_draw_get_str_bounds( 0, &th, FNT_JPN12, "+" ); + I32 plus_y = sy + ( top_h - th ) / 2; + I32 minus_y = sy + top_h + ( bot_h - th ) / 2; + I32 cx = sx + FLOATINPUT_STEPPER_W / 2; + gui_draw_str( cx, plus_y, ALIGN_C, FNT_JPN12, ui_clr.txt, "+" ); + gui_draw_str( cx, minus_y, ALIGN_C, FNT_JPN12, ui_clr.txt, "-" ); +} + U8 gui_floatinput_is_bound_val( GUI_FLOATINPUT* input ) { if( input->wraparound ) return 0; @@ -26,7 +80,7 @@ CLR gui_floatinput_get_progress_clr( GUI_FLOATINPUT* input ) { void gui_floatinput_draw_bound( GUI_FLOATINPUT* input ) { I32 x = gui_relx( input ); I32 y = gui_rely( input ); - I32 w = input->w; + I32 w = gui_floatinput_content_w( input ); I32 h = input->h; F32 min = input->min; @@ -52,7 +106,7 @@ void gui_floatinput_draw_bound( GUI_FLOATINPUT* input ) { void gui_floatinput_draw_unbound( GUI_FLOATINPUT* input ) { I32 x = gui_relx( input ); I32 y = gui_rely( input ); - I32 w = input->w; + I32 w = gui_floatinput_content_w( input ); F32 val = *input->pval; @@ -104,6 +158,8 @@ void gui_floatinput_draw_fn( void* ptr ) { gui_floatinput_draw_unbound( input ); else gui_floatinput_draw_bound( input ); + + gui_floatinput_draw_stepper( input ); } void gui_floatinput_input_bound( GUI_FLOATINPUT* input ) { @@ -111,7 +167,7 @@ void gui_floatinput_input_bound( GUI_FLOATINPUT* input ) { return; I32 x = gui_relx( input ); - I32 w = input->w; + I32 w = gui_floatinput_content_w( input ); F32 min = input->min; F32 max = input->max; @@ -181,6 +237,7 @@ void gui_floatinput_input_fn( void* ptr ) { GUI_FLOATINPUT* input = (GUI_FLOATINPUT*)ptr; I32 m1 = gui_mbutton_down( 0 ); + I32 m2 = gui_mbutton_down( 1 ); I32 x = gui_relx( input ); I32 y = gui_rely( input ); @@ -190,10 +247,34 @@ void gui_floatinput_input_fn( void* ptr ) { I32 mx, my; gui_cursor_pos( &mx, &my ); U8 inbounds = mx >= x && mx <= x + w && my >= y && my <= y + h; + U8 has_stepper = gui_floatinput_has_stepper( input ); + I32 step_x = x + w - FLOATINPUT_STEPPER_W; + U8 in_stepper = has_stepper && inbounds && mx >= step_x; if( inbounds ) gui_floatinput_input_scroll( input ); + if( in_stepper ) { + if( !m1 && !m2 ) { + input->held = 0; + input->heldoutbounds = 0; + return; + } + + if( !input->held ) { + U8 fine = !!m2; + I32 split_y = y + 1 + ( h - 2 ) / 2; + U8 inc = my < split_y; + F32 step = fine ? 0.1f : 1.f; + *input->pval += inc ? step : -step; + gui_floatinput_clamp_and_snap( input ); + if( input->cb ) + input->cb( input ); + input->held = 1; + } + return; + } + if( !input->held && m1 && !inbounds ) input->heldoutbounds = 1; if( !input->heldoutbounds && m1 && inbounds ) { @@ -218,6 +299,7 @@ void gui_floatinput_input_fn( void* ptr ) { gui_floatinput_input_unbound( input ); else gui_floatinput_input_bound( input ); + gui_floatinput_clamp_and_snap( input ); if( input->cb && oldv != *input->pval ) { input->cb( input ); diff --git a/src/gui/list.cpp b/src/gui/list.cpp index 90f2f49..2feff47 100644 --- a/src/gui/list.cpp +++ b/src/gui/list.cpp @@ -10,18 +10,33 @@ void gui_list_draw_fn( void* ptr ) { I32 y = gui_rely( list ); gui_draw_str( x, y, ALIGN_L, FNT_JPN12, ui_clr.txt, list->name ); - y += LIST_TITLE_OFFSET; + I32 panel_y = y + LIST_TITLE_OFFSET; CLR col = gui_is_fg_window( list )? ui_clr.border : ui_clr.border_inactive; - gui_draw_frect( x, y, list->w, list->h, col ); - gui_draw_frect( x+1, y+1, list->w-2, list->h-2, ui_clr.bg_sec ); + gui_draw_frect( x, panel_y, list->w, list->h, col ); + gui_draw_frect( x + 1, panel_y + 1, list->w - 2, list->h - 2, ui_clr.bg_sec ); + + I32 txt_h = 12; + gui_draw_get_str_bounds( 0, &txt_h, FNT_JPN12, "ag" ); I32 yoff = 0; list->plist->each( fn( GUI_LIST_ENTRY* e ) { U8 selected = e->val == *list->pval; - CLR col = selected? ui_clr.txt : ui_clr.txt_inactive; + I32 row_x = x + 1; + I32 row_y = panel_y + 1 + yoff; + I32 row_w = list->w - 2; + if( row_w < 1 ) row_w = 1; + I32 row_h = LIST_ITEM_HEIGHT; + + if( selected ) { + CLR sel_bg = CLR::blend( ui_clr.border, ui_clr.bg, 0.70f ); + gui_draw_frect( row_x, row_y, row_w, row_h, sel_bg ); + } + + CLR col = selected ? ui_clr.txt : ui_clr.txt_inactive; + I32 txt_y = row_y + ( row_h - txt_h ) / 2; - gui_draw_str( x + 4, y + yoff + 6, ALIGN_L, FNT_JPN12, col, e->title ); + gui_draw_str( row_x + 3, txt_y, ALIGN_L, FNT_JPN12, col, e->title ); yoff += LIST_ITEM_HEIGHT; } ); } @@ -31,6 +46,7 @@ void gui_list_input_fn( void* ptr ) { I32 x = gui_relx( list ); I32 y = gui_rely( list ); + I32 panel_y = y + LIST_TITLE_OFFSET; I32 w = list->w; I32 h = list->h; @@ -38,12 +54,12 @@ void gui_list_input_fn( void* ptr ) { I32 mx, my; gui_cursor_pos( &mx, &my ); - U8 inbounds = mx >= x && mx <= x + w && my >= y && my <= y + h; + U8 inbounds = mx >= x && mx <= x + w && my >= panel_y && my <= panel_y + h; if( !inbounds ) return; - I32 diff = my - y; - I32 idx = diff / LIST_ITEM_HEIGHT - 1; + I32 diff = my - panel_y; + I32 idx = diff / LIST_ITEM_HEIGHT; if( idx >= list->plist->size ) idx = list->plist->size - 1; if( idx < 0 ) idx = 0; |
