textbox start
authorhgn <hgodden00@gmail.com>
Mon, 1 May 2023 02:21:59 +0000 (03:21 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 1 May 2023 02:21:59 +0000 (03:21 +0100)
submodules/SDL
vg.h
vg_imgui.h
vg_log.h

index 06492c598158cf825a18aececaf7511d7fd04f48..eef4d3c86a653f91b7221c80809ba8ab56f94cf1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 06492c598158cf825a18aececaf7511d7fd04f48
+Subproject commit eef4d3c86a653f91b7221c80809ba8ab56f94cf1
diff --git a/vg.h b/vg.h
index a89d750d80aaf9c7cbad96a188e08d85dcf38cd5..0be8031aec1d230718ef78a2cb3e9add81797c5a 100644 (file)
--- a/vg.h
+++ b/vg.h
@@ -122,7 +122,7 @@ VG_STATIC void vg_update_fixed(void);
 VG_STATIC void vg_update_post(void);
 
 VG_STATIC void vg_render(void);
-VG_STATIC void vg_ui(void);
+VG_STATIC void vg_gui(void);
 
 struct vg
 {
@@ -428,7 +428,7 @@ VG_STATIC void _vg_gameloop_render(void)
    vg.engine_stage = k_engine_stage_ui;
    {
       ui_prerender();
-      vg_ui();
+      vg_gui();
       ui_postrender();
 #if 0
       ui_begin( vg.window_x, vg.window_y );
@@ -477,7 +477,7 @@ VG_STATIC void _vg_gameloop_render(void)
 
       /* FIXME */
       audio_debug_ui( vg.pv );
-      vg_ui();
+      vg_gui();
       _vg_console_draw();
       
       ui_resolve();
index d843cdc6cfadfedc99bebf5da1201aaedd8c0120..deda2fce05ca1b2e955984c0516835c39632bc87 100644 (file)
@@ -18,7 +18,6 @@
 #include "vg/vg_shader.h"
 
 typedef i16                            ui_px;
-typedef u32                            ui_colour;
 typedef ui_px                          ui_rect[4];
 typedef struct ui_vert  ui_vert;
 
@@ -54,13 +53,43 @@ struct ui_vert
 };
 #pragma pack(pop)
 
-struct
-{
+enum ui_scheme_colour{
+   k_ui_bg      = 0,
+   k_ui_fg      = 8,
+   k_ui_hue     = 16,
+   k_ui_red     = 16,
+   k_ui_orange,
+   k_ui_yellow,
+   k_ui_green,
+   k_ui_aqua,
+   k_ui_blue,
+   k_ui_purple,
+   k_ui_gray,
+   k_ui_brighter = 8
+};
+
+typedef u32 ui_scheme[8*4];
+
+#define UI_RGB( STDHEX )          0xff000000       |\
+                         ((STDHEX&0x000000ff)<<16) |\
+                         ((STDHEX&0x0000ff00)    ) |\
+                         ((STDHEX&0x00ff0000)>>16) 
+
+struct{
    struct ui_vert *vertex_buffer;
    u16            *indice_buffer;
        u32 max_verts, max_indices, 
        cur_vert,  cur_indice,
        vert_start, indice_start;
+
+   void *focused_control_id; /* uses the memory location of various locking
+                                controls as an id */
+   u32 focused_control_hit;
+   enum ui_control_type{
+      k_ui_control_none,
+      k_ui_control_textbox,
+   }
+   focused_control_type;
        
        GLuint tex_glyphs, vao, vbo, ebo;
 
@@ -70,9 +99,48 @@ struct
 
    ui_rect click_fader;
    float click_fade_opacity;
+
+   ui_scheme scheme;
 } 
+static vg_ui = {
+   .scheme = {
+      [ k_ui_bg+0 ] = UI_RGB( 0x1d2021 ),
+      [ k_ui_bg+1 ] = UI_RGB( 0x282828 ),
+      [ k_ui_bg+2 ] = UI_RGB( 0x3c3836 ),
+      [ k_ui_bg+3 ] = UI_RGB( 0x504945 ),
+      [ k_ui_bg+4 ] = UI_RGB( 0x665c54 ),
+      [ k_ui_bg+5 ] = UI_RGB( 0x7c6f64 ),
+      [ k_ui_bg+6 ] = UI_RGB( 0x928374 ),
+      [ k_ui_bg+7 ] = UI_RGB( 0xa89984 ),
+
+      [ k_ui_fg+0 ] = UI_RGB( 0xebdbb2 ),
+      [ k_ui_fg+1 ] = UI_RGB( 0xfbf1c7 ),
+      [ k_ui_fg+2 ] = UI_RGB( 0xd5c4a1 ),
+      [ k_ui_fg+3 ] = UI_RGB( 0xbdae93 ),
+      [ k_ui_fg+4 ] = UI_RGB( 0xa89984 ),
+      [ k_ui_fg+5 ] = UI_RGB( 0x000000 ),
+      [ k_ui_fg+6 ] = UI_RGB( 0x000000 ),
+      [ k_ui_fg+7 ] = UI_RGB( 0x000000 ),
+
+      [ k_ui_red    ] = UI_RGB( 0xcc241d ),
+      [ k_ui_orange ] = UI_RGB( 0xd65d0e ),
+      [ k_ui_yellow ] = UI_RGB( 0xd79921 ),
+      [ k_ui_green  ] = UI_RGB( 0x98971a ),
+      [ k_ui_aqua   ] = UI_RGB( 0x689d6a ),
+      [ k_ui_blue   ] = UI_RGB( 0x458588 ),
+      [ k_ui_purple ] = UI_RGB( 0xb16286 ),
+      [ k_ui_gray   ] = UI_RGB( 0x928374 ),
+      [ k_ui_red    + k_ui_brighter ] = UI_RGB( 0xfb4934 ),
+      [ k_ui_orange + k_ui_brighter ] = UI_RGB( 0xfe8019 ),
+      [ k_ui_yellow + k_ui_brighter ] = UI_RGB( 0xfabd2f ),
+      [ k_ui_green  + k_ui_brighter ] = UI_RGB( 0xb8bb26 ),
+      [ k_ui_aqua   + k_ui_brighter ] = UI_RGB( 0x8ec07c ),
+      [ k_ui_blue   + k_ui_brighter ] = UI_RGB( 0x83a598 ),
+      [ k_ui_purple + k_ui_brighter ] = UI_RGB( 0xd3869b ),
+      [ k_ui_gray   + k_ui_brighter ] = UI_RGB( 0xa89984 ),
+   }
+};
 
-static vg_uictx;
 static struct vg_shader _shader_ui =
 {
    .name = "[vg] ui",
@@ -110,23 +178,24 @@ static struct vg_shader _shader_ui =
        "in vec4 aColour;"
        ""
        "in vec2 aWsp;"
+
+   "vec2 rand_hash22( vec2 p )"
+   "{"
+      "vec3 p3 = fract(vec3(p.xyx) * 213.8976123);"
+      "p3 += dot(p3, p3.yzx+19.19);"
+      "return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));"
+   "}"
        ""
        "void main()"
        "{"
-
-               "vec4 glyph = vec4(1.0,1.0,1.0,1.0);"
+               "vec4 diffuse = aColour;"
                
-               "if( aColour.a == 0.0 )"
+               "if( diffuse.a == 0.0 )"
                "{"
-                       "glyph = texture( uTexGlyphs, aTexCoords );"
-                       "glyph.a = smoothstep( 0.47, 0.53, glyph.r );"
-               "}"
-               "else"
-               "{"
-                       "glyph.a = aColour.a;"
+                       "diffuse.a = texture( uTexGlyphs, aTexCoords ).r;"
                "}"
                
-               "FragColor = vec4( aColour.rgb, glyph.a );"
+               "FragColor = diffuse;"
        "}"
    }
 };
@@ -198,25 +267,25 @@ VG_STATIC void _vg_ui_init(void)
     * ----------------------------------------
     */
 
-   vg_uictx.max_indices = 20000;
-   vg_uictx.max_verts = 30000;
+   vg_ui.max_indices = 20000;
+   vg_ui.max_verts = 30000;
        
        /* Generate the buffer we are gonna be drawing to */
-   glGenVertexArrays( 1, &vg_uictx.vao );
-   glGenBuffers( 1, &vg_uictx.vbo );
-   glGenBuffers( 1, &vg_uictx.ebo );
+   glGenVertexArrays( 1, &vg_ui.vao );
+   glGenBuffers( 1, &vg_ui.vbo );
+   glGenBuffers( 1, &vg_ui.ebo );
 
-   glBindVertexArray( vg_uictx.vao );
-   glBindBuffer( GL_ARRAY_BUFFER, vg_uictx.vbo );
+   glBindVertexArray( vg_ui.vao );
+   glBindBuffer( GL_ARRAY_BUFFER, vg_ui.vbo );
    
    glBufferData( GL_ARRAY_BUFFER, 
-         vg_uictx.max_verts * sizeof( struct ui_vert ), 
+         vg_ui.max_verts * sizeof( struct ui_vert ), 
          NULL, GL_DYNAMIC_DRAW );
-   glBindVertexArray( vg_uictx.vao );
+   glBindVertexArray( vg_ui.vao );
    
-   glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_uictx.ebo );
+   glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_ui.ebo );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, 
-         vg_uictx.max_indices * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW );
+         vg_ui.max_indices * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW );
 
    VG_CHECK_GL_ERR();
 
@@ -241,11 +310,11 @@ VG_STATIC void _vg_ui_init(void)
    VG_CHECK_GL_ERR();
 
        /* Alloc RAM default context */
-   u32 vert_size = vg_uictx.max_verts*sizeof(struct ui_vert),
-       inds_size = vg_align8( vg_uictx.max_indices*sizeof(u16) );
+   u32 vert_size = vg_ui.max_verts*sizeof(struct ui_vert),
+       inds_size = vg_align8( vg_ui.max_indices*sizeof(u16) );
    
-   vg_uictx.vertex_buffer = vg_linear_alloc( vg_mem.rtmemory, vert_size );
-   vg_uictx.indice_buffer = vg_linear_alloc( vg_mem.rtmemory, inds_size );
+   vg_ui.vertex_buffer = vg_linear_alloc( vg_mem.rtmemory, vert_size );
+   vg_ui.indice_buffer = vg_linear_alloc( vg_mem.rtmemory, inds_size );
 
    /* font
     * -----------------------------------------------------
@@ -271,8 +340,8 @@ VG_STATIC void _vg_ui_init(void)
       data++;
    }
    
-   glGenTextures( 1, &vg_uictx.tex_glyphs );
-   glBindTexture( GL_TEXTURE_2D, vg_uictx.tex_glyphs );
+   glGenTextures( 1, &vg_ui.tex_glyphs );
+   glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, 
                  GL_RED, GL_UNSIGNED_BYTE, image );
 
@@ -296,25 +365,25 @@ static void rect_copy( ui_rect a, ui_rect b )
 
 VG_STATIC void ui_flush( enum ui_shader shader )
 {
-   u32 vertex_offset = vg_uictx.vert_start*sizeof(ui_vert),
-       vertex_count  = vg_uictx.cur_vert-vg_uictx.vert_start,
+   u32 vertex_offset = vg_ui.vert_start*sizeof(ui_vert),
+       vertex_count  = vg_ui.cur_vert-vg_ui.vert_start,
        vertex_size   = vertex_count*sizeof(ui_vert),
 
-       indice_offset = vg_uictx.indice_start*sizeof(u16),
-       indice_count  = vg_uictx.cur_indice-vg_uictx.indice_start,
+       indice_offset = vg_ui.indice_start*sizeof(u16),
+       indice_count  = vg_ui.cur_indice-vg_ui.indice_start,
        indice_size   = indice_count * sizeof(u16);
 
    if( !vertex_size || !indice_size )
       return;
        
-       glBindVertexArray( vg_uictx.vao );
-       glBindBuffer( GL_ARRAY_BUFFER, vg_uictx.vbo );
+       glBindVertexArray( vg_ui.vao );
+       glBindBuffer( GL_ARRAY_BUFFER, vg_ui.vbo );
        glBufferSubData( GL_ARRAY_BUFFER, vertex_offset, vertex_size,
-                    vg_uictx.vertex_buffer+vg_uictx.vert_start );
+                    vg_ui.vertex_buffer+vg_ui.vert_start );
        
-       glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_uictx.ebo );
+       glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_ui.ebo );
        glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, indice_offset, indice_size,
-                    vg_uictx.indice_buffer+vg_uictx.indice_start );
+                    vg_ui.indice_buffer+vg_ui.indice_start );
        
        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@@ -332,7 +401,7 @@ VG_STATIC void ui_flush( enum ui_shader shader )
                           GL_FALSE, (float *)view );
        
       glActiveTexture( GL_TEXTURE0 );
-      glBindTexture( GL_TEXTURE_2D, vg_uictx.tex_glyphs );
+      glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs );
       glUniform1i( glGetUniformLocation( _shader_ui.id, "uTexGlyphs" ), 0 );
    }
    else if( shader == k_ui_shader_image ){
@@ -345,23 +414,23 @@ VG_STATIC void ui_flush( enum ui_shader shader )
       vg_fatal_error( "Invalid UI shader (%d)\n", shader );
        
        glDrawElements( GL_TRIANGLES, indice_count, GL_UNSIGNED_SHORT, 
-                   (void *)(vg_uictx.indice_start*sizeof(u16)) );
+                   (void *)(vg_ui.indice_start*sizeof(u16)) );
 
        glDisable( GL_BLEND );
 
-   vg_uictx.indice_start = vg_uictx.cur_indice;
-   vg_uictx.vert_start = vg_uictx.cur_vert;
+   vg_ui.indice_start = vg_ui.cur_indice;
+   vg_ui.vert_start = vg_ui.cur_vert;
 }
 
 static void ui_fill_rect( ui_rect rect, u32 colour, ui_px uv[4] )
 {
    /* this if far from ideal but stops us from crashing */
-   if( (vg_uictx.cur_vert + 4 > vg_uictx.max_verts) || 
-       (vg_uictx.cur_indice + 6 > vg_uictx.max_indices))
+   if( (vg_ui.cur_vert + 4 > vg_ui.max_verts) || 
+       (vg_ui.cur_indice + 6 > vg_ui.max_indices))
       return;
 
-   struct ui_vert *vertices = &vg_uictx.vertex_buffer[ vg_uictx.cur_vert ];
-       u16            *indices  = &vg_uictx.indice_buffer[ vg_uictx.cur_indice ];
+   struct ui_vert *vertices = &vg_ui.vertex_buffer[ vg_ui.cur_vert ];
+       u16            *indices  = &vg_ui.indice_buffer[ vg_ui.cur_indice ];
 
    for( int i=0; i<4; i++ ){
       vertices[i].colour = colour;
@@ -383,17 +452,17 @@ static void ui_fill_rect( ui_rect rect, u32 colour, ui_px uv[4] )
        vertices[3].co[1] = rect[1]+rect[3];
        vertices[3].uv[0] = uv[0];
        vertices[3].uv[1] = uv[3];
-       u16 ind_start = vg_uictx.cur_vert;
+       u16 ind_start = vg_ui.cur_vert;
        
-       u16 start = vg_uictx.cur_vert;
+       u16 start = vg_ui.cur_vert;
    u32 mesh[] = { 0,2,1, 0,3,2 };
 
    for( u32 i=0; i<vg_list_size(mesh); i++ ){
       indices[i] = start+mesh[i];
    }
 
-       vg_uictx.cur_indice += 6;
-       vg_uictx.cur_vert += 4;
+       vg_ui.cur_indice += 6;
+       vg_ui.cur_vert += 4;
 }
 
 static void ui_fill( ui_rect rect, u32 colour )
@@ -404,12 +473,12 @@ static void ui_fill( ui_rect rect, u32 colour )
 static void ui_outline( ui_rect rect, ui_px thickness, u32 colour )
 {
    /* this if far from ideal but stops us from crashing */
-   if( (vg_uictx.cur_vert + 8 > vg_uictx.max_verts) || 
-       (vg_uictx.cur_indice + 24 > vg_uictx.max_indices))
+   if( (vg_ui.cur_vert + 8 > vg_ui.max_verts) || 
+       (vg_ui.cur_indice + 24 > vg_ui.max_indices))
       return;
 
-   struct ui_vert *vertices = &vg_uictx.vertex_buffer[ vg_uictx.cur_vert ];
-       u16            *indices  = &vg_uictx.indice_buffer[ vg_uictx.cur_indice ];
+   struct ui_vert *vertices = &vg_ui.vertex_buffer[ vg_ui.cur_vert ];
+       u16            *indices  = &vg_ui.indice_buffer[ vg_ui.cur_indice ];
 
    for( int i=0; i<8; i++ ){
       vertices[i].uv[0] = 4;
@@ -434,15 +503,15 @@ static void ui_outline( ui_rect rect, ui_px thickness, u32 colour )
    vertices[7].co[0] = vertices[3].co[0]-thickness;
    vertices[7].co[1] = vertices[3].co[1]+thickness;
 
-       u16 start = vg_uictx.cur_vert;
+       u16 start = vg_ui.cur_vert;
    u32 mesh[] = { 0,5,4, 0,1,5, 1,6,5, 1,2,6, 2,7,6, 2,3,7, 3,4,7, 3,0,4 };
 
    for( u32 i=0; i<vg_list_size(mesh); i++ ){
       indices[i] = start+mesh[i];
    }
        
-       vg_uictx.cur_indice += 24;
-       vg_uictx.cur_vert += 8;
+       vg_ui.cur_indice += 24;
+       vg_ui.cur_vert += 8;
 }
 
 static void ui_split_px( ui_rect rect, 
@@ -591,10 +660,10 @@ static int ui_inside_rect( ui_rect rect, ui_px co[2] )
 
 static int ui_click_down(void)
 {
-   if( vg_uictx.ignore_input_frames ) return 0;
+   if( vg_ui.ignore_input_frames ) return 0;
 
-   if( (vg_uictx.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT)) &&
-      !(vg_uictx.mouse_state[1] & SDL_BUTTON(SDL_BUTTON_LEFT)) )
+   if( (vg_ui.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT)) &&
+      !(vg_ui.mouse_state[1] & SDL_BUTTON(SDL_BUTTON_LEFT)) )
       return 1;
    else
       return 0;
@@ -602,15 +671,15 @@ static int ui_click_down(void)
 
 static int ui_clicking(void)
 {
-   if( vg_uictx.ignore_input_frames ) return 0;
-   return vg_uictx.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT);
+   if( vg_ui.ignore_input_frames ) return 0;
+   return vg_ui.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT);
 }
 
 static int ui_click_up(void)
 {
-   if( vg_uictx.ignore_input_frames ) return 0;
-   if( (vg_uictx.mouse_state[1] & SDL_BUTTON(SDL_BUTTON_LEFT)) &&
-      !(vg_uictx.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT)) )
+   if( vg_ui.ignore_input_frames ) return 0;
+   if( (vg_ui.mouse_state[1] & SDL_BUTTON(SDL_BUTTON_LEFT)) &&
+      !(vg_ui.mouse_state[0] & SDL_BUTTON(SDL_BUTTON_LEFT)) )
       return 1;
    else
       return 0;
