From 8cf3c8ca1b193c454b8a79ad921ea5f4890da013 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Thu, 27 Feb 2025 17:15:15 -0500 Subject: select widget --- main.c | 29 +++++++++++++++++++---------- ui.c | 9 ++++++++- ui.h | 3 ++- widget.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- widget.h | 17 ++++++++++++++--- 5 files changed, 97 insertions(+), 17 deletions(-) diff --git a/main.c b/main.c index 4660c49..b8a7bcd 100644 --- a/main.c +++ b/main.c @@ -19,6 +19,7 @@ enum window { static const mu_Color BLACK = {0, 0, 0, 255}; static const mu_Color WHITE = {255, 255, 255, 255}; static const mu_Color LIGHT_GRAY = {222, 222, 222, 255}; +static const mu_Color DARK_GRAY = {128, 128, 128, 255}; static const mu_Color COLOR_TEXT = BLACK; static const mu_Color COLOR_BORDER = BLACK; @@ -26,9 +27,9 @@ static const mu_Color COLOR_WINDOWBG = WHITE; static const mu_Color COLOR_TITLEBG = LIGHT_GRAY; static const mu_Color COLOR_TITLETEXT = COLOR_TEXT; static const mu_Color COLOR_PANELBG = COLOR_WINDOWBG; -static const mu_Color COLOR_BUTTON = LIGHT_GRAY; -static const mu_Color COLOR_BUTTONHOVER = COLOR_BUTTON; -static const mu_Color COLOR_BUTTONFOCUS = COLOR_BUTTON; +static const mu_Color COLOR_BUTTON = WHITE; +static const mu_Color COLOR_BUTTONHOVER = LIGHT_GRAY; +static const mu_Color COLOR_BUTTONFOCUS = DARK_GRAY; static const mu_Color COLOR_BASE = WHITE; static const mu_Color COLOR_BASEHOVER = COLOR_BASE; static const mu_Color COLOR_BASEFOCUS = COLOR_BASE; @@ -101,20 +102,28 @@ static void main_window(mu_Context *ctx, UI *ui) { int w, h; r_get_window_size(&w, &h); - if (!mu_begin_window_ex(ctx, TITLE, mu_rect(0, 0, w, h), WIN_OPTS)) { exit(EXIT_FAILURE); } + /* TODO */ - mu_layout_row(ctx, 2, (int[]) {0, 0}, 0); + + + mu_layout_row(ctx, 3, (int[]) {128, 15, 128}, 0); + static double value = 0.0; - if (field(ctx, &ui->displacement) & MU_RES_CHANGE) { + if (w_field(ctx, &ui->displacement) & MU_RES_CHANGE) { /* TODO */ value = ui->displacement.value; } - static char buf[64]; - snprintf(buf, sizeof(buf), "%lf", value); - mu_label(ctx, buf); - mu_label(ctx, "abcdefghijklmnopqrstuvwxyz0123456789"); + + if (w_select(ctx, &ui->displacement_unit) & MU_RES_CHANGE) { + /* TODO */ + } + + mu_layout_begin_column(ctx); + mu_button(ctx, "foo bar"); + mu_layout_end_column(ctx); + mu_end_window(ctx); } diff --git a/ui.c b/ui.c index f44e89d..65ce084 100644 --- a/ui.c +++ b/ui.c @@ -2,7 +2,14 @@ #include "widget.h" #include "ui.h" + +#define nelem(arr) (sizeof(arr)/sizeof(arr[0])) + + void init_ui(UI *ui) { - init_field(&ui->displacement); + w_init_field(&ui->displacement); + + static const char *const displacement_units[] = {"cc", "l", "ci"}; + w_init_select(&ui->displacement_unit, nelem(displacement_units), displacement_units); } diff --git a/ui.h b/ui.h index 9fa170f..c8388c4 100644 --- a/ui.h +++ b/ui.h @@ -1,5 +1,6 @@ typedef struct { - Field displacement; + w_Field displacement; + w_Select displacement_unit; } UI; void init_ui(UI *ui); diff --git a/widget.c b/widget.c index 8a77b8f..8b862a8 100644 --- a/widget.c +++ b/widget.c @@ -1,10 +1,15 @@ #include +#include #include "microui.h" #include "widget.h" + +#define nelem(arr) (sizeof(arr)/sizeof(arr[0])) + + void -init_field(Field *f) { +w_init_field(w_Field *f) { f->buf[0] = '\0'; f->value = 0.0; } @@ -12,7 +17,7 @@ init_field(Field *f) { /* field draws a Field widget and updates its value. * It returns MU_RES_CHANGE if the value has changed. */ int -field(mu_Context *ctx, Field *f) { +w_field(mu_Context *ctx, w_Field *f) { double value; int changed = 0; if (mu_textbox(ctx, f->buf, sizeof(f->buf)) & MU_RES_CHANGE) { @@ -26,3 +31,50 @@ field(mu_Context *ctx, Field *f) { } return changed ? MU_RES_CHANGE : 0; } + +void +w_init_select(w_Select *select, int nopts, const char *const opts[]) { + select->nopts = nopts; + select->opts = opts; + select->idx = 0; + select ->active = 0; +} + +int +w_select(mu_Context *ctx, w_Select *select) { + mu_Id id; + mu_Rect r; + int color, res, i; + + mu_layout_begin_column(ctx); + + id = mu_get_id(ctx, &select, sizeof(select)); + r = mu_layout_next(ctx); + mu_update_control(ctx, id, r, 0); + + select->active ^= (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id); + + color = MU_COLOR_BUTTON; + if (ctx->hover == id) { + color = MU_COLOR_BUTTONHOVER; + } + ctx->draw_frame(ctx, r, color); + const char *label = select->opts[select->idx]; + mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, 0); + + res = 0; + if (select->active) { + res = MU_RES_ACTIVE; + for (i = 0; i < select->nopts; i++) { + if (mu_button(ctx, select->opts[i])) { + select->idx = i; + res |= MU_RES_CHANGE; + select->active = 0; + } + } + } + + mu_layout_end_column(ctx); + + return res; +} diff --git a/widget.h b/widget.h index a0149e0..afd7bb1 100644 --- a/widget.h +++ b/widget.h @@ -2,7 +2,18 @@ typedef struct { char buf[64]; double value; -} Field; +} w_Field; -void init_field(Field *f); -int field(mu_Context *ctx, Field *f); +void w_init_field(w_Field *f); +int w_field(mu_Context *ctx, w_Field *f); + + +typedef struct { + int nopts; + const char *const *opts; + int idx; /* index of selected option. */ + int active; +} w_Select; + +void w_init_select(w_Select *select, int nopts, const char *const opts[]); +int w_select(mu_Context *ctx, w_Select *select); -- cgit v1.2.3