diff --git a/roo-e/src/gui/widgets/button.c b/roo-e/src/gui/widgets/button.c new file mode 100644 index 0000000..f376866 --- /dev/null +++ b/roo-e/src/gui/widgets/button.c @@ -0,0 +1,134 @@ +/* + * 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 "button.h" + + +uint8_t __MAGIC_BUTTON = 0; + + +static void buttonClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data); +static void buttonDestroy(struct WidgetS *widget, ...); +static void buttonPaint(struct WidgetS *widget, ...); + + +static void buttonClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) { + ButtonT *b = (ButtonT *)widget; + + switch (event) { + case CLICK_LEFT_DOWN: + b->isPressed = 1; + break; + + case CLICK_LEFT_UP: + b->isPressed = 0; + // Call the actual click event. + b->handler(widget, x, y, event, data); + break; + + case CLICK_LEFT_CANCEL: + b->isPressed = 0; + break; + } + + guiWidgetDirtySet(widget, 1); +} + + +void buttonClickSet(ButtonT *button, ClickHandlerT handler, void *data) { + button->handler = handler; + button->base.data = data; +} + + +ButtonT *buttonCreate(char *label, ClickHandlerT handler, void *data, ...) { + ButtonT *b = NULL; + uint16_t width; + uint16_t height; + FontT *f = __guiFontVGA8x16; + + NEW(ButtonT, b); + memset(b, 0, sizeof(ButtonT)); + + b->offset.x = 8; // 8 = two border, 6 padding. + b->offset.y = 4; // 4 = two border, two padding. + b->label = labelCreate(LABEL_ALIGN_LEFT, f, label); + if (!b->label) { + DEL(b); + return NULL; + } + + width = fontWidthCharactersGet(label) * fontWidthGet(f) + (b->offset.x * 2); + height = fontHeightGet(f) + (b->offset.y * 2); + + guiWidgetBaseSet(W(b), __MAGIC_BUTTON, width, height); + + buttonClickSet(b, handler, data); + + return b; +} + + +static void buttonDestroy(struct WidgetS *widget, ...) { + ButtonT *b = (ButtonT *)widget; + + guiWidgetDestroy(W(b->label)); + DEL(b); +} + + +static void buttonPaint(struct WidgetS *widget, ...) { + ButtonT *b = (ButtonT *)widget; + ColorT h = b->isPressed ? GUI_BLACK : GUI_WHITE; + ColorT s = b->isPressed ? GUI_WHITE : GUI_BLACK; + + if (guiWidgetDirtyGet(widget)) { + guiWidgetDirtySet(widget, 0); + // Paint button. + surfaceBoxHighlight(b->base.r.x, b->base.r.y, b->base.r.x + b->base.r.x2 - 1, b->base.r.y + b->base.r.y2 - 1, h, s); + surfaceBoxHighlight(b->base.r.x + 1, b->base.r.y + 1, b->base.r.x + b->base.r.x2 - 2, b->base.r.y + b->base.r.y2 - 2, h, s); + surfaceBoxFilled(b->base.r.x + 2, b->base.r.y + 2, b->base.r.x + b->base.r.x2 - 3, b->base.r.y + b->base.r.y2 - 3, GUI_LIGHTGRAY); + // Paint label. + guiWidgetPaintManually(W(b->label), b->base.r.x + b->offset.x + b->isPressed, b->base.r.y + b->offset.y + b->isPressed); + } +} + + +RegisterT *buttonRegister(uint8_t magic) { + static RegisterT reg = { + "Button", + buttonClick, + buttonDestroy, + buttonPaint, + NULL // No unregister handler. + }; + + // One-time widget startup code. + __MAGIC_BUTTON = magic; + + return ® +} diff --git a/roo-e/src/gui/widgets/button.h b/roo-e/src/gui/widgets/button.h new file mode 100644 index 0000000..de52041 --- /dev/null +++ b/roo-e/src/gui/widgets/button.h @@ -0,0 +1,51 @@ +/* + * 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 BUTTON_H +#define BUTTON_H + + +#include "../gui.h" +#include "label.h" + + +typedef struct ButtonS { + WidgetT base; // Required by all widgets. + LabelT *label; // Label to display text. + PointT offset; // Offset of label in button. + ClickHandlerT handler; // Actual event handler. + uint8_t isPressed; // Is the button being pressed? +} ButtonT; + + +extern uint8_t __MAGIC_BUTTON; // Magic ID assigned to us from the GUI. + + +void buttonClickSet(ButtonT *button, ClickHandlerT handler, void *data); +ButtonT *buttonCreate(char *label, ClickHandlerT handler, void *data, ...); +RegisterT *buttonRegister(uint8_t magic); + + +#endif // BUTTON_H