@@ -619,32 +688,38 @@ static int ui_click_up(void)
 static void ui_prerender(void)
 {
    int x, y;
-   vg_uictx.mouse_state[1] = vg_uictx.mouse_state[0];
-   vg_uictx.mouse_state[0] = SDL_GetMouseState( &x, &y );
-   vg_uictx.mouse[0] = x;
-   vg_uictx.mouse[1] = y;
-
-       vg_uictx.cur_vert = 0;
-       vg_uictx.cur_indice = 0;
-   vg_uictx.vert_start = 0;
-   vg_uictx.indice_start = 0;
-
-   if( vg_uictx.ignore_input_frames ){
-      vg_uictx.ignore_input_frames --;
+   vg_ui.mouse_state[1] = vg_ui.mouse_state[0];
+   vg_ui.mouse_state[0] = SDL_GetMouseState( &x, &y );
+   vg_ui.mouse[0] = x;
+   vg_ui.mouse[1] = y;
+
+       vg_ui.cur_vert = 0;
+       vg_ui.cur_indice = 0;
+   vg_ui.vert_start = 0;
+   vg_ui.indice_start = 0;
+   vg_ui.focused_control_hit = 0;
+
+   if( vg_ui.ignore_input_frames ){
+      vg_ui.ignore_input_frames --;
       return;
    }
 
    if( ui_click_down() ){
-      vg_uictx.mouse_click[0] = vg_uictx.mouse[0];
-      vg_uictx.mouse_click[1] = vg_uictx.mouse[1];
+      vg_ui.mouse_click[0] = vg_ui.mouse[0];
+      vg_ui.mouse_click[1] = vg_ui.mouse[1];
    }
 }
 
+static u32 ui_colour( enum ui_scheme_colour id )
+{
+   return vg_ui.scheme[ id ];
+}
+
 static void ui_text( ui_rect rect, const char *str, ui_px scale, 
                         enum ui_align align )
 {
        ui_rect text_cursor;
-       u32 current_colour = 0x00ffffff;
+       u32 colour = ui_colour( k_ui_fg ) & 0x00ffffff;
        
    const char *_c = str;
        u8 c;
@@ -681,7 +756,7 @@ static void ui_text( ui_rect rect, const char *str, ui_px scale,
          ui_rect rect_char;
 
          if( ui_clip( rect, text_cursor, rect_char ) ){
-            ui_fill_rect( rect_char, current_colour, (ui_px[4])
+            ui_fill_rect( rect_char, colour, (ui_px[4])
             {
                glyph_base[0]+2,
                glyph_base[1]+1,
@@ -700,16 +775,18 @@ static void ui_text( ui_rect rect, const char *str, ui_px scale,
                                                _c = _c + i + 1;
                                                
                                                switch( colour_id ){
-                                                       case '0':        current_colour = 0x00ffffff; break;
-                                                       case '3'|'1'<<8: current_colour = 0x00201fee; break;
-                                                       case '3'|'2'<<8: current_colour = 0x0037e420; break;
-                                                       case '3'|'3'<<8: current_colour = 0x000ed8e2; break;
-                                                       case '3'|'4'<<8: current_colour = 0x00f15010; break;
-                                                       case '3'|'5'<<8: current_colour = 0x00ee20ee; break;
-                                                       case '3'|'6'<<8: current_colour = 0x00eeee20; break;
-                                                       case '3'|'7'<<8: current_colour = 0x00ffffff; break;
+                   case '0':        colour = ui_colour( k_ui_fg ); break;
+                   case '3'|'0'<<8: colour = ui_colour( k_ui_bg ); break;
+                   case '3'|'1'<<8: colour = ui_colour( k_ui_red ); break;
+                   case '3'|'2'<<8: colour = ui_colour( k_ui_green ); break;
+                   case '3'|'3'<<8: colour = ui_colour( k_ui_yellow ); break;
+                   case '3'|'4'<<8: colour = ui_colour( k_ui_blue ); break;
+                   case '3'|'5'<<8: colour = ui_colour( k_ui_purple ); break;
+                   case '3'|'6'<<8: colour = ui_colour( k_ui_aqua ); break;
+                   case '3'|'7'<<8: colour = ui_colour( 0xffffffff ); break;
                                                }
-                                               
+
+                  colour &= 0x00ffffff;
                                                break;
                                        }
                                        
@@ -752,55 +829,69 @@ static u32 v4f_u32_colour( v4f colour )
    return r | (g<<8) | (b<<16) | (a<<24);
 }
 
-static int ui_button( ui_rect rect, v4f colour )
+static void ui_defocus_all(void)
+{
+   if( vg_ui.focused_control_type == k_ui_control_textbox ){
+      SDL_StopTextInput();
+   }
+
+   vg_ui.focused_control_id = NULL;
+   vg_ui.focused_control_hit = 0;
+   vg_ui.focused_control_type = k_ui_control_none;
+}
+
+static int ui_button( ui_rect rect, enum ui_scheme_colour colour )
 {
    int clickup= ui_click_up(),
        click  = ui_clicking() | clickup,
-       target = ui_inside_rect( rect, vg_uictx.mouse_click ) && click,
-       hover  = ui_inside_rect( rect, vg_uictx.mouse );
+       target = ui_inside_rect( rect, vg_ui.mouse_click ) && click,
+       hover  = ui_inside_rect( rect, vg_ui.mouse );
 
-   u32 basecolour = v4f_u32_colour( colour );
+   u32 col_base      = vg_ui.scheme[ colour ],
+       col_highlight = vg_ui.scheme[ k_ui_fg ],
+       col_hover     = vg_ui.scheme[ colour + k_ui_brighter ];
 
    if( click ){
       if( target ){
          if( hover ){
             if( clickup ){
-               ui_fill( rect, 0xffffffff );
-               vg_uictx.ignore_input_frames = 2;
-               rect_copy( rect, vg_uictx.click_fader );
-               vg_uictx.click_fade_opacity = 1.0f;
+               ui_fill( rect, col_highlight );
+               vg_ui.ignore_input_frames = 2;
+               rect_copy( rect, vg_ui.click_fader );
+               vg_ui.click_fade_opacity = 1.0f;
+               ui_defocus_all();
                return 1;
             }
             else{
-               ui_fill( rect, 0xffcccccc );
+               ui_fill( rect, col_highlight );
                return 0;
             }
          }
          else{
-            ui_fill( rect, 0xff505050 );
-            ui_outline( rect, 1, 0xffffffff );
+            ui_fill( rect, col_base );
+            ui_outline( rect, 1, col_highlight );
             return 0;
          }
       }
       else{
-         ui_fill( rect, 0xff505050 );
+         ui_fill( rect, col_base );
          return 0;
       }
    }
    else{
       if( hover ){
-         ui_fill( rect, 0xffa0a0a0 );
+         ui_fill( rect, col_hover );
          return 0;
       }
       else{
-         ui_fill( rect, 0xff505050 );
+         ui_fill( rect, col_base );
          return 0;
       }
    }
 }
 
 static int ui_button_text( ui_rect rect, const char *string, ui_px scale,
-                           v4f colour )
+                           enum ui_scheme_colour colour )
 {
    int result = ui_button( rect, colour );
    ui_rect t = { 0,0, ui_text_line_width( string )*scale, 14*scale };
@@ -811,22 +902,82 @@ static int ui_button_text( ui_rect rect, const char *string, ui_px scale,
 
 static void ui_postrender(void)
 {
-   if( vg_uictx.click_fade_opacity > 0.0f ){
+   if( vg_ui.click_fade_opacity > 0.0f ){
 
-      float scale = vg_uictx.click_fade_opacity;
+      float scale = vg_ui.click_fade_opacity;
             scale = vg_maxf( 1.0f/255.0f, scale*scale );
 
-      vg_uictx.click_fade_opacity -= vg.time_frame_delta * 1.8f;
+      vg_ui.click_fade_opacity -= vg.time_frame_delta * 1.8f;
       u32 colour = v4f_u32_colour( (v4f){ 1.0f,1.0f,1.0f, scale } );
 
       ui_rect rect;
-      rect[3] = (float)(vg_uictx.click_fader[3]) * scale;
-      rect[2] = vg_uictx.click_fader[2];
-      ui_rect_center( vg_uictx.click_fader, rect );
+      rect[3] = (float)(vg_ui.click_fader[3]) * scale;
+      rect[2] = vg_ui.click_fader[2];
+      ui_rect_center( vg_ui.click_fader, rect );
 
       ui_fill( rect, colour );
    }
    ui_flush( k_ui_shader_colour );
+
+   if( !vg_ui.focused_control_hit ){
+      ui_defocus_all();
+   }
+}
+
+static int ui_textbox( ui_rect rect, char *buf, u32 len )
+{
+   int clickup= ui_click_up(),
+       click  = ui_clicking() | clickup,
+       target = ui_inside_rect( rect, vg_ui.mouse_click ) && click,
+       hover  = ui_inside_rect( rect, vg_ui.mouse );
+
+   u32 col_base      = vg_ui.scheme[ k_ui_bg ],
+       col_highlight = vg_ui.scheme[ k_ui_fg ];
+
+   ui_px border = -1;
+
+   if( vg_ui.focused_control_id == buf ){
+      ui_fill( rect, col_base );
+      ui_outline( rect, -2, vg_ui.scheme[ k_ui_orange ] );
+      vg_ui.focused_control_hit = 1;
+      return 0;
+   }
+
+   if( click ){
+      if( target ){
+         if( hover ){
+            if( clickup ){
+               ui_fill( rect, col_highlight );
+               vg_ui.ignore_input_frames = 2;
+               rect_copy( rect, vg_ui.click_fader );
+               vg_ui.click_fade_opacity = 1.0f;
+               vg_ui.focused_control_id = buf;
+               vg_ui.focused_control_hit = 1;
+               vg_ui.focused_control_type = k_ui_control_textbox;
+               SDL_StartTextInput();
+            }
+            else{
+               ui_fill( rect, col_highlight );
+            }
+         }
+         else{
+            ui_fill( rect, col_base );
+            ui_outline( rect, -1, col_highlight );
+         }
+      }
+      else{
+         ui_fill( rect, col_base );
+      }
+   }
+   else{
+      ui_fill( rect, col_base );
+
+      if( hover ){
+         ui_outline( rect, -1, col_highlight );
+      }
+   }
+
+   return 0;
 }
 
 #endif /* VG_IMGUI_H */
index 04390697f06be444833a5574651c43ef41674ab1..cc42761b69e7dd5777e60765f47d7cfaac669e6c 100644 (file)
--- a/vg_log.h
+++ b/vg_log.h
@@ -8,6 +8,7 @@
 #include "vg_platform.h"
 
 #define KNRM  "\x1B[0m"
+#define KBLK  "\x1B[30m"
 #define KRED  "\x1B[31m"
 #define KGRN  "\x1B[32m"
 #define KYEL  "\x1B[33m"