[wip] re-introducing UI subsystem

This commit is contained in:
Martin Fouilleul 2023-03-03 17:13:03 +01:00
parent 653ddec978
commit d21e737733
5 changed files with 57 additions and 49 deletions

View File

@ -73,3 +73,5 @@
#else #else
#error "Unsupported platform" #error "Unsupported platform"
#endif #endif
#include"ui.c"

View File

@ -37,6 +37,7 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
#include"mp_app.h" #include"mp_app.h"
#include"graphics.h" #include"graphics.h"
#include"ui.h"
#ifdef MG_INCLUDE_GL_API #ifdef MG_INCLUDE_GL_API
#include"gl_api.h" #include"gl_api.h"

View File

@ -275,7 +275,8 @@ bool mp_input_mouse_released(mp_mouse_button button)
bool mp_input_mouse_clicked(mp_mouse_button button) bool mp_input_mouse_clicked(mp_mouse_button button)
{ {
mp_key_state state = mp_input_get_mouse_button_state(button); mp_key_state state = mp_input_get_mouse_button_state(button);
return(state.clicked); bool clicked = state.clicked && (state.lastUpdate == __mpApp.inputState.frameCounter);
return(clicked);
} }
bool mp_input_mouse_double_clicked(mp_mouse_button button) bool mp_input_mouse_double_clicked(mp_mouse_button button)

View File

