Fixes, new widgets: Checkbox, Frame, Label, Picture, Radio Button.
This commit is contained in:
parent
abcc4f2071
commit
7c531861a4
22 changed files with 1130 additions and 37 deletions
|
@ -45,7 +45,12 @@ INCLUDEPATH += \
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
$$LINUX_HEADERS \
|
$$LINUX_HEADERS \
|
||||||
src/gui/button.h \
|
src/gui/button.h \
|
||||||
|
src/gui/checkbox.h \
|
||||||
|
src/gui/frame.h \
|
||||||
src/gui/keyboard.h \
|
src/gui/keyboard.h \
|
||||||
|
src/gui/label.h \
|
||||||
|
src/gui/picture.h \
|
||||||
|
src/gui/radio.h \
|
||||||
src/gui/task.h \
|
src/gui/task.h \
|
||||||
src/thirdparty/stb_ds.h \
|
src/thirdparty/stb_ds.h \
|
||||||
src/thirdparty/stb_leakcheck.h \
|
src/thirdparty/stb_leakcheck.h \
|
||||||
|
@ -67,9 +72,14 @@ SOURCES = \
|
||||||
$$LINUX_SOURCES \
|
$$LINUX_SOURCES \
|
||||||
src/gui/array.c \
|
src/gui/array.c \
|
||||||
src/gui/button.c \
|
src/gui/button.c \
|
||||||
|
src/gui/checkbox.c \
|
||||||
src/gui/font.c \
|
src/gui/font.c \
|
||||||
src/gui/desktop.c \
|
src/gui/desktop.c \
|
||||||
|
src/gui/frame.c \
|
||||||
src/gui/gui.c \
|
src/gui/gui.c \
|
||||||
|
src/gui/label.c \
|
||||||
|
src/gui/picture.c \
|
||||||
|
src/gui/radio.c \
|
||||||
src/gui/task.c \
|
src/gui/task.c \
|
||||||
src/gui/widget.c \
|
src/gui/widget.c \
|
||||||
src/gui/window.c \
|
src/gui/window.c \
|
||||||
|
|
BIN
client/data/kanga.png
(Stored with Git LFS)
Normal file
BIN
client/data/kanga.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
|
|
||||||
|
|
||||||
static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
||||||
static void buttonPaint(WidgetT *widget);
|
static void buttonPaint(WidgetT *widget);
|
||||||
|
|
||||||
|
@ -43,8 +44,8 @@ WidgetT *buttonInit(WidgetT *button, uint16_t x, uint16_t y, char *title, widget
|
||||||
b->base.paintMethod = buttonPaint;
|
b->base.paintMethod = buttonPaint;
|
||||||
b->base.mouseEventMethod = buttonMouseEvent;
|
b->base.mouseEventMethod = buttonMouseEvent;
|
||||||
b->title = NULL;
|
b->title = NULL;
|
||||||
b->clicked = callback;
|
|
||||||
|
|
||||||
|
buttonSetClickHandler(b, callback);
|
||||||
buttonSetTitle(b, title);
|
buttonSetTitle(b, title);
|
||||||
|
|
||||||
// Width is set in buttonSetTitle
|
// Width is set in buttonSetTitle
|
||||||
|
@ -102,8 +103,9 @@ ButtonT *buttonNew(uint16_t x, uint16_t y, char *title, widgetCallback callback)
|
||||||
static void buttonPaint(WidgetT *widget) {
|
static void buttonPaint(WidgetT *widget) {
|
||||||
ButtonT *b = (ButtonT *)widget;
|
ButtonT *b = (ButtonT *)widget;
|
||||||
int16_t i;
|
int16_t i;
|
||||||
ColorT highlight = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_BUTTON_SHADOW] : _guiColor[COLOR_BUTTON_HIGHLIGHT];
|
int8_t active = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE);
|
||||||
ColorT shadow = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? _guiColor[COLOR_BUTTON_HIGHLIGHT] : _guiColor[COLOR_BUTTON_SHADOW] ;
|
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)) {
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
vbeSurfaceSet(b->base.surface);
|
vbeSurfaceSet(b->base.surface);
|
||||||
|
@ -117,15 +119,21 @@ static void buttonPaint(WidgetT *widget) {
|
||||||
guiDrawFilledRectangle(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]);
|
guiDrawFilledRectangle(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).
|
// 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_MARGIN], b->base.y + i + _guiMetric[METRIC_BUTTON_VERTICAL_MARGIN]);
|
fontRender(_guiFont, b->title, _guiColor[COLOR_BUTTON_TEXT], _guiColor[COLOR_BUTTON_BACKGROUND], b->base.x + i + _guiMetric[METRIC_BUTTON_HORIZONTAL_MARGIN] + active, b->base.y + i + _guiMetric[METRIC_BUTTON_VERTICAL_MARGIN] + active);
|
||||||
|
|
||||||
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void buttonSetClickHandler(ButtonT *button, widgetCallback callback) {
|
||||||
|
button->clicked = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void buttonSetTitle(ButtonT *button, char *title) {
|
void buttonSetTitle(ButtonT *button, char *title) {
|
||||||
if (button->title) free(button->title);
|
if (button->title) free(button->title);
|
||||||
button->title = strdup(title);
|
button->title = strdup(title);
|
||||||
button->base.w = (strlen(title) * fontWidthGet(_guiFont)) + (_guiMetric[METRIC_BUTTON_HORIZONTAL_MARGIN] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2);
|
button->base.w = (strlen(title) * fontWidthGet(_guiFont)) + (_guiMetric[METRIC_BUTTON_HORIZONTAL_MARGIN] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2);
|
||||||
|
GUI_SET_FLAG((WidgetT *)button, WIDGET_FLAG_DIRTY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ typedef struct ButtonS {
|
||||||
void buttonDel(WidgetT **widget);
|
void buttonDel(WidgetT **widget);
|
||||||
WidgetT *buttonInit(WidgetT *button, uint16_t x, uint16_t y, char *title, widgetCallback callback);
|
WidgetT *buttonInit(WidgetT *button, uint16_t x, uint16_t y, char *title, widgetCallback callback);
|
||||||
ButtonT *buttonNew(uint16_t x, uint16_t y, char *title, widgetCallback callback);
|
ButtonT *buttonNew(uint16_t x, uint16_t y, char *title, widgetCallback callback);
|
||||||
|
void buttonSetClickHandler(ButtonT *button, widgetCallback callback);
|
||||||
void buttonSetTitle(ButtonT *button, char *title);
|
void buttonSetTitle(ButtonT *button, char *title);
|
||||||
|
|
||||||
|
|
||||||
|
|
151
client/src/gui/checkbox.c
Normal file
151
client/src/gui/checkbox.c
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* 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 "checkbox.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
||||||
|
static void checkboxPaint(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
void checkboxDel(WidgetT **widget) {
|
||||||
|
CheckboxT *c = (CheckboxT *)*widget;
|
||||||
|
|
||||||
|
if (c->title) free(c->title);
|
||||||
|
free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t checkboxGetValue(CheckboxT *checkbox) {
|
||||||
|
return GUI_GET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *checkboxInit(WidgetT *widget, uint16_t x, uint16_t y, char *title) {
|
||||||
|
CheckboxT *c = (CheckboxT *)widget;
|
||||||
|
|
||||||
|
c->base.magic = MAGIC_CHECKBOX;
|
||||||
|
c->base.x = x;
|
||||||
|
c->base.y = y;
|
||||||
|
c->base.delMethod = checkboxDel;
|
||||||
|
c->base.paintMethod = checkboxPaint;
|
||||||
|
c->base.mouseEventMethod = checkboxMouseEvent;
|
||||||
|
c->title = NULL;
|
||||||
|
c->clicked = NULL;
|
||||||
|
|
||||||
|
checkboxSetTitle(c, title);
|
||||||
|
|
||||||
|
// Width is set in checkboxSetTitle
|
||||||
|
c->base.h = fontHeightGet(_guiFont);
|
||||||
|
|
||||||
|
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.
|
||||||
|
checkboxSetValue(c, !checkboxGetValue(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;
|
||||||
|
|
||||||
|
if (!checkbox) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit((WidgetT *)checkbox);
|
||||||
|
if (!widget) {
|
||||||
|
free(checkbox);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox = (CheckboxT *)checkboxInit((WidgetT *)checkbox, x, y, title);
|
||||||
|
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void checkboxPaint(WidgetT *widget) {
|
||||||
|
CheckboxT *c = (CheckboxT *)widget;
|
||||||
|
int16_t o;
|
||||||
|
int8_t active = checkboxGetValue(c);
|
||||||
|
ColorT highlight = active ? _guiColor[COLOR_CHECKBOX_SHADOW] : _guiColor[COLOR_CHECKBOX_HIGHLIGHT];
|
||||||
|
ColorT shadow = active ? _guiColor[COLOR_CHECKBOX_HIGHLIGHT] : _guiColor[COLOR_CHECKBOX_SHADOW];
|
||||||
|
ColorT fill = active ? _guiColor[COLOR_CHECKBOX_ACTIVE] : _guiColor[COLOR_CHECKBOX_INACTIVE];
|
||||||
|
|
||||||
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
|
vbeSurfaceSet(c->base.surface);
|
||||||
|
|
||||||
|
// Checkbox is 10x10 pixels. Find offset based on font height.
|
||||||
|
o = (_guiFont->height - 10) * 0.5;
|
||||||
|
|
||||||
|
// Draw outline of checkbox.
|
||||||
|
guiDrawHighlightFrame(c->base.x, c->base.y + o, c->base.x + 10, c->base.y + 10 + o, highlight, shadow);
|
||||||
|
|
||||||
|
// Draw background.
|
||||||
|
guiDrawFilledRectangle(c->base.x + 1, c->base.y + o + 1, c->base.x + 9, c->base.y + + o + 9, fill);
|
||||||
|
|
||||||
|
// Draw title.
|
||||||
|
fontRender(_guiFont, c->title, _guiColor[COLOR_CHECKBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], c->base.x + 10 + _guiMetric[METRIC_CHECKBOX_PADDING], c->base.y);
|
||||||
|
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkboxSetClickHandler(CheckboxT *checkbox, widgetCallback callback) {
|
||||||
|
checkbox->clicked = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkboxSetTitle(CheckboxT *checkbox, char *title) {
|
||||||
|
if (checkbox->title) free(checkbox->title);
|
||||||
|
checkbox->title = strdup(title);
|
||||||
|
checkbox->base.w = (strlen(title) * fontWidthGet(_guiFont)) + 10 + _guiMetric[METRIC_CHECKBOX_PADDING];
|
||||||
|
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkboxSetValue(CheckboxT *checkbox, uint8_t selected) {
|
||||||
|
if (selected) {
|
||||||
|
if (!checkboxGetValue(checkbox)) {
|
||||||
|
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
|
||||||
|
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkboxGetValue(checkbox)) {
|
||||||
|
GUI_CLEAR_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
|
||||||
|
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
45
client/src/gui/checkbox.h
Normal file
45
client/src/gui/checkbox.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CHECKBOX_H
|
||||||
|
#define CHECKBOX_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct CheckboxS {
|
||||||
|
WidgetT base; // Must be first in every widget
|
||||||
|
char *title;
|
||||||
|
widgetCallback clicked;
|
||||||
|
} CheckboxT;
|
||||||
|
|
||||||
|
|
||||||
|
void checkboxDel(WidgetT **widget);
|
||||||
|
uint8_t checkboxGetValue(CheckboxT *checkbox);
|
||||||
|
WidgetT *checkboxInit(WidgetT *widget, uint16_t x, uint16_t y, char *title);
|
||||||
|
CheckboxT *checkboxNew(uint16_t x, uint16_t y, char *title);
|
||||||
|
void checkboxSetClickHandler(CheckboxT *checkbox, widgetCallback callback);
|
||||||
|
void checkboxSetTitle(CheckboxT *checkbox, char *title);
|
||||||
|
void checkboxSetValue(CheckboxT *checkbox, uint8_t selected);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CHECKBOX_H
|
101
client/src/gui/frame.c
Normal file
101
client/src/gui/frame.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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 "frame.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void framePaint(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
void frameDel(WidgetT **widget) {
|
||||||
|
FrameT *f = (FrameT *)*widget;
|
||||||
|
|
||||||
|
if (f->title) free(f->title);
|
||||||
|
free(f);
|
||||||
|
f = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *frameInit(WidgetT *widget, uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title) {
|
||||||
|
FrameT *f = (FrameT *)widget;
|
||||||
|
|
||||||
|
f->base.magic = MAGIC_FRAME;
|
||||||
|
f->base.x = x;
|
||||||
|
f->base.y = y;
|
||||||
|
f->base.w = w;
|
||||||
|
f->base.h = h;
|
||||||
|
f->base.delMethod = frameDel;
|
||||||
|
f->base.paintMethod = framePaint;
|
||||||
|
f->title = NULL;
|
||||||
|
|
||||||
|
f->base.marginX += 3;
|
||||||
|
f->base.marginY += 9;
|
||||||
|
|
||||||
|
frameSetTitle(f, title);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FrameT *frameNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title) {
|
||||||
|
FrameT *frame = (FrameT *)malloc(sizeof(FrameT));
|
||||||
|
WidgetT *widget = NULL;
|
||||||
|
|
||||||
|
if (!frame) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit((WidgetT *)frame);
|
||||||
|
if (!widget) {
|
||||||
|
free(frame);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = (FrameT *)frameInit((WidgetT *)frame, x, y, w, h, title);
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void framePaint(WidgetT *widget) {
|
||||||
|
FrameT *f = (FrameT *)widget;
|
||||||
|
uint16_t o = _guiFont->height * 0.5;
|
||||||
|
|
||||||
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
|
vbeSurfaceSet(f->base.surface);
|
||||||
|
|
||||||
|
// Draw frame.
|
||||||
|
guiDrawHighlightFrame(f->base.x, f->base.y + o, f->base.x + f->base.w, f->base.y + f->base.h - o, _guiColor[COLOR_FRAME_SHADOW], _guiColor[COLOR_FRAME_HIGHLIGHT]);
|
||||||
|
|
||||||
|
// Draw title.
|
||||||
|
fontRender(_guiFont, f->title, _guiColor[COLOR_FRAME_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], f->base.x + 10, f->base.y);
|
||||||
|
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void frameSetTitle(FrameT *frame, char *title) {
|
||||||
|
if (frame->title) free(frame->title);
|
||||||
|
frame->title = (char *)malloc(strlen(title) + 3);
|
||||||
|
frame->title[0] = ' ';
|
||||||
|
frame->title[1] = 0;
|
||||||
|
strcat(frame->title, title);
|
||||||
|
strcat(frame->title, " ");
|
||||||
|
GUI_SET_FLAG((WidgetT *)frame, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
41
client/src/gui/frame.h
Normal file
41
client/src/gui/frame.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FRAME_H
|
||||||
|
#define FRAME_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct FrameS {
|
||||||
|
WidgetT base; // Must be first in every widget
|
||||||
|
char *title;
|
||||||
|
} FrameT;
|
||||||
|
|
||||||
|
|
||||||
|
void frameDel(WidgetT **widget);
|
||||||
|
WidgetT *frameInit(WidgetT *widget, uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
|
||||||
|
FrameT *frameNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
|
||||||
|
void frameSetTitle(FrameT *frame, char *title);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FRAME_H
|
|
@ -349,7 +349,9 @@ DesktopT *guiStartup(void) {
|
||||||
_guiMetric[METRIC_BUTTON_VERTICAL_MARGIN] = 2;
|
_guiMetric[METRIC_BUTTON_VERTICAL_MARGIN] = 2;
|
||||||
_guiMetric[METRIC_WINDOW_BORDER_WIDTH] = 4; // Does not include highlight or shadow lines.
|
_guiMetric[METRIC_WINDOW_BORDER_WIDTH] = 4; // Does not include highlight or shadow lines.
|
||||||
_guiMetric[METRIC_WINDOW_TITLE_HEIGHT] = 17; // Does not include highlight or shadow lines.
|
_guiMetric[METRIC_WINDOW_TITLE_HEIGHT] = 17; // Does not include highlight or shadow lines.
|
||||||
_guiMetric[METRIC_WINDOW_TITLE_GRAB_HEIGHT] = _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 4; // Border, highlights, titlebar.
|
_guiMetric[METRIC_WINDOW_TITLE_GRAB_HEIGHT] = _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 5; // Border, highlights, titlebar.
|
||||||
|
_guiMetric[METRIC_CHECKBOX_PADDING] = 6; // Makes the 10 wide checkbox fill two character cells by padding it out to 16.
|
||||||
|
_guiMetric[METRIC_RADIOBUTTON_PADDING] = 6; // Makes the 10 wide radio button fill two character cells by padding it out to 16.
|
||||||
|
|
||||||
_guiColor[COLOR_BUTTON_BACKGROUND] = vbeMakeColor(168, 168, 168);
|
_guiColor[COLOR_BUTTON_BACKGROUND] = vbeMakeColor(168, 168, 168);
|
||||||
_guiColor[COLOR_BUTTON_HIGHLIGHT] = vbeMakeColor(248, 252, 248);
|
_guiColor[COLOR_BUTTON_HIGHLIGHT] = vbeMakeColor(248, 252, 248);
|
||||||
|
@ -363,6 +365,21 @@ DesktopT *guiStartup(void) {
|
||||||
_guiColor[COLOR_WINDOW_TITLE_INACTIVE] = vbeMakeColor(168, 168, 168);
|
_guiColor[COLOR_WINDOW_TITLE_INACTIVE] = vbeMakeColor(168, 168, 168);
|
||||||
_guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] = vbeMakeColor(248, 252, 248);
|
_guiColor[COLOR_WINDOW_TITLE_TEXT_ACTIVE] = vbeMakeColor(248, 252, 248);
|
||||||
_guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE] = vbeMakeColor( 0, 0, 0);
|
_guiColor[COLOR_WINDOW_TITLE_TEXT_INACTIVE] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeMakeColor(248, 252, 248);
|
||||||
|
_guiColor[COLOR_LABEL_TEXT_INACTIVE] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_CHECKBOX_HIGHLIGHT] = vbeMakeColor(248, 252, 248);
|
||||||
|
_guiColor[COLOR_CHECKBOX_SHADOW] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_CHECKBOX_ACTIVE] = vbeMakeColor( 80, 84, 80);
|
||||||
|
_guiColor[COLOR_CHECKBOX_INACTIVE] = vbeMakeColor(168, 168, 168);
|
||||||
|
_guiColor[COLOR_CHECKBOX_TEXT] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_RADIOBUTTON_HIGHLIGHT] = vbeMakeColor(248, 252, 248);
|
||||||
|
_guiColor[COLOR_RADIOBUTTON_SHADOW] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_RADIOBUTTON_ACTIVE] = vbeMakeColor( 80, 84, 80);
|
||||||
|
_guiColor[COLOR_RADIOBUTTON_INACTIVE] = vbeMakeColor(168, 168, 168);
|
||||||
|
_guiColor[COLOR_RADIOBUTTON_TEXT] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_FRAME_HIGHLIGHT] = vbeMakeColor(248, 252, 248);
|
||||||
|
_guiColor[COLOR_FRAME_SHADOW] = vbeMakeColor( 0, 0, 0);
|
||||||
|
_guiColor[COLOR_FRAME_TEXT] = vbeMakeColor( 0, 0, 0);
|
||||||
|
|
||||||
_guiFont = fontLoad("vga8x14.dat");
|
_guiFont = fontLoad("vga8x14.dat");
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
|
|
||||||
#define GUI_GET_FLAG(w,f) ((w)->flags & (1 << (f)))
|
#define GUI_GET_FLAG(w,f) (((w)->flags & (1 << (f))) != 0)
|
||||||
#define GUI_SET_FLAG(w,f) (w)->flags |= (1 << (f))
|
#define GUI_SET_FLAG(w,f) ((w)->flags |= (1 << (f)))
|
||||||
#define GUI_CLEAR_FLAG(w,f) (w)->flags &= (~(1 << (f)))
|
#define GUI_CLEAR_FLAG(w,f) ((w)->flags &= (~(1 << (f))))
|
||||||
|
|
||||||
#define W(w) ((WidgetT *)w)
|
#define W(w) ((WidgetT *)w)
|
||||||
|
|
||||||
|
@ -42,6 +42,14 @@ enum MagicE {
|
||||||
MAGIC_DESKTOP,
|
MAGIC_DESKTOP,
|
||||||
MAGIC_WINDOW,
|
MAGIC_WINDOW,
|
||||||
MAGIC_BUTTON,
|
MAGIC_BUTTON,
|
||||||
|
MAGIC_LABEL,
|
||||||
|
MAGIC_CHECKBOX,
|
||||||
|
MAGIC_RADIOBUTTON,
|
||||||
|
MAGIC_PICTURE,
|
||||||
|
MAGIC_FRAME,
|
||||||
|
//MAGIC_TEXTBOX,
|
||||||
|
//MAGIC_UPDOWN,
|
||||||
|
//MAGIC_LISTBOX,
|
||||||
MAGIC_COUNT
|
MAGIC_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +61,8 @@ enum MetricE {
|
||||||
METRIC_WINDOW_BORDER_WIDTH,
|
METRIC_WINDOW_BORDER_WIDTH,
|
||||||
METRIC_WINDOW_TITLE_HEIGHT,
|
METRIC_WINDOW_TITLE_HEIGHT,
|
||||||
METRIC_WINDOW_TITLE_GRAB_HEIGHT,
|
METRIC_WINDOW_TITLE_GRAB_HEIGHT,
|
||||||
|
METRIC_CHECKBOX_PADDING,
|
||||||
|
METRIC_RADIOBUTTON_PADDING,
|
||||||
METRIC_COUNT
|
METRIC_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +80,21 @@ enum ColorE {
|
||||||
COLOR_WINDOW_TITLE_INACTIVE,
|
COLOR_WINDOW_TITLE_INACTIVE,
|
||||||
COLOR_WINDOW_TITLE_TEXT_ACTIVE,
|
COLOR_WINDOW_TITLE_TEXT_ACTIVE,
|
||||||
COLOR_WINDOW_TITLE_TEXT_INACTIVE,
|
COLOR_WINDOW_TITLE_TEXT_INACTIVE,
|
||||||
|
COLOR_LABEL_TEXT_ACTIVE,
|
||||||
|
COLOR_LABEL_TEXT_INACTIVE,
|
||||||
|
COLOR_CHECKBOX_HIGHLIGHT,
|
||||||
|
COLOR_CHECKBOX_SHADOW,
|
||||||
|
COLOR_CHECKBOX_ACTIVE,
|
||||||
|
COLOR_CHECKBOX_INACTIVE,
|
||||||
|
COLOR_CHECKBOX_TEXT,
|
||||||
|
COLOR_RADIOBUTTON_HIGHLIGHT,
|
||||||
|
COLOR_RADIOBUTTON_SHADOW,
|
||||||
|
COLOR_RADIOBUTTON_ACTIVE,
|
||||||
|
COLOR_RADIOBUTTON_INACTIVE,
|
||||||
|
COLOR_RADIOBUTTON_TEXT,
|
||||||
|
COLOR_FRAME_HIGHLIGHT,
|
||||||
|
COLOR_FRAME_SHADOW,
|
||||||
|
COLOR_FRAME_TEXT,
|
||||||
COLOR_COUNT
|
COLOR_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,11 @@ ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t imageHeightGet(ImageT *image) {
|
||||||
|
return image->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ImageT *imageLoad(char *filename) {
|
ImageT *imageLoad(char *filename) {
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
uint16_t y;
|
uint16_t y;
|
||||||
|
@ -116,9 +121,15 @@ ColorT imagePixelGet(ImageT *image, uint16_t x, uint16_t y) {
|
||||||
void imageRender(ImageT *image, uint16_t x, uint16_t y) {
|
void imageRender(ImageT *image, uint16_t x, uint16_t y) {
|
||||||
uint16_t x1;
|
uint16_t x1;
|
||||||
uint16_t y1;
|
uint16_t y1;
|
||||||
|
uint16_t x2 = image->width;
|
||||||
|
uint16_t y2 = image->height;
|
||||||
|
|
||||||
for (y1=0; y1<image->height; y1++) {
|
// Clip on right and bottom
|
||||||
for (x1=0; x1<image->width; x1++) {
|
if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet();
|
||||||
|
if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet();
|
||||||
|
|
||||||
|
for (y1=0; y1<y2; y1++) {
|
||||||
|
for (x1=0; x1<x2; x1++) {
|
||||||
vbePutPixel(x + x1, y + y1, image->pixels[x1][y1]);
|
vbePutPixel(x + x1, y + y1, image->pixels[x1][y1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,8 +143,8 @@ void imageRenderWithAlpha(ImageT *image, uint16_t x, uint16_t y, ColorT alpha) {
|
||||||
uint16_t y2 = image->height;
|
uint16_t y2 = image->height;
|
||||||
|
|
||||||
// Clip on right and bottom
|
// Clip on right and bottom
|
||||||
if (x + x2 > vbeDisplayWidthGet()) x2 -= x + x2 - vbeDisplayWidthGet();
|
if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet();
|
||||||
if (y + y2 > vbeDisplayHeightGet()) y2 -= y + y2 - vbeDisplayHeightGet();
|
if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet();
|
||||||
|
|
||||||
for (y1=0; y1<y2; y1++) {
|
for (y1=0; y1<y2; y1++) {
|
||||||
for (x1=0; x1<x2; x1++) {
|
for (x1=0; x1<x2; x1++) {
|
||||||
|
@ -156,3 +167,8 @@ void imageUnload(ImageT **image) {
|
||||||
free(i);
|
free(i);
|
||||||
i = NULL;
|
i = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t imageWidthGet(ImageT *image) {
|
||||||
|
return image->width;
|
||||||
|
}
|
||||||
|
|
|
@ -35,13 +35,15 @@ typedef struct ImageS {
|
||||||
} ImageT;
|
} ImageT;
|
||||||
|
|
||||||
|
|
||||||
ImageT *imageAllocate(uint16_t w, uint16_t h);
|
ImageT *imageAllocate(uint16_t w, uint16_t h);
|
||||||
ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color);
|
ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color);
|
||||||
ImageT *imageLoad(char *filename);
|
uint16_t imageHeightGet(ImageT *image);
|
||||||
ColorT imagePixelGet(ImageT *image, uint16_t x, uint16_t y);
|
ImageT *imageLoad(char *filename);
|
||||||
void imageRender(ImageT *image, uint16_t x, uint16_t y);
|
ColorT imagePixelGet(ImageT *image, uint16_t x, uint16_t y);
|
||||||
void imageRenderWithAlpha(ImageT *image, uint16_t x, uint16_t y, ColorT alpha);
|
void imageRender(ImageT *image, uint16_t x, uint16_t y);
|
||||||
void imageUnload(ImageT **image);
|
void imageRenderWithAlpha(ImageT *image, uint16_t x, uint16_t y, ColorT alpha);
|
||||||
|
void imageUnload(ImageT **image);
|
||||||
|
uint16_t imageWidthGet(ImageT *image);
|
||||||
|
|
||||||
|
|
||||||
#endif // IMAGE_H
|
#endif // IMAGE_H
|
||||||
|
|
148
client/src/gui/label.c
Normal file
148
client/src/gui/label.c
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* 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 "label.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void labelMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
||||||
|
static void labelPaint(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
void labelDel(WidgetT **widget) {
|
||||||
|
LabelT *l = (LabelT *)*widget;
|
||||||
|
|
||||||
|
if (l->title) free(l->title);
|
||||||
|
free(l);
|
||||||
|
l = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *labelInit(WidgetT *widget, uint16_t x, uint16_t y, char *title) {
|
||||||
|
LabelT *l = (LabelT *)widget;
|
||||||
|
|
||||||
|
l->base.magic = MAGIC_LABEL;
|
||||||
|
l->base.x = x;
|
||||||
|
l->base.y = y;
|
||||||
|
l->base.delMethod = labelDel;
|
||||||
|
l->base.paintMethod = labelPaint;
|
||||||
|
l->base.mouseEventMethod = labelMouseEvent;
|
||||||
|
l->title = NULL;
|
||||||
|
l->background = _guiColor[COLOR_WINDOW_BACKGROUND];
|
||||||
|
l->foreground = _guiColor[COLOR_LABEL_TEXT_INACTIVE];
|
||||||
|
l->clicked = NULL;
|
||||||
|
|
||||||
|
labelSetTitle(l, title);
|
||||||
|
|
||||||
|
// Width is set in labelSetTitle
|
||||||
|
l->base.h = fontHeightGet(_guiFont);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void labelMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
|
||||||
|
LabelT *l = (LabelT *)widget;
|
||||||
|
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
(void)mouse;
|
||||||
|
|
||||||
|
// Label 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 (l->clicked) l->clicked(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LabelT *labelNew(uint16_t x, uint16_t y, char *title) {
|
||||||
|
LabelT *label = (LabelT *)malloc(sizeof(LabelT));
|
||||||
|
WidgetT *widget = NULL;
|
||||||
|
|
||||||
|
if (!label) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit((WidgetT *)label);
|
||||||
|
if (!widget) {
|
||||||
|
free(label);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
label = (LabelT *)labelInit((WidgetT *)label, x, y, title);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void labelPaint(WidgetT *widget) {
|
||||||
|
LabelT *l = (LabelT *)widget;
|
||||||
|
ColorT text = GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE) ? l->active : l->foreground;
|
||||||
|
|
||||||
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
|
vbeSurfaceSet(l->base.surface);
|
||||||
|
|
||||||
|
// Draw title.
|
||||||
|
fontRender(_guiFont, l->title, text, l->background, l->base.x, l->base.y);
|
||||||
|
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void labelSetActiveColor(LabelT *label, ColorT color) {
|
||||||
|
label->active = color;
|
||||||
|
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void labelSetBackgroundColor(LabelT *label, ColorT color) {
|
||||||
|
label->background = color;
|
||||||
|
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void labelSetClickHandler(LabelT *label, widgetCallback callback) {
|
||||||
|
label->clicked = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void labelSetForegroundColor(LabelT *label, ColorT color) {
|
||||||
|
label->foreground = color;
|
||||||
|
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void labelSetTitle(LabelT *label, char *title) {
|
||||||
|
if (label->title) free(label->title);
|
||||||
|
label->title = strdup(title);
|
||||||
|
label->base.w = (strlen(title) * fontWidthGet(_guiFont));
|
||||||
|
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
49
client/src/gui/label.h
Normal file
49
client/src/gui/label.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LABEL_H
|
||||||
|
#define LABEL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct LabelS {
|
||||||
|
WidgetT base; // Must be first in every widget
|
||||||
|
char *title;
|
||||||
|
widgetCallback clicked;
|
||||||
|
ColorT active;
|
||||||
|
ColorT foreground;
|
||||||
|
ColorT background;
|
||||||
|
} LabelT;
|
||||||
|
|
||||||
|
|
||||||
|
void labelDel(WidgetT **widget);
|
||||||
|
WidgetT *labelInit(WidgetT *widget, uint16_t x, uint16_t y, char *title);
|
||||||
|
LabelT *labelNew(uint16_t x, uint16_t y, char *title);
|
||||||
|
void labelSetActiveColor(LabelT *label, ColorT color);
|
||||||
|
void labelSetBackgroundColor(LabelT *label, ColorT color);
|
||||||
|
void labelSetClickHandler(LabelT *label, widgetCallback callback);
|
||||||
|
void labelSetForegroundColor(LabelT *label, ColorT color);
|
||||||
|
void labelSetTitle(LabelT *label, char *title);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LABEL_H
|
114
client/src/gui/picture.c
Normal file
114
client/src/gui/picture.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* 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 "picture.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void pictureMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
||||||
|
static void picturePaint(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
void pictureDel(WidgetT **widget) {
|
||||||
|
PictureT *p = (PictureT *)*widget;
|
||||||
|
|
||||||
|
if (p->image) imageUnload(&p->image);
|
||||||
|
if (p->filename) free(p->filename);
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *pictureInit(WidgetT *widget, uint16_t x, uint16_t y, char *filename) {
|
||||||
|
PictureT *l = (PictureT *)widget;
|
||||||
|
|
||||||
|
l->base.magic = MAGIC_PICTURE;
|
||||||
|
l->base.x = x;
|
||||||
|
l->base.y = y;
|
||||||
|
l->base.delMethod = pictureDel;
|
||||||
|
l->base.paintMethod = picturePaint;
|
||||||
|
l->base.mouseEventMethod = pictureMouseEvent;
|
||||||
|
l->filename = strdup(filename);
|
||||||
|
l->clicked = NULL;
|
||||||
|
|
||||||
|
l->image = imageLoad(l->filename);
|
||||||
|
if (!l->image) {
|
||||||
|
free(l->filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
l->base.w = imageWidthGet(l->image);
|
||||||
|
l->base.h = imageHeightGet(l->image);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void pictureMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
|
||||||
|
PictureT *p = (PictureT *)widget;
|
||||||
|
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
(void)mouse;
|
||||||
|
|
||||||
|
// Fire callback on mouse up.
|
||||||
|
if (event == MOUSE_EVENT_LEFT_UP) {
|
||||||
|
if (p->clicked) p->clicked(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PictureT *pictureNew(uint16_t x, uint16_t y, char *filename) {
|
||||||
|
PictureT *picture = (PictureT *)malloc(sizeof(PictureT));
|
||||||
|
WidgetT *widget = NULL;
|
||||||
|
|
||||||
|
if (!picture) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit((WidgetT *)picture);
|
||||||
|
if (!widget) {
|
||||||
|
free(picture);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
picture = (PictureT *)pictureInit((WidgetT *)picture, x, y, filename);
|
||||||
|
if (!picture) {
|
||||||
|
free(picture);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return picture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void picturePaint(WidgetT *widget) {
|
||||||
|
PictureT *p = (PictureT *)widget;
|
||||||
|
|
||||||
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
|
vbeSurfaceSet(p->base.surface);
|
||||||
|
|
||||||
|
imageRender(p->image, p->base.x, p->base.y);
|
||||||
|
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pictureSetClickHandler(PictureT *picture, widgetCallback callback) {
|
||||||
|
picture->clicked = callback;
|
||||||
|
}
|
44
client/src/gui/picture.h
Normal file
44
client/src/gui/picture.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PICTURE_H
|
||||||
|
#define PICTURE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PictureS {
|
||||||
|
WidgetT base; // Must be first in every widget
|
||||||
|
char *filename;
|
||||||
|
widgetCallback clicked;
|
||||||
|
ImageT *image;
|
||||||
|
} PictureT;
|
||||||
|
|
||||||
|
|
||||||
|
void pictureDel(WidgetT **widget);
|
||||||
|
WidgetT *pictureInit(WidgetT *widget, uint16_t x, uint16_t y, char *filename);
|
||||||
|
PictureT *pictureNew(uint16_t x, uint16_t y, char *filename);
|
||||||
|
void pictureSetClickHandler(PictureT *picture, widgetCallback callback);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PICTURE_H
|
207
client/src/gui/radio.c
Normal file
207
client/src/gui/radio.c
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* 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 "radio.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void radioClearSelectedInGroup(WidgetT *widget, uint32_t group);
|
||||||
|
static RadioT *radioFindSelectedInGroup(WidgetT *widget, uint32_t group);
|
||||||
|
static void radioMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
|
||||||
|
static void radioPaint(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
static void radioClearSelectedInGroup(WidgetT *widget, uint32_t group) {
|
||||||
|
size_t len = arrlenu(widget->children);
|
||||||
|
size_t x;
|
||||||
|
|
||||||
|
// Is this a Radio Button?
|
||||||
|
if (widget->magic == MAGIC_RADIOBUTTON) {
|
||||||
|
// Is this in our group and active?
|
||||||
|
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
|
||||||
|
// Deactivate it, mark it dirty, and stop searching.
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_ACTIVE);
|
||||||
|
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process any children.
|
||||||
|
if (len > 0) {
|
||||||
|
for (x=0; x<len; x++) {
|
||||||
|
radioClearSelectedInGroup(widget->children[x], group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void radioDel(WidgetT **widget) {
|
||||||
|
RadioT *r = (RadioT *)*widget;
|
||||||
|
|
||||||
|
if (r->title) free(r->title);
|
||||||
|
free(r);
|
||||||
|
r = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static RadioT *radioFindSelectedInGroup(WidgetT *widget, uint32_t group) {
|
||||||
|
size_t len = arrlenu(widget->children);
|
||||||
|
size_t x;
|
||||||
|
RadioT *result = NULL;
|
||||||
|
|
||||||
|
// Is this a Radio Button?
|
||||||
|
if (widget->magic == MAGIC_RADIOBUTTON) {
|
||||||
|
// Is this in our group and active?
|
||||||
|
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
|
||||||
|
// Found! Stop searching.
|
||||||
|
return (RadioT *)widget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process any children.
|
||||||
|
if (len > 0) {
|
||||||
|
for (x=0; x<len; x++) {
|
||||||
|
result = radioFindSelectedInGroup(widget->children[x], group);
|
||||||
|
if (result) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RadioT *radioGetSelected(RadioT *radio) {
|
||||||
|
return radioFindSelectedInGroup(guiRootGet(), radio->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *radioInit(WidgetT *widget, uint16_t x, uint16_t y, char *title, uint16_t group) {
|
||||||
|
RadioT *r = (RadioT *)widget;
|
||||||
|
|
||||||
|
r->base.magic = MAGIC_RADIOBUTTON;
|
||||||
|
r->base.x = x;
|
||||||
|
r->base.y = y;
|
||||||
|
r->base.delMethod = radioDel;
|
||||||
|
r->base.paintMethod = radioPaint;
|
||||||
|
r->base.mouseEventMethod = radioMouseEvent;
|
||||||
|
r->title = NULL;
|
||||||
|
r->clicked = NULL;
|
||||||
|
r->group = group;
|
||||||
|
|
||||||
|
radioSetTitle(r, title);
|
||||||
|
|
||||||
|
// Width is set in radioSetTitle
|
||||||
|
r->base.h = fontHeightGet(_guiFont);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void radioMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
|
||||||
|
RadioT *r = (RadioT *)widget;
|
||||||
|
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
(void)mouse;
|
||||||
|
|
||||||
|
if (event == MOUSE_EVENT_LEFT_UP) {
|
||||||
|
// Select us.
|
||||||
|
radioSetSelected(r);
|
||||||
|
// Fire callback on mouse up.
|
||||||
|
if (r->clicked) r->clicked(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RadioT *radioNew(uint16_t x, uint16_t y, char *title, uint16_t group) {
|
||||||
|
RadioT *radio = (RadioT *)malloc(sizeof(RadioT));
|
||||||
|
WidgetT *widget = NULL;
|
||||||
|
|
||||||
|
if (!radio) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit((WidgetT *)radio);
|
||||||
|
if (!widget) {
|
||||||
|
free(radio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio = (RadioT *)radioInit((WidgetT *)radio, x, y, title, group);
|
||||||
|
|
||||||
|
return radio;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void radioPaint(WidgetT *widget) {
|
||||||
|
RadioT *r = (RadioT *)widget;
|
||||||
|
int16_t i;
|
||||||
|
int16_t o;
|
||||||
|
uint8_t active = (radioGetSelected(r) == r);
|
||||||
|
ColorT highlight = active ? _guiColor[COLOR_RADIOBUTTON_SHADOW] : _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT];
|
||||||
|
ColorT shadow = active ? _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT] : _guiColor[COLOR_RADIOBUTTON_SHADOW];
|
||||||
|
ColorT fill = active ? _guiColor[COLOR_RADIOBUTTON_ACTIVE] : _guiColor[COLOR_RADIOBUTTON_INACTIVE];
|
||||||
|
|
||||||
|
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
|
||||||
|
vbeSurfaceSet(r->base.surface);
|
||||||
|
|
||||||
|
// Radio button is 10x10 pixels. Find offset based on font height.
|
||||||
|
o = (_guiFont->height - 10) * 0.5;
|
||||||
|
|
||||||
|
// Draw outline of radio button.
|
||||||
|
guiDrawLine(r->base.x, r->base.y + o + 5, r->base.x + 5, r->base.y + o, highlight);
|
||||||
|
guiDrawLine(r->base.x + 5, r->base.y + o, r->base.x + 10, r->base.y + o + 5, highlight);
|
||||||
|
guiDrawLine(r->base.x, r->base.y + o + 5, r->base.x + 5, r->base.y + o + 10, shadow);
|
||||||
|
guiDrawLine(r->base.x + 5, r->base.y + o + 10, r->base.x + 10, r->base.y + o + 5, shadow);
|
||||||
|
|
||||||
|
// Fill radio button.
|
||||||
|
for (i=0; i<4; i++) {
|
||||||
|
guiDrawLine(r->base.x + 5 - i, r->base.y + o + i + 1, r->base.x + 5 + i, r->base.y + o + i + 1, fill);
|
||||||
|
guiDrawLine(r->base.x + 5 - i, r->base.y + o - i + 8, r->base.x + 5 + i, r->base.y + o - i + 8, fill);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw title.
|
||||||
|
fontRender(_guiFont, r->title, _guiColor[COLOR_RADIOBUTTON_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], r->base.x + 10 + _guiMetric[METRIC_RADIOBUTTON_PADDING], r->base.y);
|
||||||
|
|
||||||
|
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void radioSetClickHandler(RadioT *radio, widgetCallback callback) {
|
||||||
|
radio->clicked = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void radioSetSelected(RadioT *radio) {
|
||||||
|
// Are we already selected?
|
||||||
|
if (!GUI_GET_FLAG((WidgetT *)radio, WIDGET_FLAG_ACTIVE)) {
|
||||||
|
// Clear whoever is selected.
|
||||||
|
radioClearSelectedInGroup(guiRootGet(), radio->group);
|
||||||
|
// Select us.
|
||||||
|
GUI_SET_FLAG((WidgetT *)radio, WIDGET_FLAG_ACTIVE);
|
||||||
|
GUI_SET_FLAG((WidgetT *)radio, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void radioSetTitle(RadioT *radio, char *title) {
|
||||||
|
if (radio->title) free(radio->title);
|
||||||
|
radio->title = strdup(title);
|
||||||
|
radio->base.w = (strlen(title) * fontWidthGet(_guiFont)) + 10 + _guiMetric[METRIC_RADIOBUTTON_PADDING];
|
||||||
|
GUI_SET_FLAG((WidgetT *)radio, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
46
client/src/gui/radio.h
Normal file
46
client/src/gui/radio.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RADIO_H
|
||||||
|
#define RADIO_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct RadioS {
|
||||||
|
WidgetT base; // Must be first in every widget
|
||||||
|
char *title;
|
||||||
|
uint16_t group;
|
||||||
|
widgetCallback clicked;
|
||||||
|
} RadioT;
|
||||||
|
|
||||||
|
|
||||||
|
void radioDel(WidgetT **widget);
|
||||||
|
RadioT *radioGetSelected(RadioT *radio);
|
||||||
|
WidgetT *radioInit(WidgetT *widget, uint16_t x, uint16_t y, char *title, uint16_t group);
|
||||||
|
RadioT *radioNew(uint16_t x, uint16_t y, char *title, uint16_t group);
|
||||||
|
void radioSetClickHandler(RadioT *radio, widgetCallback callback);
|
||||||
|
void radioSetSelected(RadioT *radio);
|
||||||
|
void radioSetTitle(RadioT *radio, char *title);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RADIO_H
|
|
@ -21,6 +21,16 @@
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t widgetGetHeight(WidgetT *widget) {
|
||||||
|
return widget->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t widgetGetWidth(WidgetT *widget) {
|
||||||
|
return widget->w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WidgetT *widgetInit(WidgetT *widget) {
|
WidgetT *widgetInit(WidgetT *widget) {
|
||||||
widget->magic = MAGIC_UNKNOWN;
|
widget->magic = MAGIC_UNKNOWN;
|
||||||
widget->flags = 0;
|
widget->flags = 0;
|
||||||
|
|
|
@ -62,8 +62,10 @@ typedef struct WidgetS {
|
||||||
} WidgetT;
|
} WidgetT;
|
||||||
|
|
||||||
|
|
||||||
WidgetT *widgetInit(WidgetT *widget);
|
uint16_t widgetGetHeight(WidgetT *widget);
|
||||||
WidgetT *widgetNew(void);
|
uint16_t widgetGetWidth(WidgetT *widget);
|
||||||
|
WidgetT *widgetInit(WidgetT *widget);
|
||||||
|
WidgetT *widgetNew(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // WIDGET_H
|
#endif // WIDGET_H
|
||||||
|
|
|
@ -70,8 +70,8 @@ WidgetT *windowInit(WidgetT *window, uint16_t x, uint16_t y, uint16_t w, uint16_
|
||||||
win->flags = 0;
|
win->flags = 0;
|
||||||
win->title = NULL;
|
win->title = NULL;
|
||||||
|
|
||||||
win->base.marginX += _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2;
|
win->base.marginX += _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 6;
|
||||||
win->base.marginY += _guiMetric[METRIC_WINDOW_TITLE_GRAB_HEIGHT];
|
win->base.marginY += _guiMetric[METRIC_WINDOW_TITLE_GRAB_HEIGHT] + 1;
|
||||||
|
|
||||||
windowSetTitle(win, title);
|
windowSetTitle(win, title);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To Do:
|
||||||
|
*
|
||||||
|
* - Fix function naming to be classItemVerb (checkboxValueGet instead of checkboxGetValue)
|
||||||
|
* - Replace any direct data manipulation from outside a class with methods to handle it
|
||||||
|
* - More widget states: Ghosted, hidden
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "vesa.h"
|
#include "vesa.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
@ -25,11 +35,17 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include "desktop.h"
|
#include "desktop.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
|
#include "label.h"
|
||||||
|
#include "checkbox.h"
|
||||||
|
#include "radio.h"
|
||||||
|
#include "picture.h"
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
|
||||||
void buttonClick(WidgetT *widget) {
|
void buttonClick(WidgetT *widget) {
|
||||||
|
@ -38,36 +54,73 @@ void buttonClick(WidgetT *widget) {
|
||||||
|
|
||||||
|
|
||||||
void test(void *data) {
|
void test(void *data) {
|
||||||
MouseT *mouse = NULL;
|
MouseT *mouse = NULL;
|
||||||
ImageT *pointer = NULL;
|
ImageT *pointer = NULL;
|
||||||
ColorT alpha;
|
ColorT alpha;
|
||||||
DesktopT *desktop = (DesktopT *)guiRootGet();
|
DesktopT *desktop = (DesktopT *)guiRootGet();
|
||||||
WindowT *w1 = NULL;
|
WindowT *w1 = NULL;
|
||||||
WindowT *w2 = NULL;
|
WindowT *w2 = NULL;
|
||||||
WindowT *w3 = NULL;
|
WindowT *w3 = NULL;
|
||||||
ButtonT *b1 = NULL;
|
ButtonT *b1 = NULL;
|
||||||
int8_t key = 0;
|
LabelT *l1 = NULL;
|
||||||
|
CheckboxT *c1 = NULL;
|
||||||
|
RadioT *r1a = NULL;
|
||||||
|
RadioT *r2a = NULL;
|
||||||
|
RadioT *r3a = NULL;
|
||||||
|
RadioT *r1b = NULL;
|
||||||
|
RadioT *r2b = NULL;
|
||||||
|
RadioT *r3b = NULL;
|
||||||
|
PictureT *p1 = NULL;
|
||||||
|
FrameT *f1 = NULL;
|
||||||
|
int8_t key = 0;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
pointer = imageLoad("mouse.png");
|
pointer = imageLoad("mouse.png");
|
||||||
alpha = imagePixelGet(pointer, 5, 0);
|
alpha = imagePixelGet(pointer, 5, 0);
|
||||||
|
|
||||||
|
// Windows
|
||||||
w1 = windowNew(25, 25, 300, 200, "Window 1");
|
w1 = windowNew(25, 25, 300, 200, "Window 1");
|
||||||
w2 = windowNew(150, 150, 300, 200, "Window 2");
|
|
||||||
w3 = windowNew(300, 300, 300, 200, "Window 3");
|
|
||||||
guiAttach(W(desktop), W(w1));
|
guiAttach(W(desktop), W(w1));
|
||||||
|
w2 = windowNew(150, 150, 300, 200, "Window 2");
|
||||||
guiAttach(W(desktop), W(w2));
|
guiAttach(W(desktop), W(w2));
|
||||||
|
w3 = windowNew(300, 300, 300, 200, "Window 3");
|
||||||
guiAttach(W(desktop), W(w3));
|
guiAttach(W(desktop), W(w3));
|
||||||
|
|
||||||
b1 = buttonNew(25, 25, "Test Button", buttonClick);
|
// Window 1
|
||||||
guiAttach(W(w3), W(b1));
|
p1 = pictureNew(0, 0, "kanga.png");
|
||||||
|
guiAttach(W(w1), W(p1));
|
||||||
|
|
||||||
|
// Window 2
|
||||||
|
r1a = radioNew(10, 10, "Radio 1a", 1);
|
||||||
|
guiAttach(W(w2), W(r1a));
|
||||||
|
r2a = radioNew(20 + widgetGetWidth(W(r1a)), 10, "Radio 2a", 1);
|
||||||
|
guiAttach(W(w2), W(r2a));
|
||||||
|
r3a = radioNew(30 + widgetGetWidth(W(r1a)) + widgetGetWidth(W(r2a)), 10, "Radio 3a", 1);
|
||||||
|
guiAttach(W(w2), W(r3a));
|
||||||
|
r1b = radioNew(10, 35, "Radio 1b", 2);
|
||||||
|
guiAttach(W(w2), W(r1b));
|
||||||
|
r2b = radioNew(20 + widgetGetWidth(W(r1b)), 35, "Radio 2b", 2);
|
||||||
|
guiAttach(W(w2), W(r2b));
|
||||||
|
r3b = radioNew(30 + widgetGetWidth(W(r1b)) + widgetGetWidth(W(r2b)), 35, "Radio 3b", 2);
|
||||||
|
guiAttach(W(w2), W(r3b));
|
||||||
|
radioSetSelected(r1a);
|
||||||
|
radioSetSelected(r2b);
|
||||||
|
|
||||||
|
// Window 3
|
||||||
|
f1 = frameNew(10, 5, 175, 125, "Test Frame");
|
||||||
|
guiAttach(W(w3), W(f1));
|
||||||
|
b1 = buttonNew(10, 10, "Test Button", buttonClick);
|
||||||
|
guiAttach(W(f1), W(b1));
|
||||||
|
l1 = labelNew(10, 40, "Test Label");
|
||||||
|
guiAttach(W(f1), W(l1));
|
||||||
|
c1 = checkboxNew(10, 65, "Test Checkbox");
|
||||||
|
guiAttach(W(f1), W(c1));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
mouse = mouseRead();
|
mouse = mouseRead();
|
||||||
if (keyHit()) {
|
if (keyHit()) {
|
||||||
key = keyASCII();
|
key = keyASCII();
|
||||||
logWrite("Key %d Scan %d Alt %d\n", key, keyScanCode(), keyAlt());
|
|
||||||
} else {
|
} else {
|
||||||
key = 0;
|
key = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue