1414// Structures
1515//-----------------------------------------------------------------------------------------------------------------------------
1616
17- typedef struct
18- {
19- float x , y , width , height ;
20- } ui_rect ;
21-
2217typedef struct {float x , y ;} ui_vec2 ;
2318
2419typedef struct
@@ -27,6 +22,9 @@ typedef struct
2722 uint32_t id ;
2823 ui_vec2 pos ;
2924 float width , height ;
25+ float min_width , min_height ;
26+ uint32_t options ;
27+ bool closed ;
3028} ui_window ;
3129
3230typedef struct
@@ -69,6 +67,7 @@ struct ui_context
6967 ui_window windows [MAX_WINDOWS ];
7068 uint32_t num_windows ;
7169 ui_window * current_window ;
70+ ui_window * resizing_window ;
7271 void * dragging_object ;
7372 ui_animation animation ;
7473 ui_hover hover ;
@@ -77,7 +76,7 @@ struct ui_context
7776 float font_height ;
7877 float row_height ;
7978 float padding ;
80- float corners_radius ;
79+ float corner ;
8180 ui_colors colors ;
8281 ui_renderer_fnc_t renderer ;
8382 char string_buffer [STRING_BUFFER_SIZE ];
@@ -88,6 +87,7 @@ struct ui_context
8887//-----------------------------------------------------------------------------------------------------------------------------
8988
9089static inline ui_vec2 ui_vec2_sub (ui_vec2 a , ui_vec2 b ) {return (ui_vec2 ){a .x - b .x , a .y - b .y };}
90+ static inline ui_vec2 ui_vec2_add (ui_vec2 a , ui_vec2 b ) {return (ui_vec2 ){a .x + b .x , a .y + b .y };}
9191static inline bool in_rect (const ui_rect * rect , ui_vec2 pos )
9292{
9393 return ((pos .x >=rect -> x ) && (pos .x <=rect -> x + rect -> width ) && (pos .y >=rect -> y ) && (pos .y <=rect -> y + rect -> height ));
@@ -164,6 +164,8 @@ ui_context* ui_init(const ui_def* def)
164164{
165165 assert (def -> renderer_callbacks .draw_box && def -> renderer_callbacks .draw_text &&
166166 def -> renderer_callbacks .set_clip_rect && def -> renderer_callbacks .text_width );
167+
168+ assert (((uintptr_t )def -> preallocated_buffer )%sizeof (uintptr_t ) == 0 );
167169
168170 ui_context * ctx = (ui_context * )def -> preallocated_buffer ;
169171 * ctx = (ui_context )
@@ -172,7 +174,7 @@ ui_context* ui_init(const ui_def* def)
172174 .font_height = def -> font_height ,
173175 .renderer = def -> renderer_callbacks ,
174176 .padding = fmaxf (def -> font_height /4.f , 2.f ),
175- .corners_radius = fmaxf (def -> font_height /2.f , 2.f ),
177+ .corner = fmaxf (def -> font_height /2.f , 2.f ),
176178 .colors =
177179 {
178180 .window_bg = 0xFFF7F0E9 ,
@@ -215,7 +217,7 @@ void ui_begin_frame(ui_context* ctx, float delta_time)
215217}
216218
217219//-----------------------------------------------------------------------------------------------------------------------------
218- void ui_begin_window (ui_context * ctx , const char * name , float x , float y , float width , float height )
220+ void ui_begin_window (ui_context * ctx , const char * name , float x , float y , float width , float height , uint32_t options )
219221{
220222 assert (ctx -> current_window == NULL );
221223
@@ -236,32 +238,49 @@ void ui_begin_window(ui_context* ctx, const char* name, float x, float y, float
236238 .name = name ,
237239 .id = id ,
238240 .pos = {.x = x , .y = y },
239- .width = fmaxf (width , ctx -> renderer .text_width (name , ctx -> renderer .user ) + ctx -> padding * 2.f ),
240- .height = fmaxf (height , ctx -> font_height + ctx -> padding * 2.f )
241+ .min_width = ctx -> renderer .text_width (name , ctx -> renderer .user ) + ctx -> padding * 2.f ,
242+ .min_height = ctx -> row_height * 2.f ,
243+ .width = width ,
244+ .height = height ,
245+ .options = options ,
246+ .closed = false
241247 };
242248 }
243249
244250 ui_window * w = ctx -> current_window ;
251+
252+ // resize
253+ ui_rect handle_rect = {w -> pos .x + w -> width - ctx -> corner , w -> pos .y + w -> height - ctx -> corner , ctx -> corner , ctx -> corner };
254+ if (ctx -> mouse_button == button_pressed && in_rect (& handle_rect , ctx -> mouse_pos ) && (w -> options & window_resizable ))
255+ {
256+ ctx -> resizing_window = w ;
257+ ctx -> dragging_offset = ui_vec2_sub (ui_vec2_add (w -> pos , (ui_vec2 ) {w -> width , w -> height }), ctx -> mouse_pos );
258+ }
259+
260+ if (ctx -> mouse_down && ctx -> resizing_window == w )
261+ {
262+ w -> width = fmaxf (ctx -> mouse_pos .x + ctx -> dragging_offset .x - w -> pos .x , w -> min_width );
263+ w -> height = fmaxf (ctx -> mouse_pos .y + ctx -> dragging_offset .y - w -> pos .y , w -> min_height );
264+ }
265+
245266 ui_rect title_rect = {w -> pos .x + ctx -> padding , w -> pos .y + ctx -> padding , w -> width - ctx -> padding * 2.f , ctx -> row_height };
246267
247268 // move the window if click on the title bar
248- if (ctx -> mouse_button == button_pressed && in_rect (& title_rect , ctx -> mouse_pos ))
269+ if (ctx -> mouse_button == button_pressed && in_rect (& title_rect , ctx -> mouse_pos ) &&
270+ !(w -> options & window_pinned ) && ctx -> resizing_window != w )
249271 {
250272 ctx -> dragging_object = w ;
251273 ctx -> dragging_offset = ui_vec2_sub (ctx -> mouse_pos , w -> pos );
252274 }
253275
254- if (ctx -> mouse_button == button_released && ctx -> dragging_object == w )
255- ctx -> dragging_object = NULL ;
256-
257276 if (ctx -> mouse_down && ctx -> dragging_object == w )
258277 w -> pos = ui_vec2_sub (ctx -> mouse_pos , ctx -> dragging_offset );
259278
260279 // border
261- ctx -> renderer .draw_box (w -> pos .x , w -> pos .y , w -> width , w -> height , ctx -> corners_radius , ctx -> colors .window_border , ctx -> renderer .user );
280+ ctx -> renderer .draw_box (w -> pos .x , w -> pos .y , w -> width , w -> height , ctx -> corner , ctx -> colors .window_border , ctx -> renderer .user );
262281
263282 // title bg
264- ctx -> renderer .draw_box (title_rect .x , title_rect .y , title_rect .width , title_rect .height , ctx -> corners_radius , ctx -> colors .title_bg , ctx -> renderer .user );
283+ ctx -> renderer .draw_box (title_rect .x , title_rect .y , title_rect .width , title_rect .height , ctx -> corner , ctx -> colors .title_bg , ctx -> renderer .user );
265284
266285 ctx -> layout = (ui_rect )
267286 {
@@ -281,6 +300,10 @@ void ui_begin_window(ui_context* ctx, const char* name, float x, float y, float
281300 // title
282301 draw_align_text (ctx , & title_rect , w -> name , ctx -> colors .title_text , align_center );
283302
303+ // draw resize handle
304+ if (w -> options & window_resizable )
305+ ctx -> renderer .draw_box (handle_rect .x , handle_rect .y , handle_rect .width , handle_rect .height , 0.f , ctx -> colors .separator , ctx -> renderer .user );
306+
284307 // clip rect
285308 uint16_t clip_minx = (uint16_t ) fmaxf (ctx -> layout .x , 0.f );
286309 uint16_t clip_miny = (uint16_t ) fmaxf (ctx -> layout .y , 0.f );
@@ -413,7 +436,7 @@ void ui_segmented(ui_context* ctx, const char** entries, uint32_t num_entries, u
413436 };
414437
415438 ctx -> renderer .draw_box (seg_rect .x , seg_rect .y + ctx -> padding , ctx -> layout .width , seg_rect .height ,
416- ctx -> corners_radius , ctx -> colors .widget_bg , ctx -> renderer .user );
439+ ctx -> corner , ctx -> colors .widget_bg , ctx -> renderer .user );
417440
418441 if (* selected < num_entries )
419442 {
@@ -528,9 +551,6 @@ void ui_slider(ui_context* ctx, const char* label, float min_value, float max_va
528551 ctx -> dragging_object = NULL ;
529552 }
530553
531- if (ctx -> mouse_button == button_released && ctx -> dragging_object == value )
532- ctx -> dragging_object = NULL ;
533-
534554 // click-on-track update
535555 if (ctx -> animation .widget == value )
536556 thumb_x = lerp_float (ctx -> animation .value_key0 , ctx -> animation .value_key1 , ctx -> animation .t );
@@ -595,22 +615,29 @@ bool ui_button(ui_context* ctx, const char* label, enum ui_text_alignment alignm
595615
596616 // border
597617 ctx -> renderer .draw_box (button_rect .x , button_rect .y , button_rect .width , button_rect .height ,
598- ctx -> corners_radius , ctx -> colors .separator , ctx -> renderer .user );
618+ ctx -> corner , ctx -> colors .separator , ctx -> renderer .user );
599619
600620 expand_rect (& button_rect , -1.f );
601621
602622 ctx -> renderer .draw_box (button_rect .x , button_rect .y , button_rect .width , button_rect .height ,
603- ctx -> corners_radius , button_color , ctx -> renderer .user );
623+ ctx -> corner , button_color , ctx -> renderer .user );
604624
605625 ctx -> renderer .draw_text (text_pos .x , text_pos .y , label , ctx -> colors .text , ctx -> renderer .user );
606626
607627 return clicked ;
608628}
609629
630+ //-----------------------------------------------------------------------------------------------------------------------------
631+ const ui_rect * ui_get_layout (const ui_context * ctx )
632+ {
633+ return & ctx -> layout ;
634+ }
635+
610636//-----------------------------------------------------------------------------------------------------------------------------
611637void ui_end_window (ui_context * ctx )
612638{
613639 assert (ctx -> current_window != NULL );
640+ ctx -> current_window -> min_height = ctx -> layout .y - ctx -> current_window -> pos .y + ctx -> row_height * 2.f ;
614641 ctx -> current_window = NULL ;
615642 ctx -> renderer .set_clip_rect (0 , 0 , UINT16_MAX , UINT16_MAX , ctx -> renderer .user );
616643}
@@ -620,12 +647,18 @@ void ui_end_frame(ui_context* ctx)
620647{
621648 assert (ctx -> current_window == NULL );
622649
623- ctx -> mouse_button = button_idle ;
624-
625650 if (ctx -> animation .t >= 1.f )
626651 {
627652 ctx -> animation .widget = NULL ;
628653 ctx -> animation .t = 1.f ;
629654 }
655+
656+ if (ctx -> mouse_button == button_released )
657+ {
658+ ctx -> resizing_window = NULL ;
659+ ctx -> dragging_object = NULL ;
660+ }
661+
662+ ctx -> mouse_button = button_idle ;
630663}
631664
0 commit comments