ui_rect cursor;
u32 stack_count;
u32 capture_mouse_id;
+ int capture_lock;
+ u32 id_base;
// User input
ui_px mouse[2];
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 )
else
node->mouse_over = 0;
}
+ else
+ {
+ node->mouse_over = 0;
+ }
}
static int ui_hasmouse( 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;
}
}
{
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
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)
{
/*
+------+--------------+-+----------------------------+-+
*/
- ui_ctx ctx = { .padding = 8 };
+ static ui_ctx ctx = { .padding = 8 };
ui_begin( &ctx, vg_window_x, vg_window_y );
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;