142 lines
4.2 KiB
C
142 lines
4.2 KiB
C
/*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "button.h"
|
|
|
|
|
|
static void buttonDel(WidgetT **widget);
|
|
static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
|
static void buttonPaint(WidgetT *widget, RectT pos);
|
|
|
|
|
|
void buttonClickHandlerSet(ButtonT *button, widgetCallback callback) {
|
|
button->clicked = callback;
|
|
}
|
|
|
|
|
|
static 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;
|
|
|
|
buttonClickHandlerSet(b, callback);
|
|
|
|
// Width is set in buttonSetTitle
|
|
buttonTitleSet(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++) {
|
|
surfaceHighlightFrameDraw(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).
|
|
surfaceRectangleFilledDraw(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 buttonTitleSet(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);
|
|
}
|