1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
3 SHADER_DEFINE( shader_ui
,
6 "layout (location=0) in vec2 a_co;" // i16, i16, .. ?
7 "layout (location=1) in vec2 a_uv;" // i16, i16
8 "layout (location=2) in vec4 a_colour;" // u32
9 "layout (location=3) in vec4 a_clip;" // i16, i16, i16, i16
12 "out vec2 aTexCoords;"
19 "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
20 "aTexCoords = a_uv * 0.0078125;"
28 "uniform sampler2D uTexGlyphs;"
39 "float clip_blend = step( aWsp.x, aClip.z ) * step( aWsp.y, aClip.w ) * step( aClip.x, aWsp.x ) * step( aClip.y, aWsp.y );"
40 "vec4 glyph = vec4(1.0,1.0,1.0,1.0);"
42 "if( aColour.a == 0.0 )"
44 "glyph = texture( uTexGlyphs, aTexCoords );"
45 "glyph.a = smoothstep( 0.47, 0.53, glyph.r );"
49 "glyph.a = aColour.a;"
52 "FragColor = vec4( aColour.rgb, glyph.a*clip_blend );"
55 UNIFORMS({ "uPv", "uTexGlyphs" })
59 // ===========================================================================================================
62 typedef u32 ui_colour
;
63 typedef ui_px ui_rect
[4];
64 typedef struct ui_ctx ui_ctx
;
65 typedef struct ui_colourset ui_colourset
;
67 // Relative to cursor p0
70 k_text_align_left
= 0,
71 k_text_align_right
= 1,
72 k_text_align_center
= 2
123 u32 capture_mouse_id
;
130 int click_state
; // 0: released, 1: on down, 2: pressed, 3: on release
132 ui_colourset
*colours
;
148 // ===========================================================================================================
150 #define UI_GLYPH_SPACING_X 9
152 static GLuint ui_glyph_texture
= 0;
153 static ui_colourset ui_default_colours
= {
159 static ui_ctx ui_global_ctx
;
162 // ===========================================================================================================
164 static void ui_init_context( ui_ctx
*ctx
, int index_buffer_size
)
166 u32 vertex_buffer_size
= (index_buffer_size
+(index_buffer_size
/2));
168 // Generate the buffer we are gonna be drawing to
170 glGenVertexArrays(1, &ctx
->vao
);
171 glGenBuffers( 1, &ctx
->vbo
);
172 glGenBuffers( 1, &ctx
->ebo
);
173 glBindVertexArray( ctx
->vao
);
175 glBindBuffer( GL_ARRAY_BUFFER
, ctx
->vbo
);
177 glBufferData( GL_ARRAY_BUFFER
, vertex_buffer_size
* sizeof( struct ui_vert
), NULL
, GL_DYNAMIC_DRAW
);
178 glBindVertexArray( ctx
->vao
);
180 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER
, ctx
->ebo
);
181 glBufferData( GL_ELEMENT_ARRAY_BUFFER
, index_buffer_size
* sizeof( u16
), NULL
, GL_DYNAMIC_DRAW
);
183 u32
const stride
= sizeof( struct ui_vert
);
186 glVertexAttribPointer( 0, 2, GL_SHORT
, GL_FALSE
, stride
, (void *)offsetof( struct ui_vert
, co
) );
187 glEnableVertexAttribArray( 0 );
190 glVertexAttribPointer( 1, 2, GL_UNSIGNED_BYTE
, GL_FALSE
, stride
, (void *)offsetof( struct ui_vert
, uv
) );
191 glEnableVertexAttribArray( 1 );
194 glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE
, GL_TRUE
, stride
, (void *)offsetof( struct ui_vert
, colour
) );
195 glEnableVertexAttribArray( 2 );
198 glVertexAttribPointer( 3, 4, GL_SHORT
, GL_FALSE
, stride
, (void *)offsetof( struct ui_vert
, clip
) );
199 glEnableVertexAttribArray( 3 );
202 // Initialize default context
204 ctx
->verts
= (struct ui_vert
*)malloc( vertex_buffer_size
* sizeof(struct ui_vert
) );
205 ctx
->indices
= (u16
*)malloc( index_buffer_size
* sizeof(u16
) );
208 ctx
->colours
= &ui_default_colours
;
212 static void ui_context_free( ui_ctx
*ctx
)
214 glDeleteVertexArrays( 1, &ctx
->vao
);
215 glDeleteBuffers( 1, &ctx
->vbo
);
216 glDeleteBuffers( 1, &ctx
->ebo
);
219 free( ctx
->indices
);
222 static void ui_default_init(void)
226 #include "vg/vg_pxfont.h"
229 u32 pixels
= 0, total
= 256*256, data
= 0;
230 u8
*image
= malloc( total
);
232 while( pixels
< total
)
234 for( int b
= 31; b
>= 0; b
-- )
236 image
[ pixels
++ ] = (compressed
[data
] & (0x1 << b
))? 0xff: 0x00;
238 if( pixels
>= total
)
247 glGenTextures( 1, &ui_glyph_texture
);
248 glBindTexture( GL_TEXTURE_2D
, ui_glyph_texture
);
250 glTexImage2D( GL_TEXTURE_2D
, 0, GL_R8
, 256, 256, 0, GL_RED
, GL_UNSIGNED_BYTE
, image
);
257 // Setup OpenGL memory
258 SHADER_INIT( shader_ui
);
259 ui_init_context( &ui_global_ctx
, 20000 );
262 static void ui_default_free(void)
264 glDeleteTextures( 1, &ui_glyph_texture
);
265 ui_context_free( &ui_global_ctx
);
268 static struct ui_vert
*ui_fill_rect_uv( ui_ctx
*ctx
, ui_rect rect
, u32 colour
, ui_px uv
[4] );
269 static void ui_draw( ui_ctx
*ctx
, m3x3f view_override
)
271 u32 num_indices_normal
= ctx
->num_indices
;
273 // Append images to back of buffer
274 for( int i
= 0; i
< ctx
->image_count
; i
++ )
275 ui_fill_rect_uv( ctx
, ctx
->images
[i
].rc
, 0xffffffff, (ui_px
[4]){0,0,128,128} );
277 glBindVertexArray( ctx
->vao
);
279 glBindBuffer( GL_ARRAY_BUFFER
, ctx
->vbo
);
280 glBufferSubData( GL_ARRAY_BUFFER
, 0, ctx
->num_verts
* sizeof( struct ui_vert
), ctx
->verts
);
282 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER
, ctx
->ebo
);
283 glBufferSubData( GL_ELEMENT_ARRAY_BUFFER
, 0, ctx
->num_indices
* sizeof( u16
), ctx
->indices
);
286 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
287 glBlendEquation(GL_FUNC_ADD
);
289 SHADER_USE( shader_ui
);
291 m3x3f view
= M3X3_IDENTITY
;
295 view_override
= view
;
297 m3x3_translate( view
, (v3f
){ -1.0f
, 1.0f
, 0.0f
} );
298 m3x3_scale( view
, (v3f
){ 1.0f
/((float)vg_window_x
*0.5f
), -1.0f
/((float)vg_window_y
*0.5f
), 1.0f
} );
301 glUniformMatrix3fv( SHADER_UNIFORM( shader_ui
, "uPv" ), 1, GL_FALSE
, (float *)view_override
);
303 glActiveTexture( GL_TEXTURE0
);
304 glBindTexture( GL_TEXTURE_2D
, ui_glyph_texture
);
305 glUniform1i( SHADER_UNIFORM( shader_ui
, "uTexGlyphs" ), 0 );
307 glDrawElements( GL_TRIANGLES
, num_indices_normal
, GL_UNSIGNED_SHORT
, (void*)(0) );
309 // Draw image elements
310 for( int i
= 0; i
< ctx
->image_count
; i
++ )
312 struct ui_image
*img
= &ctx
->images
[i
];
314 glBindTexture( GL_TEXTURE_2D
, img
->image
);
315 glDrawElements( GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, (void*)( (num_indices_normal
+ 6*i
)*sizeof(u16
) ) );
322 // ===========================================================================================================
324 static void ui_rect_copy( ui_rect src
, ui_rect dst
)
332 static void ui_rect_pad( ui_rect rect
, ui_px pad
)
341 // ===========================================================================================================
343 static struct ui_qnode
*ui_current( ui_ctx
*ctx
)
345 return &ctx
->stack
[ ctx
->stack_count
-1 ];
348 static void ui_new_node( ui_ctx
*ctx
)
350 if( ctx
->stack_count
== vg_list_size( ctx
->stack
) )
351 vg_exiterr( "[UI] Stack overflow while creating box!" );
353 struct ui_qnode
*parent
= &ctx
->stack
[ ctx
->stack_count
-1 ];
354 struct ui_qnode
*node
= &ctx
->stack
[ ctx
->stack_count
++ ];
355 ui_rect_copy( ctx
->cursor
, node
->rect
);
357 if( parent
->mouse_over
)
359 if( ctx
->mouse
[0] >= node
->rect
[0] && ctx
->mouse
[0] < node
->rect
[0]+node
->rect
[2] &&
360 ctx
->mouse
[1] >= node
->rect
[1] && ctx
->mouse
[1] < node
->rect
[1]+node
->rect
[3] )
361 node
->mouse_over
= 1;
363 node
->mouse_over
= 0;
367 node
->mouse_over
= 0;
371 static int ui_hasmouse( ui_ctx
*ctx
)
373 struct ui_qnode
*node
= ui_current( ctx
);
374 return (node
->mouse_over
&& (node
->capture_id
== ctx
->capture_mouse_id
));
377 static void ui_end( ui_ctx
*ctx
)
379 struct ui_qnode
*node
= &ctx
->stack
[ --ctx
->stack_count
];
380 ui_rect_copy( node
->rect
, ctx
->cursor
);
383 static void ui_end_down( ui_ctx
*ctx
)
385 ui_px height
= ui_current( ctx
)->rect
[3];
387 ctx
->cursor
[1] += height
;
390 static void ui_end_right( ui_ctx
*ctx
)
392 ui_px width
= ui_current( ctx
)->rect
[2];
394 ctx
->cursor
[0] += width
;
397 static void ui_fill_y( ui_ctx
*ctx
)
399 struct ui_qnode
*node
= ui_current( ctx
);
400 ctx
->cursor
[3] = node
->rect
[3] - (ctx
->cursor
[1]-node
->rect
[1]);
403 static void ui_fill_x( ui_ctx
*ctx
)
405 struct ui_qnode
*node
= ui_current( ctx
);
406 ctx
->cursor
[2] = node
->rect
[2] - (ctx
->cursor
[0]-node
->rect
[0]);
409 // Alignment: | [] | -> | []|
410 static void ui_align_bottom( ui_ctx
*ctx
)
412 struct ui_qnode
*node
= ui_current( ctx
);
413 ctx
->cursor
[1] = node
->rect
[1] + node
->rect
[3] - ctx
->cursor
[3];
416 static void ui_align_right( ui_ctx
*ctx
)
418 struct ui_qnode
*node
= ui_current( ctx
);
419 ctx
->cursor
[0] = node
->rect
[0] + node
->rect
[2] - ctx
->cursor
[2];
422 static void ui_align_top( ui_ctx
*ctx
)
424 ctx
->cursor
[1] = ui_current( ctx
)->rect
[1];
427 static void ui_align_left( ui_ctx
*ctx
)
429 ctx
->cursor
[0] = ui_current( ctx
)->rect
[0];
432 static void ui_clamp_rect( ui_rect parent
, ui_rect dest
)
434 dest
[0] = vg_min( parent
[0] + parent
[2] - dest
[2], dest
[0] );
435 dest
[1] = vg_min( parent
[1] + parent
[3] - dest
[3], dest
[1] );
436 dest
[0] = vg_max( parent
[0], dest
[0] );
437 dest
[1] = vg_max( parent
[1], dest
[1] );
440 static u32
ui_group_id( ui_ctx
*ctx
, u32 lesser_unique
)
442 return ctx
->id_base
| lesser_unique
;
445 static void ui_capture_mouse( ui_ctx
*ctx
, u32 id
)
447 u32 group_uid
= ui_group_id(ctx
,id
);
449 struct ui_qnode
*node
= &ctx
->stack
[ ctx
->stack_count
-1 ];
450 node
->capture_id
= group_uid
;
452 if( !ctx
->capture_lock
&& node
->mouse_over
)
454 ctx
->capture_mouse_id
= group_uid
;
458 static int ui_want_mouse( ui_ctx
*ctx
)
460 return ctx
->capture_mouse_id
== 0? 0: 1;
463 static void ui_set_clip( ui_ctx
*ctx
, ui_rect clip
)
465 ctx
->clipping
[0] = clip
[0];
466 ctx
->clipping
[1] = clip
[1];
467 ctx
->clipping
[2] = clip
[0] + clip
[2];
468 ctx
->clipping
[3] = clip
[1] + clip
[3];
471 static void ui_release_clip( ui_ctx
*ctx
)
473 ctx
->clipping
[0] = -32000;
474 ctx
->clipping
[1] = -32000;
475 ctx
->clipping
[2] = 32000;
476 ctx
->clipping
[3] = 32000;
480 // ===========================================================================================================
482 static struct ui_vert
*ui_fill_rect_uv( ui_ctx
*ctx
, ui_rect rect
, u32 colour
, ui_px uv
[4] )
484 struct ui_vert
*vertices
= &ctx
->verts
[ ctx
->num_verts
];
485 vertices
[0].co
[0] = rect
[0];
486 vertices
[0].co
[1] = rect
[1];
487 vertices
[0].uv
[0] = uv
[0];
488 vertices
[0].uv
[1] = uv
[1];
489 vertices
[0].colour
= colour
;
490 vertices
[1].co
[0] = rect
[0]+rect
[2];
491 vertices
[1].co
[1] = rect
[1];
492 vertices
[1].uv
[0] = uv
[2];
493 vertices
[1].uv
[1] = uv
[1];
494 vertices
[1].colour
= colour
;
495 vertices
[2].co
[0] = rect
[0]+rect
[2];
496 vertices
[2].co
[1] = rect
[1]+rect
[3];
497 vertices
[2].uv
[0] = uv
[2];
498 vertices
[2].uv
[1] = uv
[3];
499 vertices
[2].colour
= colour
;
500 vertices
[3].co
[0] = rect
[0];
501 vertices
[3].co
[1] = rect
[1]+rect
[3];
502 vertices
[3].uv
[0] = uv
[0];
503 vertices
[3].uv
[1] = uv
[3];
504 vertices
[3].colour
= colour
;
505 u16 ind_start
= ctx
->num_verts
;
506 u16
*indices
= &ctx
->indices
[ ctx
->num_indices
];
508 ui_rect_copy( ctx
->clipping
, vertices
[0].clip
);
509 ui_rect_copy( ctx
->clipping
, vertices
[1].clip
);
510 ui_rect_copy( ctx
->clipping
, vertices
[2].clip
);
511 ui_rect_copy( ctx
->clipping
, vertices
[3].clip
);
513 indices
[0] = ind_start
+0;
514 indices
[1] = ind_start
+2;
515 indices
[2] = ind_start
+1;
517 indices
[3] = ind_start
+0;
518 indices
[4] = ind_start
+3;
519 indices
[5] = ind_start
+2;
521 ctx
->num_indices
+= 6;
527 static struct ui_vert
*ui_fill_rect( ui_ctx
*ctx
, ui_rect rect
, u32 colour
)
529 return ui_fill_rect_uv( ctx
, rect
, colour
, (ui_px
[4]){ 4,4, 4,4 } );
532 static ui_px
ui_text_line_offset( const char *str
, ui_px scale
, enum ui_text_align align
)
534 if( align
== k_text_align_left
)
538 const char *_c
= str
;
541 while( (c
= *(_c
++)) )
542 if( c
>= 32 && c
<= 126 )
547 if( align
== k_text_align_right
)
548 return -length
* scale
*8;
550 return (-length
* scale
*8) / 2;
553 static void ui_text( ui_ctx
*ctx
, ui_px pos
[2], const char *str
, ui_px scale
, enum ui_text_align align
)
556 u32 current_colour
= 0x00ffffff;
558 const char *_c
= str
;
561 text_cursor
[0] = pos
[0] + ui_text_line_offset( str
, scale
, align
);
562 text_cursor
[1] = pos
[1];
563 text_cursor
[2] = 8*scale
;
564 text_cursor
[3] = 14*scale
;
566 while( (c
= *(_c
++)) )
570 text_cursor
[1] += 14*scale
;
571 text_cursor
[0] = pos
[0] + ui_text_line_offset( _c
, scale
, align
);
578 glyph_base
[0] = glyph_index
& 0xf;
579 glyph_base
[1] = (glyph_index
-glyph_base
[0])>>4;
584 ui_fill_rect_uv( ctx
, text_cursor
, current_colour
, (ui_px
[4]){glyph_base
[0]+2,glyph_base
[1]+1,glyph_base
[0]+6,glyph_base
[1]+8} );
586 else if( c
== '\x1B' )
590 for( int i
= 0; i
< 3; i
++ )
600 case '0': current_colour
= 0x00ffffff; break;
601 case '3'|'1'<<8: current_colour
= 0x00201fee; break;
602 case '3'|'2'<<8: current_colour
= 0x0037e420; break;
603 case '3'|'3'<<8: current_colour
= 0x000ed8e2; break;
604 case '3'|'4'<<8: current_colour
= 0x00f15010; break;
605 case '3'|'5'<<8: current_colour
= 0x00ee20ee; break;
606 case '3'|'6'<<8: current_colour
= 0x00eeee20; break;
607 case '3'|'7'<<8: current_colour
= 0x00ffffff; break;
613 colour_id
|= _c
[i
] << (i
*8);
626 text_cursor
[0] += UI_GLYPH_SPACING_X
*scale
*4;
630 text_cursor
[0] += UI_GLYPH_SPACING_X
*scale
;
635 // ====================================================================
637 static void ui_begin( ui_ctx
*ctx
, ui_px res_x
, ui_px res_y
)
641 ctx
->cursor
[2] = res_x
;
642 ctx
->cursor
[3] = res_y
;
644 ui_rect_copy( ctx
->cursor
, ctx
->stack
[0].rect
);
645 ctx
->stack
[0].mouse_over
= 1;
647 ctx
->stack_count
= 1;
650 ctx
->num_indices
= 0;
652 ui_release_clip( ctx
);
654 if( ctx
->click_state
== 0 )
655 ctx
->capture_mouse_id
= 0;
657 ctx
->image_count
= 0;
660 static void ui_resolve( ui_ctx
*ctx
)
662 if( ctx
->stack_count
-1 )
663 vg_exiterr( "[UI] Mismatched node create/drestroy!" );
665 if( ctx
->click_state
== 3 || ctx
->click_state
== 0 )
667 ctx
->capture_lock
= 0;
672 // ====================================================================
674 static void ui_set_mouse( ui_ctx
*ctx
, int x
, int y
, int click_state
)
679 ctx
->click_state
= click_state
;
682 // High level controls
683 // ====================================================================
691 ui_px drag_offset
[2];
696 k_button_released
= 0,
697 k_button_start_click
,
702 static int ui_button( ui_ctx
*ctx
, u32 id
)
706 ui_capture_mouse( ctx
, id
);
708 if( ui_hasmouse(ctx
) )
710 ui_fill_rect( ctx
, ctx
->cursor
, ctx
->colours
->hover
);
712 if( ctx
->click_state
== 1 )
714 ctx
->capture_lock
= 1;
715 return k_button_start_click
;
717 else if( ctx
->capture_lock
&& ctx
->click_state
== 3 )
718 return k_button_click
;
719 else if( ctx
->capture_lock
&& ctx
->click_state
== 2 )
720 return k_button_hold
;
723 ui_fill_rect( ctx
, ctx
->cursor
, ctx
->colours
->main
);
726 return k_button_released
;
729 static int ui_window( ui_ctx
*ctx
, struct ui_window
*window
, u32 control_group
)
731 ctx
->id_base
= control_group
<< 16;
735 window
->transform
[0] = ctx
->mouse
[0]+window
->drag_offset
[0];
736 window
->transform
[1] = ctx
->mouse
[1]+window
->drag_offset
[1];
738 ui_clamp_rect( ctx
->stack
[0].rect
, window
->transform
);
740 if( ctx
->click_state
== 0 || ctx
->click_state
== 3 )
746 ui_rect_copy( window
->transform
, ctx
->cursor
);
750 ui_capture_mouse( ctx
, __COUNTER__
);
756 ui_capture_mouse( ctx
, __COUNTER__
);
758 struct ui_vert
*drag_bar
= ui_fill_rect( ctx
, ctx
->cursor
, 0xff555555 );
763 ui_text( ctx
, ctx
->cursor
, window
->title
, 2, 0 );
768 ui_align_right( ctx
);
770 ui_rect_pad( ctx
->cursor
, 4 );
772 if( ui_button( ctx
, __COUNTER__
) )
774 vg_info( "Click clacked\n" );
777 ui_text( ctx
, ctx
->cursor
, "x", 2, 0 );
780 if( ui_hasmouse( ctx
) )
782 drag_bar
[0].colour
= 0xff777777;
783 drag_bar
[1].colour
= 0xff777777;
784 drag_bar
[2].colour
= 0xff777777;
785 drag_bar
[3].colour
= 0xff777777;
788 if( ctx
->click_state
== 1 )
791 window
->drag_offset
[0] = window
->transform
[0]-ctx
->mouse
[0];
792 window
->drag_offset
[1] = window
->transform
[1]-ctx
->mouse
[1];
812 static void ui_scrollbar( ui_ctx
*ctx
, struct ui_scrollbar
*scrollbar
, u32 id
)
814 scrollbar
->view_height
= ctx
->cursor
[3];
816 if( scrollbar
->drag
)
818 scrollbar
->py
= ctx
->mouse
[1]+scrollbar
->drag_offset
;
819 scrollbar
->py
= VG_MAX( scrollbar
->py
, 0 );
820 scrollbar
->py
= VG_MIN( scrollbar
->py
, ctx
->cursor
[3] - scrollbar
->bar_height
);
822 if( ctx
->click_state
== 0 || ctx
->click_state
== 3 )
828 ui_fill_rect( ctx
, ctx
->cursor
, ctx
->colours
->background
);
829 ui_capture_mouse( ctx
, id
);
831 ctx
->cursor
[1] += scrollbar
->py
;
832 ctx
->cursor
[3] = scrollbar
->bar_height
;
836 ui_capture_mouse( ctx
, __COUNTER__
);
837 struct ui_vert
*drag_bar
= ui_fill_rect( ctx
, ctx
->cursor
, ctx
->colours
->bar
);
839 if( ui_hasmouse( ctx
) || scrollbar
->drag
)
841 drag_bar
[0].colour
= ctx
->colours
->bar_hover
;
842 drag_bar
[1].colour
= ctx
->colours
->bar_hover
;
843 drag_bar
[2].colour
= ctx
->colours
->bar_hover
;
844 drag_bar
[3].colour
= ctx
->colours
->bar_hover
;
847 if( ctx
->click_state
== 1 )
850 scrollbar
->drag_offset
= scrollbar
->py
- ctx
->mouse
[1];
859 static ui_px
ui_calculate_content_scroll( struct ui_scrollbar
*scrollbar
, ui_px content
)
861 float overlap
= vg_maxf( 0.0f
, (float)(content
- scrollbar
->view_height
) );
863 float range
= scrollbar
->view_height
- scrollbar
->bar_height
;
864 return ((float)scrollbar
->py
/ range
) * overlap
;
867 static void ui_push_image( ui_ctx
*ctx
, ui_rect rc
, GLuint image
)
869 struct ui_image
*img
= &ctx
->images
[ ctx
->image_count
++ ];
870 ui_rect_copy( rc
, img
->rc
);
875 #define gui_draw(...) ui_draw( &ui_global_ctx, __VA_ARGS__)
876 #define gui_current(...) ui_current( &ui_global_ctx, __VA_ARGS__)
877 #define gui_new_node() ui_new_node( &ui_global_ctx )
878 #define gui_hasmouse(...) ui_hasmouse( &ui_global_ctx, __VA_ARGS__)
879 #define gui_end() ui_end( &ui_global_ctx )
880 #define gui_end_down() ui_end_down( &ui_global_ctx )
881 #define gui_end_right() ui_end_right( &ui_global_ctx )
882 #define gui_fill_y() ui_fill_y( &ui_global_ctx)
883 #define gui_fill_x() ui_fill_x( &ui_global_ctx)
884 #define gui_align_bottom() ui_align_bottom( &ui_global_ctx )
885 #define gui_align_right() ui_align_right( &ui_global_ctx )
886 #define gui_align_top() ui_align_top( &ui_global_ctx )
887 #define gui_align_left() ui_align_left( &ui_global_ctx )
888 #define gui_clamp_rect(...) ui_clamp_rect( &ui_global_ctx, __VA_ARGS__)
889 #define gui_group_id(...) ui_group_id( &ui_global_ctx, __VA_ARGS__)
890 #define gui_capture_mouse(...) ui_capture_mouse( &ui_global_ctx, __VA_ARGS__)
891 #define gui_set_clip(...) ui_set_clip( &ui_global_ctx, __VA_ARGS__)
892 #define gui_release_clip() ui_release_clip( &ui_global_ctx )
893 #define gui_fill_rect_uv(...) ui_fill_rect_uv( &ui_global_ctx, __VA_ARGS__)
894 #define gui_fill_rect(...) ui_fill_rect( &ui_global_ctx, __VA_ARGS__)
895 #define gui_text(...) ui_text( &ui_global_ctx, __VA_ARGS__)
896 #define gui_begin(...) ui_begin( &ui_global_ctx, __VA_ARGS__)
897 #define gui_resolve(...) ui_resolve( &ui_global_ctx, __VA_ARGS__)
898 #define gui_set_mouse(...) ui_set_mouse( &ui_global_ctx, __VA_ARGS__)
899 #define gui_button(...) ui_button( &ui_global_ctx, __VA_ARGS__)
900 #define gui_window(...) ui_window( &ui_global_ctx, __VA_ARGS__)
901 #define gui_want_mouse() ui_want_mouse( &ui_global_ctx )
902 #define gui_push_image(...) ui_push_image( &ui_global_ctx, __VA_ARGS__ )
903 #define gui_scrollbar(...) ui_scrollbar( &ui_global_ctx, __VA_ARGS__)
904 #define gui_reset_colours(...) ui_reset_colours( &ui_global_ctx )