@ -195,12 +195,14 @@ void ui_box_pop(void)
{ {
ui_context* ui = ui_get_context(); ui_context* ui = ui_get_context();
ui_box* box = ui_box_top(); ui_box* box = ui_box_top();
if(box->flags & UI_FLAG_CLIP) if(box)
{ {
ui_clip_pop(); if(box->flags & UI_FLAG_CLIP)
{
ui_clip_pop();
}
ui_stack_pop(&ui->boxStack);
} }
ui_stack_pop(&ui->boxStack);
} }
ui_style_attr* ui_push_style_attr(ui_context* ui, ui_stack_elt** stack) ui_style_attr* ui_push_style_attr(ui_context* ui, ui_stack_elt** stack)
@ -1064,31 +1066,31 @@ void ui_solve_layout(ui_context* ui)
// Drawing // Drawing
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ui_rectangle_fill(mg_canvas canvas, mp_rect rect, f32 roundness) void ui_rectangle_fill(mp_rect rect, f32 roundness)
{ {
if(roundness) if(roundness)
{ {
mg_rounded_rectangle_fill(canvas, rect.x, rect.y, rect.w, rect.h, roundness); mg_rounded_rectangle_fill(rect.x, rect.y, rect.w, rect.h, roundness);
} }
else else
{ {
mg_rectangle_fill(canvas, rect.x, rect.y, rect.w, rect.h); mg_rectangle_fill(rect.x, rect.y, rect.w, rect.h);
} }
} }
void ui_rectangle_stroke(mg_canvas canvas, mp_rect rect, f32 roundness) void ui_rectangle_stroke(mp_rect rect, f32 roundness)
{ {
if(roundness) if(roundness)
{ {
mg_rounded_rectangle_stroke(canvas, rect.x, rect.y, rect.w, rect.h, roundness); mg_rounded_rectangle_stroke(rect.x, rect.y, rect.w, rect.h, roundness);
} }
else else
{ {
mg_rectangle_stroke(canvas, rect.x, rect.y, rect.w, rect.h); mg_rectangle_stroke(rect.x, rect.y, rect.w, rect.h);
} }
} }
void ui_draw_box(mg_canvas canvas, ui_box* box) void ui_draw_box(ui_box* box)
{ {
if(ui_box_hidden(box)) if(ui_box_hidden(box))
{ {
@ -1099,29 +1101,29 @@ void ui_draw_box(mg_canvas canvas, ui_box* box)
if(box->flags & UI_FLAG_CLIP) if(box->flags & UI_FLAG_CLIP)
{ {
mg_clip_push(canvas, box->rect.x, box->rect.y, box->rect.w, box->rect.h); mg_clip_push(box->rect.x, box->rect.y, box->rect.w, box->rect.h);
} }
if(box->flags & UI_FLAG_DRAW_BACKGROUND) if(box->flags & UI_FLAG_DRAW_BACKGROUND)
{ {
mg_set_color(canvas, style->bgColor); mg_set_color(style->bgColor);
ui_rectangle_fill(canvas, box->rect, style->roundness); ui_rectangle_fill(box->rect, style->roundness);
} }
if((box->flags & UI_FLAG_DRAW_RENDER_PROC) && box->renderProc) if((box->flags & UI_FLAG_DRAW_RENDER_PROC) && box->renderProc)
{ {
box->renderProc(canvas, box, box->renderData); box->renderProc(box, box->renderData);
} }
for_each_in_list(&box->children, child, ui_box, listElt) for_each_in_list(&box->children, child, ui_box, listElt)
{ {
ui_draw_box(canvas, child); ui_draw_box(child);
} }
if(box->flags & UI_FLAG_DRAW_FOREGROUND) if(box->flags & UI_FLAG_DRAW_FOREGROUND)
{ {
mg_set_color(canvas, style->fgColor); mg_set_color(style->fgColor);
ui_rectangle_fill(canvas, box->rect, style->roundness); ui_rectangle_fill(box->rect, style->roundness);
} }
if(box->flags & UI_FLAG_DRAW_TEXT) if(box->flags & UI_FLAG_DRAW_TEXT)
@ -1131,29 +1133,29 @@ void ui_draw_box(mg_canvas canvas, ui_box* box)
f32 x = box->rect.x + 0.5*(box->rect.w - textBox.w); f32 x = box->rect.x + 0.5*(box->rect.w - textBox.w);
f32 y = box->rect.y + 0.5*(box->rect.h - textBox.h) - textBox.y; f32 y = box->rect.y + 0.5*(box->rect.h - textBox.h) - textBox.y;
mg_set_font(canvas, style->font); mg_set_font(style->font);
mg_set_font_size(canvas, style->fontSize); mg_set_font_size(style->fontSize);
mg_set_color(canvas, style->fontColor); mg_set_color(style->fontColor);
mg_move_to(canvas, x, y); mg_move_to(x, y);
mg_text_outlines(canvas, box->string); mg_text_outlines(box->string);
mg_fill(canvas); mg_fill();
} }
if(box->flags & UI_FLAG_CLIP) if(box->flags & UI_FLAG_CLIP)
{ {
mg_clip_pop(canvas); mg_clip_pop();
} }
if(box->flags & UI_FLAG_DRAW_BORDER) if(box->flags & UI_FLAG_DRAW_BORDER)
{ {
mg_set_width(canvas, style->borderSize); mg_set_width(style->borderSize);
mg_set_color(canvas, style->borderColor); mg_set_color(style->borderColor);
ui_rectangle_stroke(canvas, box->rect, style->roundness); ui_rectangle_stroke(box->rect, style->roundness);
} }
} }
void ui_draw(mg_canvas canvas) void ui_draw()
{ {
ui_context* ui = ui_get_context(); ui_context* ui = ui_get_context();
@ -1161,14 +1163,14 @@ void ui_draw(mg_canvas canvas)
mg_mat2x3 transform = {1, 0, 0, mg_mat2x3 transform = {1, 0, 0,
0, -1, ui->height}; 0, -1, ui->height};
bool oldTextFlip = mg_get_text_flip(canvas); bool oldTextFlip = mg_get_text_flip();
mg_set_text_flip(canvas, true); mg_set_text_flip(true);
mg_matrix_push(canvas, transform); mg_matrix_push(transform);
ui_draw_box(canvas, ui->root); ui_draw_box(ui->root);
mg_matrix_pop(canvas); mg_matrix_pop();
mg_set_text_flip(canvas, oldTextFlip); mg_set_text_flip(oldTextFlip);
//TODO: restore flip?? //TODO: restore flip??
} }
@ -2006,7 +2008,7 @@ str32 ui_edit_perform_operation(ui_context* ui, ui_edit_op operation, ui_edit_mo
return(codepoints); return(codepoints);
} }
void ui_text_box_render(mg_canvas canvas, ui_box* box, void* data) void ui_text_box_render(ui_box* box, void* data)
{ {
str32 codepoints = *(str32*)data; str32 codepoints = *(str32*)data;
ui_context* ui = ui_get_context(); ui_context* ui = ui_get_context();
@ -2038,17 +2040,17 @@ void ui_text_box_render(mg_canvas canvas, ui_box* box, void* data)
f32 caretX = box->rect.x + textMargin - beforeBox.w + beforeCaretBox.w; f32 caretX = box->rect.x + textMargin - beforeBox.w + beforeCaretBox.w;
f32 caretY = textTop; f32 caretY = textTop;
mg_set_color_rgba(canvas, 0, 0, 0, 1); mg_set_color_rgba(0, 0, 0, 1);
mg_rectangle_fill(canvas, caretX, caretY, 2, lineHeight); mg_rectangle_fill(caretX, caretY, 2, lineHeight);
} }
mg_set_font(canvas, style->font); mg_set_font(style->font);
mg_set_font_size(canvas, style->fontSize); mg_set_font_size(style->fontSize);
mg_set_color(canvas, style->fontColor); mg_set_color(style->fontColor);
mg_move_to(canvas, textX, textY); mg_move_to(textX, textY);
mg_codepoints_outlines(canvas, codepoints); mg_codepoints_outlines(codepoints);
mg_fill(canvas); mg_fill();
} }
ui_text_box_result ui_text_box(const char* name, mem_arena* arena, str8 text) ui_text_box_result ui_text_box(const char* name, mem_arena* arena, str8 text)

