diff --git a/roo-e/roo-e.pro b/roo-e/roo-e.pro index 9294546..b097fa9 100644 --- a/roo-e/roo-e.pro +++ b/roo-e/roo-e.pro @@ -53,6 +53,7 @@ HEADERS += \ src/gui/image.h \ src/gui/surface.h \ src/gui/widgets/button.h \ + src/gui/widgets/checkbox.h \ src/gui/widgets/label.h \ src/gui/widgets/picture.h \ src/gui/wmwindow.h \ @@ -71,6 +72,7 @@ SOURCES += \ src/gui/image.c \ src/gui/surface.c \ src/gui/widgets/button.c \ + src/gui/widgets/checkbox.c \ src/gui/widgets/label.c \ src/gui/widgets/picture.c \ src/gui/wmwindow.c \ diff --git a/roo-e/src/gui/gui.c b/roo-e/src/gui/gui.c index b26b59b..79c7492 100644 --- a/roo-e/src/gui/gui.c +++ b/roo-e/src/gui/gui.c @@ -30,6 +30,7 @@ #include "wmwindow.h" #include "widgets/button.h" +#include "widgets/checkbox.h" #include "widgets/label.h" #include "widgets/picture.h" @@ -195,10 +196,10 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) { // Register standard widgets. guiRegister(windowRegister); - guiRegister(labelRegister); - guiRegister(pictureRegister); + guiRegister(labelRegister); // Above other widgets in list since many depend on Label. guiRegister(buttonRegister); - + guiRegister(checkboxRegister); + guiRegister(pictureRegister); return SUCCESS; } diff --git a/roo-e/src/gui/widgets/checkbox.c b/roo-e/src/gui/widgets/checkbox.c new file mode 100644 index 0000000..d557bdd --- /dev/null +++ b/roo-e/src/gui/widgets/checkbox.c @@ -0,0 +1,138 @@ +/* + * Roo/E, the Kangaroo Punch Portable GUI Toolkit + * Copyright (C) 2022 Scott Duensing + * + * http://kangaroopunch.com + * + * + * This file is part of Roo/E. + * + * Roo/E is free software: you can redistribute it and/or modify it under the + * terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Roo/E. If not, see . + * + */ + + +#include "../wmwindow.h" + +#include "checkbox.h" + + +uint8_t __MAGIC_CHECKBOX = 0; + + +static void checkboxClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data); +static void checkboxDestroy(struct WidgetS *widget, ...); +static void checkboxPaint(struct WidgetS *widget, ...); + + +static void checkboxClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) { + CheckboxT *c = (CheckboxT *)widget; + + if (event == CLICK_LEFT_UP) { + // Toggle value. + c->value = !c->value; + + // Call the actual click event if it exists. + if (c->handler) c->handler(widget, x, y, event, data); + + // Repaint. + guiWidgetDirtySet(widget, 1); + } +} + + +void checkboxClickSet(CheckboxT *checkbox, ClickHandlerT handler, void *data) { + checkbox->handler = handler; + checkbox->base.data = data; +} + + +CheckboxT *checkboxCreate(char *label, uint8_t value, ...) { + CheckboxT *c = NULL; + uint16_t width; + uint16_t height; + FontT *f = __guiFontVGA8x16; + + NEW(CheckboxT, c); + memset(c, 0, sizeof(CheckboxT)); + + c->value = value; + c->label = labelCreate(LABEL_ALIGN_LEFT, f, label); + if (!c->label) { + DEL(c); + return NULL; + } + + // Checkbox is (height - 3) square. We skip two pixels on the bottom and one on the top to look okay with decender characters. + height = fontHeightGet(f); + width = fontWidthCharactersGet(label) * fontWidthGet(f) + (height * 3); + + guiWidgetBaseSet(W(c), __MAGIC_CHECKBOX, width, height); + + return c; +} + + +static void checkboxDestroy(struct WidgetS *widget, ...) { + CheckboxT *c = (CheckboxT *)widget; + + guiWidgetDestroy(W(c->label)); + DEL(c); +} + + +static void checkboxPaint(struct WidgetS *widget, ...) { + CheckboxT *c = (CheckboxT *)widget; + int16_t w; + int16_t h; + + if (guiWidgetDirtyGet(widget)) { + guiWidgetDirtySet(widget, 0); + h = fontHeightGet(c->label->font) - 2; + w = h * 1.5; + // Paint checkbox. + surfaceBoxHighlight(c->base.r.x, c->base.r.y + 1, c->base.r.x + h, c->base.r.y + h, GUI_BLACK, GUI_WHITE); + surfaceBoxFilled(c->base.r.x + 1, c->base.r.y + 2, c->base.r.x + h - 1, c->base.r.y + h - 1, c->value ? GUI_DARKGRAY : GUI_WHITE); + // Paint label. + guiWidgetPaintManually(W(c->label), c->base.r.x + w, c->base.r.y); + } +} + + +RegisterT *checkboxRegister(uint8_t magic) { + static RegisterT reg = { + "Checkbox", + checkboxClick, + checkboxDestroy, + checkboxPaint, + NULL // No unregister handler. + }; + + // One-time widget startup code. + __MAGIC_CHECKBOX = magic; + + return ® +} + + +uint8_t checkboxValueGet(CheckboxT *checkbox) { + return checkbox->value; +} + + +void checkboxValueSet(CheckboxT *checkbox, uint8_t value) { + checkbox->value = (value != 0); + // Repaint. + guiWidgetDirtySet(W(checkbox), 1); +} diff --git a/roo-e/src/gui/widgets/checkbox.h b/roo-e/src/gui/widgets/checkbox.h new file mode 100644 index 0000000..dc3ffaa --- /dev/null +++ b/roo-e/src/gui/widgets/checkbox.h @@ -0,0 +1,52 @@ +/* + * Roo/E, the Kangaroo Punch Portable GUI Toolkit + * Copyright (C) 2022 Scott Duensing + * + * http://kangaroopunch.com + * + * + * This file is part of Roo/E. + * + * Roo/E is free software: you can redistribute it and/or modify it under the + * terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Roo/E. If not, see . + * + */ + + +#ifndef CHECKBOX_H +#define CHECKBOX_H + + +#include "../gui.h" +#include "label.h" + + +typedef struct CheckboxS { + WidgetT base; // Required by all widgets. + LabelT *label; // Label to display text. + ClickHandlerT handler; // Actual event handler. + uint8_t value; // Is the button being pressed? +} CheckboxT; + + +extern uint8_t __MAGIC_CHECKBOX; // Magic ID assigned to us from the GUI. + + +void checkboxClickSet(CheckboxT *checkbox, ClickHandlerT handler, void *data); +CheckboxT *checkboxCreate(char *label, uint8_t value, ...); +RegisterT *checkboxRegister(uint8_t magic); +uint8_t checkboxValueGet(CheckboxT *checkbox); +void checkboxValueSet(CheckboxT *checkbox, uint8_t value); + + +#endif // CHECKBOX_H diff --git a/roo-e/src/main.c b/roo-e/src/main.c index aeb829c..9f55fef 100644 --- a/roo-e/src/main.c +++ b/roo-e/src/main.c @@ -28,6 +28,7 @@ #include "gui/widgets/label.h" #include "gui/widgets/picture.h" #include "gui/widgets/button.h" +#include "gui/widgets/checkbox.h" void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) { @@ -37,11 +38,12 @@ void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void * int main(int argc, char *argv[]) { - char title[256]; - uint16_t i; - LabelT *l = NULL; - ButtonT *b = NULL; - WindowT *w = NULL; + char title[256]; + uint16_t i; + LabelT *l = NULL; + ButtonT *b = NULL; + CheckboxT *c = NULL; + WindowT *w = NULL; (void)argc; @@ -61,6 +63,9 @@ int main(int argc, char *argv[]) { b = buttonCreate("Button", clickHandler, NULL); windowWidgetAdd(w, 20, 40, W(b)); + + c = checkboxCreate("Checkbox", 0); + windowWidgetAdd(w, 20, 80, W(c)); } guiRun(); guiShutdown();