/* * 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); void buttonDel(WidgetT **widget) { ButtonT *b = (ButtonT *)*widget; if (b->title) free(b->title); free(b); b = NULL; } WidgetT *buttonInit(WidgetT *button, uint16_t x, uint16_t y, char *title, widgetCallback callback) { ButtonT *b = (ButtonT *)button; b->base.magic = MAGIC_BUTTON; b->base.x = x; b->base.y = y; b->base.delMethod = buttonDel; b->base.paintMethod = buttonPaint; b->base.mouseEventMethod = buttonMouseEvent; b->title = NULL; buttonSetClickHandler(b, callback); buttonSetTitle(b, title); // Width is set in buttonSetTitle b->base.h = fontHeightGet(_guiFont) + (_guiMetric[METRIC_BUTTON_VERTICAL_PADDING] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2); 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; if (!button) return NULL; widget = widgetInit((WidgetT *)button); if (!widget) { free(button); return NULL; } button = (ButtonT *)buttonInit((WidgetT *)button, x, y, title, callback); return button; } static void buttonPaint(WidgetT *widget) { ButtonT *b = (ButtonT *)widget; int16_t i; int8_t active = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE); ColorT highlight = active ? _guiColor[COLOR_BUTTON_SHADOW] : _guiColor[COLOR_BUTTON_HIGHLIGHT]; ColorT shadow = active ? _guiColor[COLOR_BUTTON_HIGHLIGHT] : _guiColor[COLOR_BUTTON_SHADOW] ; if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { vbeSurfaceSet(b->base.surface); // Draw bezel. for (i=0; i<_guiMetric[METRIC_BUTTON_BEZEL_SIZE]; i++) { guiDrawHighlightFrame(b->base.x + i, b->base.y + i, b->base.x + b->base.w - i, b->base.y + b->base.h - i, highlight, shadow); } // Draw background (depends on x from above). guiDrawRectangleFilled(b->base.x + i, b->base.y + i, b->base.x + b->base.w - i, b->base.y + b->base.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], b->base.x + i + _guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] + active, b->base.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.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); }