added basic button function
authorhgn <hgodden00@gmail.com>
Tue, 12 Oct 2021 15:57:32 +0000 (16:57 +0100)
committerhgn <hgodden00@gmail.com>
Tue, 12 Oct 2021 15:57:32 +0000 (16:57 +0100)
vg/vg_ui.h

index 27c0645cacf05236c6e3b5ca942a310d5c51ee5f..9758d9840c4add9c0fd524b4b3a056730a0aa36a 100644 (file)
@@ -37,6 +37,8 @@ struct ui_ctx
        ui_rect cursor;
        u32 stack_count;
        u32 capture_mouse_id;
+       int capture_lock;
+       u32 id_base;
        
        // User input
        ui_px mouse[2];
@@ -54,12 +56,12 @@ static void ui_rect_copy( ui_rect src, ui_rect dst )
        dst[3] = src[3];
 }
 
-static void ui_rect_pad( ui_ctx *ctx, ui_rect rect )
+static void ui_rect_pad( ui_ctx *ctx, ui_rect rect, ui_px pad )
 {
-       rect[0] += ctx->padding;
-       rect[1] += ctx->padding;
-       rect[2] -= ctx->padding*2;
-       rect[3] -= ctx->padding*2;
+       rect[0] += pad;
+       rect[1] += pad;
+       rect[2] -= pad*2;
+       rect[3] -= pad*2;
 }
 
 static void ui_vis_rect( ui_rect rect, u32 colour )
@@ -95,6 +97,10 @@ static void ui_new_node( ui_ctx *ctx )
                else
                        node->mouse_over = 0;
        }
+       else
+       {
+               node->mouse_over = 0;
+       }
 }
 
 static int ui_hasmouse( ui_ctx *ctx )
@@ -125,14 +131,35 @@ static void ui_end_right( ui_ctx *ctx )
        ctx->cursor[0] += width;
 }
 
-static void ui_capture_mouse( ui_ctx *ctx, int id )
+static void ui_align_right( ui_ctx *ctx )
+{
+       struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];
+       ctx->cursor[0] = node->rect[0] + node->rect[2] - ctx->cursor[2];
+}
+
+static void ui_clamp_rect( ui_rect parent, ui_rect dest )
+{
+       dest[0] = vg_min( parent[0] + parent[2] - dest[2], dest[0] );
+       dest[1] = vg_min( parent[1] + parent[3] - dest[3], dest[1] );
+       dest[0] = vg_max( parent[0], dest[0] );
+       dest[1] = vg_max( parent[1], dest[1] );
+}
+
+static u32 ui_group_id( ui_ctx *ctx, u32 lesser_unique )
+{
+       return ctx->id_base | lesser_unique;
+}
+
+static void ui_capture_mouse( ui_ctx *ctx, u32 id )
 {
+       u32 group_uid = ui_group_id(ctx,id);
+
        struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];
-       node->capture_id = id;
+       node->capture_id = group_uid;
        
-       if( node->mouse_over )
+       if( !ctx->capture_lock && node->mouse_over )
        {
-               ctx->capture_mouse_id = id;
+               ctx->capture_mouse_id = group_uid;
        }
 }
 
@@ -156,6 +183,11 @@ static void ui_resolve( ui_ctx *ctx )
 {
        if( ctx->stack_count-1 )
                vg_exiterr( "[UI] Mismatched node create/drestroy!" );
+       
+       if( ctx->click_state == 3 || ctx->click_state == 0 )
+       {
+               ctx->capture_lock = 0;
+       }
 }
 
 // User Input piping
@@ -169,6 +201,97 @@ static void ui_set_mouse( ui_ctx *ctx, int x, int y, int click_state )
        ctx->click_state = click_state;
 }
 
