Widgets can now contain other widgets.
This commit is contained in:
parent
fe79a0b139
commit
3bc40f02a5
10 changed files with 60 additions and 59 deletions
|
@ -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) {
|
void widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h) {
|
||||||
widget->magic = magic;
|
widget->magic = magic;
|
||||||
|
|
||||||
|
@ -252,8 +260,8 @@ void widgetInputSetRaw(WidgetT *widget, uint8_t raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t widgetIsInWindow(WidgetT *widget, struct WindowS *window) {
|
uint8_t widgetIsInWidget(WidgetT *widget, WidgetT *parent) {
|
||||||
return widget->parent == window;;
|
return widget->parent == parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,3 +274,16 @@ void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y) {
|
||||||
widget->reg->paint(widget);
|
widget->reg->paint(widget);
|
||||||
widget->r = r;
|
widget->r = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void widgetRemove(WidgetT *target, WidgetT *widget) {
|
||||||
|
uint16_t i;
|
||||||
|
|
||||||
|
for (i=0; i<arrlen(target->children); i++) {
|
||||||
|
if (target->children[i] == widget) {
|
||||||
|
arrdel(target->children, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -77,12 +77,13 @@ typedef struct RegisterS {
|
||||||
} RegisterT;
|
} RegisterT;
|
||||||
|
|
||||||
typedef struct WidgetS {
|
typedef struct WidgetS {
|
||||||
uint8_t magic; // Magic ID of widget.
|
uint8_t magic; // Magic ID of widget. Must be first!
|
||||||
RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2!
|
RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2!
|
||||||
RegisterT *reg; // Registration information.
|
RegisterT *reg; // Registration information.
|
||||||
void *data; // Pointer to arbitrary data for user.
|
void *data; // Pointer to arbitrary data for user.
|
||||||
uint8_t flags; // Widget flags (see defines above).
|
uint8_t flags; // Widget flags (see defines above).
|
||||||
struct WindowS *parent; // Who owns this widget?
|
struct WidgetS *parent; // Who owns this widget?
|
||||||
|
struct WidgetS **children; // Widgets contained in this widget.
|
||||||
} WidgetT;
|
} WidgetT;
|
||||||
|
|
||||||
typedef struct ClickRawInputS {
|
typedef struct ClickRawInputS {
|
||||||
|
@ -137,13 +138,15 @@ void guiShutdown(void);
|
||||||
uint8_t guiStartup(int16_t width, int16_t height, int16_t depth);
|
uint8_t guiStartup(int16_t width, int16_t height, int16_t depth);
|
||||||
void guiStop(void);
|
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 widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h);
|
||||||
void widgetDestroy(WidgetT *widget);
|
void widgetDestroy(WidgetT *widget);
|
||||||
uint8_t widgetDirtyGet(WidgetT *widget);
|
uint8_t widgetDirtyGet(WidgetT *widget);
|
||||||
void widgetDirtySet(WidgetT *widget, uint8_t dirty);
|
void widgetDirtySet(WidgetT *widget, uint8_t dirty);
|
||||||
void widgetInputSetRaw(WidgetT *widget, uint8_t raw);
|
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 widgetPaintManually(WidgetT *widget, int16_t x, int16_t y);
|
||||||
|
void widgetRemove(WidgetT *target, WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
#endif // GUI_H
|
#endif // GUI_H
|
||||||
|
|
|
@ -108,7 +108,7 @@ static void checkboxPaint(struct WidgetS *widget, ...) {
|
||||||
// Finish initializing.
|
// Finish initializing.
|
||||||
if (!c->attached) {
|
if (!c->attached) {
|
||||||
c->attached = 1;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ static void hscrollPaint(struct WidgetS *widget, ...) {
|
||||||
if (widgetDirtyGet(widget)) {
|
if (widgetDirtyGet(widget)) {
|
||||||
widgetDirtySet(widget, 0);
|
widgetDirtySet(widget, 0);
|
||||||
// Find some colors.
|
// Find some colors.
|
||||||
if (widgetIsInWindow(widget, wmWindowOnTopGet())) {
|
if (widgetIsInWidget(widget, W(wmWindowOnTopGet()))) {
|
||||||
scrollBackgroundColor = GUI_DARKGRAY;
|
scrollBackgroundColor = GUI_DARKGRAY;
|
||||||
widgetColor = GUI_LIGHTGRAY;
|
widgetColor = GUI_LIGHTGRAY;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -145,7 +145,7 @@ static void radioPaint(struct WidgetS *widget, ...) {
|
||||||
// Finish initializing.
|
// Finish initializing.
|
||||||
if (!r->attached) {
|
if (!r->attached) {
|
||||||
r->attached = 1;
|
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) {
|
void radioValueSet(RadioT *radio, uint8_t value) {
|
||||||
int16_t i;
|
int16_t i;
|
||||||
WindowT *p;
|
WidgetT *p;
|
||||||
RadioT *r;
|
RadioT *r;
|
||||||
|
|
||||||
radio->value = (value != 0);
|
radio->value = (value != 0);
|
||||||
|
|
|
@ -107,14 +107,14 @@ static void scrollablePaint(struct WidgetS *widget, ...) {
|
||||||
if (s->scrollh) {
|
if (s->scrollh) {
|
||||||
s->sizes.y = s->base.r.h - s->scrollh->base.r.h;
|
s->sizes.y = s->base.r.h - s->scrollh->base.r.h;
|
||||||
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 {
|
} else {
|
||||||
s->sizes.y = s->base.r.h;
|
s->sizes.y = s->base.r.h;
|
||||||
}
|
}
|
||||||
if (s->scrollv) {
|
if (s->scrollv) {
|
||||||
s->sizes.x = s->base.r.w - s->scrollv->base.r.w;
|
s->sizes.x = s->base.r.w - s->scrollv->base.r.w;
|
||||||
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 {
|
} else {
|
||||||
s->sizes.x = s->base.r.w;
|
s->sizes.x = s->base.r.w;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ static void vscrollPaint(struct WidgetS *widget, ...) {
|
||||||
if (widgetDirtyGet(widget)) {
|
if (widgetDirtyGet(widget)) {
|
||||||
widgetDirtySet(widget, 0);
|
widgetDirtySet(widget, 0);
|
||||||
// Find some colors.
|
// Find some colors.
|
||||||
if (widgetIsInWindow(widget, wmWindowOnTopGet())) {
|
if (widgetIsInWidget(widget, W(wmWindowOnTopGet()))) {
|
||||||
scrollBackgroundColor = GUI_DARKGRAY;
|
scrollBackgroundColor = GUI_DARKGRAY;
|
||||||
widgetColor = GUI_LIGHTGRAY;
|
widgetColor = GUI_LIGHTGRAY;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -414,8 +414,8 @@ static void windowDestroy(struct WidgetS *widget, ...) {
|
||||||
// Free the title.
|
// Free the title.
|
||||||
if (window->title) DEL(window->title);
|
if (window->title) DEL(window->title);
|
||||||
// Free children.
|
// Free children.
|
||||||
for (c=0; c<arrlen(window->children); c++) widgetDestroy(window->children[c]);
|
for (c=0; c<arrlen(window->base.children); c++) widgetDestroy(window->base.children[c]);
|
||||||
arrfree(window->children);
|
arrfree(window->base.children);
|
||||||
// Free cached surface.
|
// Free cached surface.
|
||||||
if (window->cached) surfaceDestroy(&window->cached);
|
if (window->cached) surfaceDestroy(&window->cached);
|
||||||
// Free content surface.
|
// Free content surface.
|
||||||
|
@ -649,12 +649,12 @@ static void windowPaint(struct WidgetS *widget, ...) {
|
||||||
|
|
||||||
// Are any child widgets dirty?
|
// Are any child widgets dirty?
|
||||||
y = 0;
|
y = 0;
|
||||||
for (x=0; x<arrlen(w->children); x++) {
|
for (x=0; x<arrlen(w->base.children); x++) {
|
||||||
if (widgetDirtyGet(w->children[x])) {
|
if (widgetDirtyGet(w->base.children[x])) {
|
||||||
y = 1;
|
y = 1;
|
||||||
if (w->children[x]->reg->paint) {
|
if (w->base.children[x]->reg->paint) {
|
||||||
surfaceSet(w->content);
|
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; i<arrlen(window->children); i++) {
|
|
||||||
if (window->children[i] == widget) {
|
|
||||||
arrdel(window->children, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void wmShutdown(void) {
|
void wmShutdown(void) {
|
||||||
uint16_t i;
|
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;
|
*localX = event->x - win->bounds.x + win->offset.x;
|
||||||
*localY = event->y - win->bounds.y + win->offset.y;
|
*localY = event->y - win->bounds.y + win->offset.y;
|
||||||
// Find widget under mouse.
|
// Find widget under mouse.
|
||||||
for (i=0; i<arrlen(win->children); i++) {
|
for (i=0; i<arrlen(win->base.children); i++) {
|
||||||
widget = win->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) {
|
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 this widget.
|
||||||
return widget;
|
return widget;
|
||||||
|
|
|
@ -69,7 +69,6 @@ typedef struct WindowS {
|
||||||
PointT offset; // Content scroll offset in window.
|
PointT offset; // Content scroll offset in window.
|
||||||
SurfaceT *content; // Actual window contents - widgets and such.
|
SurfaceT *content; // Actual window contents - widgets and such.
|
||||||
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
|
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
|
||||||
WidgetT **children; // Widgets contained in the window.
|
|
||||||
} WindowT;
|
} WindowT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,8 +82,6 @@ void windowMinimize(WindowT *win);
|
||||||
void windowMove(WindowT *win, uint16_t x, uint16_t y);
|
void windowMove(WindowT *win, uint16_t x, uint16_t y);
|
||||||
RegisterT *windowRegister(uint8_t magic);
|
RegisterT *windowRegister(uint8_t magic);
|
||||||
void windowResize(WindowT *win, uint16_t width, uint16_t height);
|
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);
|
void wmShutdown(void);
|
||||||
|
|
|
@ -73,38 +73,38 @@ int main(int argc, char *argv[]) {
|
||||||
l = labelCreate(LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label");
|
l = labelCreate(LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label");
|
||||||
labelColorSet(l, __guiBaseColors[i], GUI_BLACK);
|
labelColorSet(l, __guiBaseColors[i], GUI_BLACK);
|
||||||
labelClickSet(l, clickHandler, title);
|
labelClickSet(l, clickHandler, title);
|
||||||
windowWidgetAdd(w, 20, 10, W(l));
|
widgetAdd(W(w), 20, 10, W(l));
|
||||||
|
|
||||||
b = buttonCreate("Button", clickHandler, NULL);
|
b = buttonCreate("Button", clickHandler, NULL);
|
||||||
windowWidgetAdd(w, 20, 40, W(b));
|
widgetAdd(W(w), 20, 40, W(b));
|
||||||
|
|
||||||
c = checkboxCreate("Checkbox", 0);
|
c = checkboxCreate("Checkbox", 0);
|
||||||
windowWidgetAdd(w, 20, 80, W(c));
|
widgetAdd(W(w), 20, 80, W(c));
|
||||||
|
|
||||||
r = radioCreate("Radio 1", 0, 1);
|
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);
|
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);
|
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);
|
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);
|
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);
|
r = radioCreate("Radio C", 1, 0);
|
||||||
windowWidgetAdd(w, 220, 140, W(r));
|
widgetAdd(W(w), 220, 140, W(r));
|
||||||
|
|
||||||
_v = vscrollCreate(100, clickHandler, NULL);
|
_v = vscrollCreate(100, clickHandler, NULL);
|
||||||
vscrollRangeSet(_v, 0, 640);
|
vscrollRangeSet(_v, 0, 640);
|
||||||
windowWidgetAdd(w, 200, 5, W(_v));
|
widgetAdd(W(w), 200, 5, W(_v));
|
||||||
|
|
||||||
_h = hscrollCreate(100, clickHandler, NULL);
|
_h = hscrollCreate(100, clickHandler, NULL);
|
||||||
hscrollRangeSet(_h, 0, 640);
|
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);
|
s = scrollableCreate(300, 200, 648, 480, SCROLLABLE_STANDARD);
|
||||||
windowWidgetAdd(w, 20, 170, W(s));
|
widgetAdd(W(w), 20, 170, W(s));
|
||||||
}
|
}
|
||||||
guiRun();
|
guiRun();
|
||||||
guiShutdown();
|
guiShutdown();
|
||||||
|
|
Loading…
Add table
Reference in a new issue