View File

@ -82,7 +82,7 @@ typedef enum { UI_STYLE_SEL_NORMAL = 1<<0,
} ui_style_selector; } ui_style_selector;
typedef u32 ui_style_tag; typedef u32 ui_style_tag;
#define UI_STYLE_TAG_ANY (ui_style_tag)0 #define UI_STYLE_TAG_ANY ((ui_style_tag)0)
typedef enum { UI_STYLE_ANIMATE_SIZE_X = 1<<1, typedef enum { UI_STYLE_ANIMATE_SIZE_X = 1<<1,
UI_STYLE_ANIMATE_SIZE_Y = 1<<2, UI_STYLE_ANIMATE_SIZE_Y = 1<<2,
@ -132,7 +132,7 @@ typedef struct ui_sig
} ui_sig; } ui_sig;
typedef void(*ui_box_render_proc)(mg_canvas canvas, ui_box* box, void* data); typedef void(*ui_box_render_proc)(ui_box* box, void* data);
struct ui_box struct ui_box
{ {
@ -190,7 +190,7 @@ void ui_set_context(ui_context* context);
void ui_begin_frame(u32 width, u32 height, ui_style defaultStyle); void ui_begin_frame(u32 width, u32 height, ui_style defaultStyle);
void ui_end_frame(void); void ui_end_frame(void);
void ui_draw(mg_canvas canvas); void ui_draw(void);
ui_box* ui_box_lookup(const char* string); ui_box* ui_box_lookup(const char* string);
ui_box* ui_box_lookup_str8(str8 string); ui_box* ui_box_lookup_str8(str8 string);
@ -259,8 +259,10 @@ void ui_pop_border_color(void);
void ui_pop_roundness(void); void ui_pop_roundness(void);
void ui_pop_animation_time(void); void ui_pop_animation_time(void);
void ui_pop_animation_flags(void); void ui_pop_animation_flags(void);
// Basic helpers
//-------------------------------------------------------------------------
// Basic widget helpers
//-------------------------------------------------------------------------
enum { enum {
UI_STYLE_TAG_USER_MAX = 1<<16, UI_STYLE_TAG_USER_MAX = 1<<16,
UI_STYLE_TAG_LABEL, UI_STYLE_TAG_LABEL,