/* * 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 "checkbox.h" static void checkboxDel(WidgetT **widget); static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event); static void checkboxPaint(WidgetT *widget, RectT pos); void checkboxClickHandlerSet(CheckboxT *checkbox, widgetCallback callback) { checkbox->clicked = callback; } static void checkboxDel(WidgetT **widget) { CheckboxT *c = (CheckboxT *)*widget; if (c->title) free(c->title); free(c); c = NULL; } WidgetT *checkboxInit(WidgetT *widget, char *title) { CheckboxT *c = (CheckboxT *)widget; c->base.delMethod = checkboxDel; c->base.paintMethod = checkboxPaint; c->base.mouseEventMethod = checkboxMouseEvent; c->title = NULL; c->clicked = NULL; checkboxTitleSet(c, title); return widget; } static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) { CheckboxT *c = (CheckboxT *)widget; (void)x; (void)y; (void)mouse; if (event == MOUSE_EVENT_LEFT_UP) { // Toggle value. checkboxValueSet(c, !checkboxValueGet(c)); // Fire callback on mouse up. if (c->clicked) c->clicked(widget); } } CheckboxT *checkboxNew(uint16_t x, uint16_t y, char *title) { CheckboxT *checkbox = (CheckboxT *)malloc(sizeof(CheckboxT)); WidgetT *widget = NULL; uint16_t h = fontHeightGet(_guiFont); if (!checkbox) return NULL; // Width is set in Init widget = widgetInit(W(checkbox), MAGIC_CHECKBOX, x, y, 0, h, 0, 0, 0, 0); if (!widget) { free(checkbox); return NULL; } checkbox = (CheckboxT *)checkboxInit((WidgetT *)checkbox, title); return checkbox; } static void checkboxPaint(WidgetT *widget, RectT pos) { CheckboxT *c = (CheckboxT *)widget; int16_t o; int8_t active; ColorT highlight; ColorT shadow; ColorT fill; if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) { active = checkboxValueGet(c); highlight = active ? _guiColor[COLOR_CHECKBOX_SHADOW] : _guiColor[COLOR_CHECKBOX_HIGHLIGHT]; shadow = active ? _guiColor[COLOR_CHECKBOX_HIGHLIGHT] : _guiColor[COLOR_CHECKBOX_SHADOW]; fill = active ? _guiColor[COLOR_CHECKBOX_ACTIVE] : _guiColor[COLOR_CHECKBOX_INACTIVE]; // Checkbox is 10x10 pixels. Find offset based on font height. o = (_guiFont->height - 10) * 0.5; // Draw outline of checkbox. surfaceHighlightFrameDraw(pos.x, pos.y + o, pos.x + 10, pos.y + 10 + o, highlight, shadow); // Draw background. surfaceRectangleFilledDraw(pos.x + 1, pos.y + o + 1, pos.x + 9, pos.y + + o + 9, fill); // Draw title. fontRender(_guiFont, c->title, _guiColor[COLOR_CHECKBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x + 10 + _guiMetric[METRIC_CHECKBOX_PADDING], pos.y); GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY); } } void checkboxTitleSet(CheckboxT *checkbox, char *title) { if (checkbox->title) free(checkbox->title); checkbox->title = strdup(title); checkbox->base.pos.w = (strlen(title) * fontWidthGet(_guiFont)) + 10 + _guiMetric[METRIC_CHECKBOX_PADDING]; GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY); } uint8_t checkboxValueGet(CheckboxT *checkbox) { return GUI_GET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE); } void checkboxValueSet(CheckboxT *checkbox, uint8_t selected) { if (selected) { if (!checkboxValueGet(checkbox)) { GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE); GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY); } } else { if (checkboxValueGet(checkbox)) { GUI_CLEAR_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE); GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY); } } }