+// High level controls
+// ====================================================================
+
+struct ui_window
+{
+       const char *title;
+       ui_rect transform;
+       
+       int     drag;
+       ui_px drag_offset[2];
+};
+
+static int ui_button( ui_ctx *ctx, u32 id )
+{
+       ui_new_node( ctx );
+       {
+               ui_capture_mouse( ctx, id );
+               
+               if( ui_hasmouse(ctx) )
+               {
+                       if( ctx->click_state == 1 )
+                               ctx->capture_lock = 1;
+                       else if( ctx->capture_lock && ctx->click_state == 3 )
+                       {
+                               return 1;
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group )
+{
+       ctx->id_base = control_group << 16;
+
+       if( window->drag )
+       {
+               window->transform[0] = ctx->mouse[0]+window->drag_offset[0];
+               window->transform[1] = ctx->mouse[1]+window->drag_offset[1];
+               
+               ui_clamp_rect( ctx->stack[0].rect, window->transform );
+               
+               if( ctx->click_state == 0 || ctx->click_state == 3 )
+               {
+                       window->drag = 0;
+               }
+       }
+       
+       ui_rect_copy( window->transform, ctx->cursor );
+       
+       ui_new_node( ctx );
+       {
+               ui_capture_mouse( ctx, __COUNTER__ );
+
+               // Drag bar
+               ctx->cursor[3] = 25;            
+               ui_new_node( ctx );
+               {
+                       ui_capture_mouse( ctx, __COUNTER__ );
+                       
+                       // title..
+                       
+                       // Close button
+                       ctx->cursor[2] = 25;
+                       ui_align_right( ctx );
+                       ui_rect_pad( ctx, ctx->cursor, 4 );
+                       
+                       if( ui_button( ctx, __COUNTER__ ) )
+                       {
+                               vg_info( "Click clacked\n" );
+                       }
+                       ui_end( ctx );
+                       
+                       if( ui_hasmouse( ctx ) )
+                       {
+                               // start drag
+                               if( ctx->click_state == 1 )
+                               {
+                                       window->drag = 1;
+                                       window->drag_offset[0] = window->transform[0]-ctx->mouse[0];
+                                       window->drag_offset[1] = window->transform[1]-ctx->mouse[1];
+                               }
+                       }
+               }
+               ui_end( ctx );
+       }
+       
+       return 1;
+}
+
 static void ui_test(void)
 {
        /*
@@ -189,7 +312,7 @@ static void ui_test(void)
                +------+--------------+-+----------------------------+-+
        */
        
-       ui_ctx ctx = { .padding = 8 };
+       static ui_ctx ctx = { .padding = 8 };
        
        ui_begin( &ctx, vg_window_x, vg_window_y );
        
@@ -201,54 +324,18 @@ static void ui_test(void)
                
        ui_set_mouse( &ctx, vg_mouse[0], vg_mouse[1], mouse_state );
        
-       static ui_px window_x = 20;
-       static ui_px window_y = 20;
-       static int window_drag = 0;
-       static ui_px drag_offset[2];
-
-       if( window_drag )
+       static struct ui_window window =
        {
-               window_x = ctx.mouse[0]+drag_offset[0];
-               window_y = ctx.mouse[1]+drag_offset[1];
-               
-               if( ctx.click_state == 0 )
-               {
-                       window_drag = 0;
-               }
-       }
-       
-       ctx.cursor[0] = window_x;
-       ctx.cursor[1] = window_y;
-       ctx.cursor[2] = 500;
-       ctx.cursor[3] = 350;
+               .transform = { 20, 20, 500, 350 },
+               .title = "Central Market"
+       };
        
-       ui_new_node( &ctx );
+       if( ui_window( &ctx, &window, __COUNTER__ ) )
        {
-               ctx.cursor[0] += 20;
-               ctx.cursor[1] += 20;
-               ctx.cursor[2] = 150;
-               ctx.cursor[3] = 25;
-               
-               ui_capture_mouse( &ctx, 1 );
-               
-               ui_new_node( &ctx );
-               {
-                       ui_capture_mouse( &ctx, 2 );
-                       
-                       if( ui_hasmouse( &ctx ) )
-                       {
-                               if( ctx.click_state == 1 ) // start drag
-                               {
-                                       window_drag = 1;
-                                       drag_offset[0] = window_x-ctx.mouse[0];
-                                       drag_offset[1] = window_y-ctx.mouse[1];
-                               }
-                       }
-               }
-               ui_end( &ctx );
+               // Contents
        }
        ui_end( &ctx );
-       
+
        ui_resolve( &ctx );
        
        m3x3f view = M3X3_IDENTITY;