From 3bc40f02a53cc9822ab0343c3ae6ab24e9388a4f Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sun, 17 Jul 2022 17:31:53 -0500 Subject: [PATCH] Widgets can now contain other widgets. --- roo-e/src/gui/gui.c | 25 ++++++++++++++++++++-- roo-e/src/gui/gui.h | 17 ++++++++------- roo-e/src/gui/widgets/checkbox.c | 2 +- roo-e/src/gui/widgets/hscroll.c | 2 +- roo-e/src/gui/widgets/radio.c | 4 ++-- roo-e/src/gui/widgets/scroll.c | 4 ++-- roo-e/src/gui/widgets/vscroll.c | 2 +- roo-e/src/gui/wmwindow.c | 36 +++++++------------------------- roo-e/src/gui/wmwindow.h | 3 --- roo-e/src/main.c | 24 ++++++++++----------- 10 files changed, 60 insertions(+), 59 deletions(-) diff --git a/roo-e/src/gui/gui.c b/roo-e/src/gui/gui.c index b180879..d216375 100644 --- a/roo-e/src/gui/gui.c +++ b/roo-e/src/gui/gui.c @@ -211,6 +211,14 @@ void guiStop(void) { } +void widgetAdd(WidgetT *target, int16_t x, int16_t y, WidgetT *widget) { + widget->parent = target; + widget->r.x = x; + widget->r.y = y; + arrput(target->children, widget); +} + + void widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h) { widget->magic = magic; @@ -252,8 +260,8 @@ void widgetInputSetRaw(WidgetT *widget, uint8_t raw) { } -uint8_t widgetIsInWindow(WidgetT *widget, struct WindowS *window) { - return widget->parent == window;; +uint8_t widgetIsInWidget(WidgetT *widget, WidgetT *parent) { + return widget->parent == parent; } @@ -266,3 +274,16 @@ void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y) { widget->reg->paint(widget); widget->r = r; } + + +void widgetRemove(WidgetT *target, WidgetT *widget) { + uint16_t i; + + for (i=0; ichildren); i++) { + if (target->children[i] == widget) { + arrdel(target->children, i); + break; + } + } + +} diff --git a/roo-e/src/gui/gui.h b/roo-e/src/gui/gui.h index f83fa80..db1f412 100644 --- a/roo-e/src/gui/gui.h +++ b/roo-e/src/gui/gui.h @@ -77,12 +77,13 @@ typedef struct RegisterS { } RegisterT; typedef struct WidgetS { - uint8_t magic; // Magic ID of widget. - RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2! - RegisterT *reg; // Registration information. - void *data; // Pointer to arbitrary data for user. - uint8_t flags; // Widget flags (see defines above). - struct WindowS *parent; // Who owns this widget? + uint8_t magic; // Magic ID of widget. Must be first! + RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2! + RegisterT *reg; // Registration information. + void *data; // Pointer to arbitrary data for user. + uint8_t flags; // Widget flags (see defines above). + struct WidgetS *parent; // Who owns this widget? + struct WidgetS **children; // Widgets contained in this widget. } WidgetT; typedef struct ClickRawInputS { @@ -137,13 +138,15 @@ void guiShutdown(void); uint8_t guiStartup(int16_t width, int16_t height, int16_t depth); void guiStop(void); +void widgetAdd(WidgetT *target, int16_t x, int16_t y, WidgetT *widget); void widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h); void widgetDestroy(WidgetT *widget); uint8_t widgetDirtyGet(WidgetT *widget); void widgetDirtySet(WidgetT *widget, uint8_t dirty); void widgetInputSetRaw(WidgetT *widget, uint8_t raw); -uint8_t widgetIsInWindow(WidgetT *widget, struct WindowS *window); +uint8_t widgetIsInWidget(WidgetT *widget, WidgetT *parent); void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y); +void widgetRemove(WidgetT *target, WidgetT *widget); #endif // GUI_H diff --git a/roo-e/src/gui/widgets/checkbox.c b/roo-e/src/gui/widgets/checkbox.c index 3091c9f..aedd846 100644 --- a/roo-e/src/gui/widgets/checkbox.c +++ b/roo-e/src/gui/widgets/checkbox.c @@ -108,7 +108,7 @@ static void checkboxPaint(struct WidgetS *widget, ...) { // Finish initializing. if (!c->attached) { c->attached = 1; - windowWidgetAdd(c->base.parent, c->base.r.x + w, c->base.r.y, W(c->label)); + widgetAdd(c->base.parent, c->base.r.x + w, c->base.r.y, W(c->label)); } } } diff --git a/roo-e/src/gui/widgets/hscroll.c b/roo-e/src/gui/widgets/hscroll.c index ee024c6..3e755ab 100644 --- a/roo-e/src/gui/widgets/hscroll.c +++ b/roo-e/src/gui/widgets/hscroll.c @@ -143,7 +143,7 @@ static void hscrollPaint(struct WidgetS *widget, ...) { if (widgetDirtyGet(widget)) { widgetDirtySet(widget, 0); // Find some colors. - if (widgetIsInWindow(widget, wmWindowOnTopGet())) { + if (widgetIsInWidget(widget, W(wmWindowOnTopGet()))) { scrollBackgroundColor = GUI_DARKGRAY; widgetColor = GUI_LIGHTGRAY; } else { diff --git a/roo-e/src/gui/widgets/radio.c b/roo-e/src/gui/widgets/radio.c index b534eba..27c277b 100644 --- a/roo-e/src/gui/widgets/radio.c +++ b/roo-e/src/gui/widgets/radio.c @@ -145,7 +145,7 @@ static void radioPaint(struct WidgetS *widget, ...) { // Finish initializing. if (!r->attached) { r->attached = 1; - windowWidgetAdd(r->base.parent, r->base.r.x + w, r->base.r.y, W(r->label)); + widgetAdd(r->base.parent, r->base.r.x + w, r->base.r.y, W(r->label)); } } } @@ -174,7 +174,7 @@ uint8_t radioValueGet(RadioT *radio) { void radioValueSet(RadioT *radio, uint8_t value) { int16_t i; - WindowT *p; + WidgetT *p; RadioT *r; radio->value = (value != 0); diff --git a/roo-e/src/gui/widgets/scroll.c b/roo-e/src/gui/widgets/scroll.c index 25b6643..351d0a0 100644 --- a/roo-e/src/gui/widgets/scroll.c +++ b/roo-e/src/gui/widgets/scroll.c @@ -107,14 +107,14 @@ static void scrollablePaint(struct WidgetS *widget, ...) { if (s->scrollh) { s->sizes.y = s->base.r.h - s->scrollh->base.r.h; s->base.r.h -= s->scrollh->base.r.h; - windowWidgetAdd(s->base.parent, s->base.r.x, s->base.r.y + s->sizes.y, W(s->scrollh)); + widgetAdd(s->base.parent, s->base.r.x, s->base.r.y + s->sizes.y, W(s->scrollh)); } else { s->sizes.y = s->base.r.h; } if (s->scrollv) { s->sizes.x = s->base.r.w - s->scrollv->base.r.w; s->base.r.w -= s->scrollv->base.r.w; - windowWidgetAdd(s->base.parent, s->base.r.x + s->sizes.x, s->base.r.y, W(s->scrollv)); + widgetAdd(s->base.parent, s->base.r.x + s->sizes.x, s->base.r.y, W(s->scrollv)); } else { s->sizes.x = s->base.r.w; } diff --git a/roo-e/src/gui/widgets/vscroll.c b/roo-e/src/gui/widgets/vscroll.c index 7419f08..5d11d47 100644 --- a/roo-e/src/gui/widgets/vscroll.c +++ b/roo-e/src/gui/widgets/vscroll.c @@ -143,7 +143,7 @@ static void vscrollPaint(struct WidgetS *widget, ...) { if (widgetDirtyGet(widget)) { widgetDirtySet(widget, 0); // Find some colors. - if (widgetIsInWindow(widget, wmWindowOnTopGet())) { + if (widgetIsInWidget(widget, W(wmWindowOnTopGet()))) { scrollBackgroundColor = GUI_DARKGRAY; widgetColor = GUI_LIGHTGRAY; } else { diff --git a/roo-e/src/gui/wmwindow.c b/roo-e/src/gui/wmwindow.c index 3f5b148..06058a4 100644 --- a/roo-e/src/gui/wmwindow.c +++ b/roo-e/src/gui/wmwindow.c @@ -414,8 +414,8 @@ static void windowDestroy(struct WidgetS *widget, ...) { // Free the title. if (window->title) DEL(window->title); // Free children. - for (c=0; cchildren); c++) widgetDestroy(window->children[c]); - arrfree(window->children); + for (c=0; cbase.children); c++) widgetDestroy(window->base.children[c]); + arrfree(window->base.children); // Free cached surface. if (window->cached) surfaceDestroy(&window->cached); // Free content surface. @@ -649,12 +649,12 @@ static void windowPaint(struct WidgetS *widget, ...) { // Are any child widgets dirty? y = 0; - for (x=0; xchildren); x++) { - if (widgetDirtyGet(w->children[x])) { + for (x=0; xbase.children); x++) { + if (widgetDirtyGet(w->base.children[x])) { y = 1; - if (w->children[x]->reg->paint) { + if (w->base.children[x]->reg->paint) { surfaceSet(w->content); - w->children[x]->reg->paint(w->children[x]); + w->base.children[x]->reg->paint(w->base.children[x]); } } } @@ -849,26 +849,6 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) { } -void windowWidgetAdd(WindowT *window, int16_t x, int16_t y, WidgetT *widget) { - widget->parent = window; - widget->r.x = x; - widget->r.y = y; - arrput(window->children, widget); -} - - -void windowWidgetRemove(WindowT *window, WidgetT *widget) { - uint16_t i; - - for (i=0; ichildren); i++) { - if (window->children[i] == widget) { - arrdel(window->children, i); - break; - } - } -} - - void wmShutdown(void) { uint16_t i; @@ -1164,8 +1144,8 @@ static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *loca *localX = event->x - win->bounds.x + win->offset.x; *localY = event->y - win->bounds.y + win->offset.y; // Find widget under mouse. - for (i=0; ichildren); i++) { - widget = win->children[i]; + for (i=0; ibase.children); i++) { + widget = win->base.children[i]; if (*localX >= widget->r.x && *localX < widget->r.x + widget->r.x2 && *localY >= widget->r.y && *localY < widget->r.y + widget->r.y2) { // Return this widget. return widget; diff --git a/roo-e/src/gui/wmwindow.h b/roo-e/src/gui/wmwindow.h index 734c0a7..509576f 100644 --- a/roo-e/src/gui/wmwindow.h +++ b/roo-e/src/gui/wmwindow.h @@ -69,7 +69,6 @@ typedef struct WindowS { PointT offset; // Content scroll offset in window. SurfaceT *content; // Actual window contents - widgets and such. SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing. - WidgetT **children; // Widgets contained in the window. } WindowT; @@ -83,8 +82,6 @@ void windowMinimize(WindowT *win); void windowMove(WindowT *win, uint16_t x, uint16_t y); RegisterT *windowRegister(uint8_t magic); void windowResize(WindowT *win, uint16_t width, uint16_t height); -void windowWidgetAdd(WindowT *window, int16_t x, int16_t y, WidgetT *widget); -void windowWidgetRemove(WindowT *window, WidgetT *widget); void wmShutdown(void); diff --git a/roo-e/src/main.c b/roo-e/src/main.c index 37b8a49..1a1005e 100644 --- a/roo-e/src/main.c +++ b/roo-e/src/main.c @@ -73,38 +73,38 @@ int main(int argc, char *argv[]) { l = labelCreate(LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label"); labelColorSet(l, __guiBaseColors[i], GUI_BLACK); labelClickSet(l, clickHandler, title); - windowWidgetAdd(w, 20, 10, W(l)); + widgetAdd(W(w), 20, 10, W(l)); b = buttonCreate("Button", clickHandler, NULL); - windowWidgetAdd(w, 20, 40, W(b)); + widgetAdd(W(w), 20, 40, W(b)); c = checkboxCreate("Checkbox", 0); - windowWidgetAdd(w, 20, 80, W(c)); + widgetAdd(W(w), 20, 80, W(c)); r = radioCreate("Radio 1", 0, 1); - windowWidgetAdd(w, 20, 110, W(r)); + widgetAdd(W(w), 20, 110, W(r)); r = radioCreate("Radio 2", 0, 0); - windowWidgetAdd(w, 120, 110, W(r)); + widgetAdd(W(w), 120, 110, W(r)); r = radioCreate("Radio 3", 0, 0); - windowWidgetAdd(w, 220, 110, W(r)); + widgetAdd(W(w), 220, 110, W(r)); r = radioCreate("Radio A", 1, 0); - windowWidgetAdd(w, 20, 140, W(r)); + widgetAdd(W(w), 20, 140, W(r)); r = radioCreate("Radio B", 1, 1); - windowWidgetAdd(w, 120, 140, W(r)); + widgetAdd(W(w), 120, 140, W(r)); r = radioCreate("Radio C", 1, 0); - windowWidgetAdd(w, 220, 140, W(r)); + widgetAdd(W(w), 220, 140, W(r)); _v = vscrollCreate(100, clickHandler, NULL); vscrollRangeSet(_v, 0, 640); - windowWidgetAdd(w, 200, 5, W(_v)); + widgetAdd(W(w), 200, 5, W(_v)); _h = hscrollCreate(100, clickHandler, NULL); hscrollRangeSet(_h, 0, 640); - windowWidgetAdd(w, 100, 5, W(_h)); + widgetAdd(W(w), 100, 5, W(_h)); s = scrollableCreate(300, 200, 648, 480, SCROLLABLE_STANDARD); - windowWidgetAdd(w, 20, 170, W(s)); + widgetAdd(W(w), 20, 170, W(s)); } guiRun(); guiShutdown();