/* * Kangaroo Punch MultiPlayer Game Server Mark II * Copyright (C) 2020-2021 Scott Duensing * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License * along with this program. If not, see . * */ #include "button.h" static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event); static void buttonPaint(WidgetT *widget, RectT pos); void buttonDel(WidgetT **widget) { ButtonT *b = (ButtonT *)*widget; if (b->title) free(b->title); free(b); b = NULL; } WidgetT *buttonInit(WidgetT *button, char *title, widgetCallback callback) { ButtonT *b = (ButtonT *)button; b->base.delMethod = buttonDel; b->base.paintMethod = buttonPaint; b->base.mouseEventMethod = buttonMouseEvent; b->title = NULL; buttonSetClickHandler(b, callback); // Width is set in buttonSetTitle buttonSetTitle(b, title); return button; } static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) { ButtonT *b = (ButtonT *)widget; (void)x; (void)y; (void)mouse; // Button pressed? if (event == MOUSE_EVENT_LEFT_HOLD) { if (!GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) { GUI_SET_FLAG(widget, WIDGET_FLAG_ACTIVE); GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY); } } else { if (GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) { GUI_CLEAR_FLAG(widget, WIDGET_FLAG_ACTIVE); GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY); } } // Fire callback on mouse up. if (event == MOUSE_EVENT_LEFT_UP) { if (b->clicked) b->clicked(widget); } } ButtonT *buttonNew(uint16_t x, uint16_t y, char *title, widgetCallback callback) { ButtonT *button = (ButtonT *)malloc(sizeof(ButtonT)); WidgetT *widget = NULL; uint16_t h = fontHeightGet(_guiFont) + (_guiMetric[METRIC_BUTTON_VERTICAL_PADDING] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2); if (!button) return NULL; // Width is set in Init. widget = widgetInit(W(button), MAGIC_BUTTON, x, y, 0, h, 0, 0, 0, 0); if (!widget) { free(button); return NULL; } button = (ButtonT *)buttonInit((WidgetT *)button, title, callback); return button; } static void buttonPaint(WidgetT *widget, RectT pos) { ButtonT *b; int16_t i; int8_t active; ColorT highlight; ColorT shadow; if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { b = (ButtonT *)widget; active = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE); highlight = active ? _guiColor[COLOR_BUTTON_SHADOW] : _guiColor[COLOR_BUTTON_HIGHLIGHT]; shadow = active ? _guiColor[COLOR_BUTTON_HIGHLIGHT] : _guiColor[COLOR_BUTTON_SHADOW]; // Draw bezel. for (i=0; i<_guiMetric[METRIC_BUTTON_BEZEL_SIZE]; i++) { guiDrawHighlightFrame(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, highlight, shadow); } // Draw background (depends on x from above). guiDrawRectangleFilled(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, _guiColor[COLOR_BUTTON_BACKGROUND]); // Draw title (depends on x from above). fontRender(_guiFont, b->title, _guiColor[COLOR_BUTTON_TEXT], _guiColor[COLOR_BUTTON_BACKGROUND], pos.x + i + _guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] + active, pos.y + i + _guiMetric[METRIC_BUTTON_VERTICAL_PADDING] + active); GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY); } } void buttonSetClickHandler(ButtonT *button, widgetCallback callback) { button->clicked = callback; } void buttonSetTitle(ButtonT *button, char *title) { if (button->title) free(button->title); button->title = strdup(title); button->base.pos.w = (strlen(title) * fontWidthGet(_guiFont)) + (_guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2); GUI_SET_FLAG((WidgetT *)button, WIDGET_FLAG_DIRTY); }