+#ifndef VG_SETTINGS_MENU_H
+#define VG_SETTINGS_MENU_H
+
+#include "vg.h"
+#include "vg_imgui.h"
+
+struct ui_enum_opt vg_settings_vsync_enum[] = {
+ { 0, "None" },
+ { 1, "On" },
+ {-1, "Adaptive" },
+};
+
+struct ui_enum_opt vg_settings_quality_enum[] = {
+ { 0, "High Quality" },
+ { 1, "Faster" },
+ { 2, "Absolute Minimum" },
+};
+
+struct ui_enum_opt vg_settings_screen_mode_enum[] = {
+ { 0, "Fullscreen (desktop)" },
+ { 1, "Fullscreen (native)" },
+ { 2, "Floating Window" }
+};
+
+struct {
+ struct vg_setting_ranged_i32{
+ i32 new_value, *actual_value, min, max;
+ char buf[10];
+ const char *label;
+ }
+ fps_limit;
+
+ struct vg_setting_enum{
+ i32 new_value, *actual_value;
+
+ struct ui_enum_opt *options;
+ u32 option_count;
+ const char *label;
+ }
+ vsync, quality, screenmode;
+
+ int windowed_before[4];
+}
+static vg_settings = {
+ .fps_limit = { .label = "Fps Limit",
+ .min=24, .max=300, .actual_value = &vg.fps_limit },
+ .vsync = { .label = "Vsync",
+ .actual_value = &vg.vsync,
+ .options = vg_settings_vsync_enum, .option_count = 3 },
+ .quality = { .label = "Graphic Quality",
+ .actual_value = &vg.quality_profile,
+ .options = vg_settings_quality_enum, .option_count = 3 },
+ .screenmode = { .label = "Type",
+ .actual_value = &vg.screen_mode,
+ .options = vg_settings_screen_mode_enum, .option_count=3 }
+
+};
+
+static void vg_settings_ui_draw_diff( ui_rect orig ){
+ ui_rect l,r;
+ ui_split( orig, k_ui_axis_v, -32, 0, l, r );
+ ui_text( r, "*", 1, k_ui_align_middle_center, ui_colour(k_ui_blue) );
+}
+
+/* i32 settings
+ * ------------------------------------------------------------------------- */
+
+static void vg_settings_ui_int( char *buf, u32 len ){
+ for( u32 i=0, j=0; i<len; i ++ ){
+ if( ((buf[i] >= '0') && (buf[i] <= '9')) || (buf[i] == '\0') )
+ buf[j ++] = buf[i];
+ }
+}
+
+struct ui_textbox_callbacks static vg_settings_ui_int_callbacks = {
+ .change = vg_settings_ui_int
+};
+
+static bool vg_settings_ranged_i32_valid( struct vg_setting_ranged_i32 *prop ){
+ if( prop->new_value < prop->min ) return 0;
+ if( prop->new_value > prop->max ) return 0;
+ return 1;
+}
+
+static bool vg_settings_ranged_i32_diff( struct vg_setting_ranged_i32 *prop ){
+ if( prop->new_value != *prop->actual_value ) return 1;
+ else return 0;
+}
+
+static bool vg_settings_ui_ranged_i32( struct vg_setting_ranged_i32 *prop,
+ ui_rect rect ){
+ ui_rect orig;
+ rect_copy( rect, orig );
+
+ ui_textbox( rect, prop->label, prop->buf, sizeof(prop->buf),
+ 1, 0, &vg_settings_ui_int_callbacks );
+ prop->new_value = atoi( prop->buf );
+
+ if( vg_settings_ranged_i32_diff( prop ) )
+ vg_settings_ui_draw_diff( orig );
+
+ bool valid = vg_settings_ranged_i32_valid( prop );
+ if( !valid ){
+ ui_rect _null, line;
+ ui_split( orig, k_ui_axis_h, -1, 0, _null, line );
+ line[1] += 3;
+
+ ui_fill( line, ui_colour( k_ui_red ) );
+ }
+
+ return valid;
+}
+
+static void ui_settings_ranged_i32_init( struct vg_setting_ranged_i32 *prop ){
+ vg_str tmp;
+ vg_strnull( &tmp, prop->buf, sizeof(prop->buf) );
+ vg_strcati32( &tmp, *prop->actual_value );
+ prop->new_value = *prop->actual_value;
+}
+
+/* enum settings
+ * ------------------------------------------------------------------------- */
+
+static bool vg_settings_enum_diff( struct vg_setting_enum *prop ){
+ if( prop->new_value != *prop->actual_value ) return 1;
+ else return 0;
+}
+
+static bool vg_settings_enum( struct vg_setting_enum *prop, ui_rect rect ){
+ ui_rect orig;
+ rect_copy( rect, orig );
+
+ ui_enum( rect, prop->label,
+ prop->options, prop->option_count, &prop->new_value );
+
+ if( vg_settings_enum_diff( prop ) )
+ vg_settings_ui_draw_diff( orig );
+
+ return 1;
+}
+
+static void ui_settings_enum_init( struct vg_setting_enum *prop ){
+ prop->new_value = *prop->actual_value;
+}
+
+/* .. */
+
+static void vg_settings_ui_header( ui_rect inout_panel, const char *name ){
+ ui_rect rect;
+ ui_standard_widget( inout_panel, rect, 2 );
+ ui_text( rect, name, 1, k_ui_align_middle_center, ui_colour(k_ui_fg+3) );
+}
+
+static void vg_settings_video_apply(void){
+ if( vg_settings_enum_diff( &vg_settings.screenmode ) ){
+ vg.screen_mode = vg_settings.screenmode.new_value;
+
+ if( (vg.screen_mode == 0) || (vg.screen_mode == 1) ){
+ SDL_GetWindowPosition( vg.window,
+ &vg_settings.windowed_before[0],
+ &vg_settings.windowed_before[1] );
+ vg_settings.windowed_before[2] = vg.window_x;
+ vg_settings.windowed_before[3] = vg.window_y;
+
+ SDL_DisplayMode video_mode;
+ if( SDL_GetDesktopDisplayMode( 0, &video_mode ) ){
+ vg_error("SDL_GetDesktopDisplayMode failed: %s\n", SDL_GetError());
+ }
+ else {
+ //vg.display_refresh_rate = video_mode.refresh_rate;
+ vg.window_x = video_mode.w;
+ vg.window_y = video_mode.h;
+ }
+ SDL_SetWindowResizable( vg.window, SDL_FALSE );
+ SDL_SetWindowSize( vg.window, vg.window_x, vg.window_y );
+ }
+
+ if( vg.screen_mode == 0 )
+ SDL_SetWindowFullscreen( vg.window, SDL_WINDOW_FULLSCREEN_DESKTOP );
+ if( vg.screen_mode == 1 )
+ SDL_SetWindowFullscreen( vg.window, SDL_WINDOW_FULLSCREEN );
+ if( vg.screen_mode == 2 ){
+ SDL_SetWindowFullscreen( vg.window, 0 );
+ SDL_SetWindowSize( vg.window,
+ vg_settings.windowed_before[2],
+ vg_settings.windowed_before[3] );
+ SDL_SetWindowPosition( vg.window,
+ vg_settings.windowed_before[0],
+ vg_settings.windowed_before[1] );
+ SDL_SetWindowResizable( vg.window, SDL_TRUE );
+ }
+ }
+
+ vg.fps_limit = vg_settings.fps_limit.new_value;
+ vg.quality_profile = vg_settings.quality.new_value;
+ vg.vsync = vg_settings.vsync.new_value;
+}
+
+static void aaaaaaaaaaaaaaaaa( ui_rect r );
+static void vg_settings_video_gui( ui_rect panel ){
+ bool validated = 1;
+ ui_rect rq;
+ ui_standard_widget( panel, rq, 1 );
+ vg_settings_enum( &vg_settings.quality, rq );
+
+ /* FIXME */
+#if 0
+ if( vg.vsync_feature == k_vsync_feature_error ){
+ ui_info( panel, "There was an error activating vsync feature." );
+ }
+#endif
+
+ /* frame timing */
+ vg_settings_ui_header( panel, "Frame Timing" );
+ ui_rect duo, d0,d1;
+ ui_standard_widget( panel, duo, 1 );
+ ui_split_ratio( duo, k_ui_axis_v, 0.5f, 16, d0, d1 );
+
+ vg_settings_enum( &vg_settings.vsync, d0 );
+ validated &= vg_settings_ui_ranged_i32( &vg_settings.fps_limit, d1 );
+
+ ui_standard_widget( panel, duo, 10 );
+ aaaaaaaaaaaaaaaaa( duo );
+
+ /* window spec */
+ vg_settings_ui_header( panel, "Window Specification" );
+
+ ui_standard_widget( panel, duo, 1 );
+ vg_settings_enum( &vg_settings.screenmode, duo );
+
+ /* apply */
+ ui_rect last_row;
+ ui_px height = (vg_ui.font->glyph_height + 18) * k_ui_scale;
+ ui_split( panel, k_ui_axis_h, -height, k_ui_padding,
+ panel, last_row );
+
+ const char *string = "Apply";
+ if( validated ){
+ if( ui_button( last_row, string ) == 1 )
+ vg_settings_video_apply();
+ }
+ else{
+ ui_rect rect;
+ ui_standard_widget( last_row, rect, 1 );
+ ui_fill( rect, ui_colour( k_ui_bg+1 ) );
+ ui_outline( rect, -1, ui_colour( k_ui_red ), 0 );
+
+ ui_rect t = { 0,0, ui_text_line_width( string ), 14 };
+ ui_rect_center( rect, t );
+ ui_text( t, string, 1, k_ui_align_left, ui_colour(k_ui_fg+3) );
+ }
+}
+
+static void vg_settings_gui(void){
+ ui_rect null;
+ ui_rect screen = { 0, 0, vg.window_x, vg.window_y };
+ ui_rect window = { 0, 0, 1000, 700 };
+ ui_rect_center( screen, window );
+ vg_ui.wants_mouse = 1;
+
+ ui_fill( window, ui_colour( k_ui_bg+1 ) );
+ ui_outline( window, 1, ui_colour( k_ui_bg+7 ), 0 );
+
+ ui_rect title, panel;
+ ui_split( window, k_ui_axis_h, 28, 0, title, panel );
+ ui_fill( title, ui_colour( k_ui_bg+7 ) );
+ ui_text( title, "Settings", 1, k_ui_align_middle_center,
+ ui_colourcont(k_ui_bg+7) );
+
+ ui_rect quit_button;
+ ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
+
+ if( ui_button_text( quit_button, "X", 1 ) == 1 ){
+ vg.settings_open = 0;
+ return;
+ }
+
+ ui_rect_pad( panel, (ui_px[2]){ 8, 8 } );
+
+ static i32 page = 0;
+ ui_tabs( panel, panel, (const char *[]){ "video", "audio", "game" },
+ 3, &page );
+
+ if( page == 0 ){
+ vg_settings_video_gui( panel );
+ }
+}
+
+static int cmd_vg_settings_toggle( int argc, const char *argv[] ){
+ vg.settings_open = !vg.settings_open;
+
+ if( vg.settings_open ){
+ ui_settings_ranged_i32_init( &vg_settings.fps_limit );
+ ui_settings_enum_init( &vg_settings.vsync );
+ ui_settings_enum_init( &vg_settings.quality );
+ ui_settings_enum_init( &vg_settings.screenmode );
+ }
+ return 0;
+}
+
+#endif /* VG_SETTINGS_MENU_H */