Much debugging. Starting to add actual client code!
This commit is contained in:
parent
7cf6a7112a
commit
30c8947936
34 changed files with 905 additions and 525 deletions
|
@ -16,6 +16,9 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# NOTE: You'll occasionally find a file with a capital "C" extension.
|
||||
# These are C files that we want ignored by the DOS compiler.
|
||||
|
||||
TEMPLATE = app
|
||||
CONFIG -= qt
|
||||
|
||||
|
@ -47,14 +50,16 @@ INCLUDEPATH += \
|
|||
|
||||
HEADERS = \
|
||||
$$LINUX_HEADERS \
|
||||
src/settings.h \
|
||||
src/system/color.h \
|
||||
src/system/memory.h \
|
||||
src/system/surface.h \
|
||||
src/system/taglist.h \
|
||||
src/test.h \
|
||||
src/thirdparty/stb_ds.h \
|
||||
src/thirdparty/stb_image.h \
|
||||
src/thirdparty/memwatch/memwatch.h \
|
||||
src/thirdparty/minicoro/minicoro.h \
|
||||
src/system/memory.h \
|
||||
src/system/keyboard.h \
|
||||
src/system/task.h \
|
||||
src/system/timer.h \
|
||||
|
@ -80,14 +85,17 @@ HEADERS = \
|
|||
src/gui/widget.h \
|
||||
src/gui/window.h \
|
||||
src/gui/image.h \
|
||||
src/stddclmr.h
|
||||
src/stddclmr.h \
|
||||
src/welcome.h
|
||||
|
||||
SOURCES = \
|
||||
$$LINUX_SOURCES \
|
||||
src/system/memory.c \
|
||||
src/thirdparty/memwatch/memwatch.c \
|
||||
src/settings.c \
|
||||
src/system/surface.c \
|
||||
src/system/taglist.c \
|
||||
src/thirdparty/memwatch/memwatch.c \
|
||||
src/system/memory.c \
|
||||
src/test.c \
|
||||
src/system/array.c \
|
||||
src/system/log.c \
|
||||
src/system/timer.c \
|
||||
|
@ -108,7 +116,8 @@ SOURCES = \
|
|||
src/gui/button.c \
|
||||
src/gui/checkbox.c \
|
||||
src/gui/label.c \
|
||||
src/main.c
|
||||
src/main.c \
|
||||
src/welcome.c
|
||||
|
||||
LIBS = \
|
||||
-lSDL2 \
|
||||
|
|
BIN
client/data/dconnect.png
(Stored with Git LFS)
Normal file
BIN
client/data/dconnect.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
client/data/ddialing.png
(Stored with Git LFS)
Normal file
BIN
client/data/ddialing.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
client/data/dinit.png
(Stored with Git LFS)
Normal file
BIN
client/data/dinit.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
client/data/logo.png
(Stored with Git LFS)
Normal file
BIN
client/data/logo.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -34,11 +34,7 @@ void buttonClickHandlerSet(ButtonT *button, widgetCallback callback) {
|
|||
static void buttonDel(WidgetT **widget) {
|
||||
ButtonT *b = (ButtonT *)*widget;
|
||||
|
||||
arrfree(b->base.children);
|
||||
if (b->title) free(b->title);
|
||||
free(b);
|
||||
b = NULL;
|
||||
*widget = W(b);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,11 +34,7 @@ void checkboxClickHandlerSet(CheckboxT *checkbox, widgetCallback callback) {
|
|||
static void checkboxDel(WidgetT **widget) {
|
||||
CheckboxT *c = (CheckboxT *)*widget;
|
||||
|
||||
arrfree(c->base.children);
|
||||
if (c->title) free(c->title);
|
||||
free(c);
|
||||
c = NULL;
|
||||
*widget = W(c);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,26 +22,13 @@
|
|||
#include "window.h"
|
||||
|
||||
|
||||
static void desktopDel(WidgetT **widget);
|
||||
static void desktopPaint(WidgetT *desktop, RectT pos);
|
||||
|
||||
|
||||
static void desktopDel(WidgetT **widget) {
|
||||
DesktopT *d = (DesktopT *)*widget;
|
||||
|
||||
arrfree(d->base.children);
|
||||
surfaceDestroy(&d->base.surface);
|
||||
free(d);
|
||||
d = NULL;
|
||||
*widget = W(d);
|
||||
}
|
||||
|
||||
|
||||
WidgetT *desktopInit(WidgetT *desktop) {
|
||||
DesktopT *d = (DesktopT *)desktop;
|
||||
|
||||
d->base.magic = MAGIC_DESKTOP;
|
||||
d->base.delMethod = desktopDel;
|
||||
d->base.paintMethod = desktopPaint;
|
||||
|
||||
GUI_SET_FLAG(desktop, WIDGET_FLAG_OWNS_SURFACE);
|
||||
|
|
|
@ -28,11 +28,7 @@ static void framePaint(WidgetT *widget, RectT pos);
|
|||
static void frameDel(WidgetT **widget) {
|
||||
FrameT *f = (FrameT *)*widget;
|
||||
|
||||
arrfree(f->base.children);
|
||||
if (f->title) free(f->title);
|
||||
free(f);
|
||||
f = NULL;
|
||||
*widget = W(f);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,10 +39,12 @@ uint16_t _guiDragOffsetY = 0;
|
|||
WindowT *_guiActiveWindow = NULL;
|
||||
|
||||
|
||||
static DesktopT *_guiDesktop = NULL;
|
||||
static WidgetT *_guiLastWidgetLeft = NULL;
|
||||
static uint8_t _guiLastWidgetLeftEvent = MOUSE_EVENT_NONE;
|
||||
static WidgetT *_guiFocused = NULL;
|
||||
static DesktopT *_guiDesktop = NULL;
|
||||
static WidgetT *_guiLastWidgetLeft = NULL;
|
||||
static uint8_t _guiLastWidgetLeftEvent = MOUSE_EVENT_NONE;
|
||||
static WidgetT *_guiFocused = NULL;
|
||||
static uint8_t _guiHasStopped = 0;
|
||||
static WidgetT ***_guiDeleteList = NULL;
|
||||
|
||||
|
||||
// Widget Magic Debug Info
|
||||
|
@ -63,6 +65,8 @@ static char *_magicDebugNames[MAGIC_COUNT] = {
|
|||
};
|
||||
|
||||
|
||||
static void guiDeleteList(void);
|
||||
static void guiDeleteListItem(WidgetT **widget);
|
||||
static void guiPaintBoundsGet(WidgetT *widget, RectT *pos);
|
||||
static void guiKeyboardChildrenProcess(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
|
||||
static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse);
|
||||
|
@ -120,7 +124,7 @@ void guiAttach(WidgetT *parent, WidgetT *child) {
|
|||
|
||||
void guiComposite() {
|
||||
WidgetT *widget = (WidgetT *)_guiDesktop;
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t len;
|
||||
size_t x;
|
||||
|
||||
// Repaint anyone who needs it.
|
||||
|
@ -133,9 +137,8 @@ void guiComposite() {
|
|||
surfaceBlit(widget->surface, widget->pos.x, widget->pos.y);
|
||||
}
|
||||
|
||||
//***TODO*** This is wrong. Should be recursive.
|
||||
|
||||
// Now render all surface-containing children to the VBE buffer.
|
||||
len = arrlenu(widget->children);
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
if (GUI_GET_FLAG(widget->children[x], WIDGET_FLAG_OWNS_SURFACE)) {
|
||||
|
@ -146,20 +149,113 @@ void guiComposite() {
|
|||
}
|
||||
|
||||
|
||||
void guiDebugAreaShow(WidgetT *widget) {
|
||||
RectT r;
|
||||
|
||||
guiWidgetBoundsDrawableOnScreenGet(widget, &r);
|
||||
logWrite("%s: %dx%d\n", _magicDebugNames[widget->magic], r.w, r.h);
|
||||
}
|
||||
|
||||
|
||||
void guiDebugWidgetTreeDump(WidgetT *widget, uint16_t depth) {
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t x;
|
||||
char line[256];
|
||||
|
||||
for (x=0; x<depth*2; x++) line[x] = '-';
|
||||
line[x] = 0;
|
||||
|
||||
logWrite("%s %s P:%dx%d-%dx%d M:%dx%d-%dx%d C:%dx%d-%dx%d F:%d\n",
|
||||
line,
|
||||
_magicDebugNames[widget->magic],
|
||||
widget->pos.x, widget->pos.y, widget->pos.w, widget->pos.h,
|
||||
widget->margin.x, widget->margin.y, widget->margin.w, widget->margin.h,
|
||||
widget->clip.x, widget->clip.y, widget->clip.w, widget->clip.h,
|
||||
widget->flags);
|
||||
|
||||
// Mark all children.
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
guiDebugWidgetTreeDump(widget->children[x], depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void guiDelete(WidgetT **widget) {
|
||||
WidgetT *w = *widget;
|
||||
size_t len = arrlenu(w->children);
|
||||
size_t x = 0;
|
||||
// Since deleting happens in widget events, it's not safe to do it
|
||||
// immediately. Instead, we make a list of what to delete and
|
||||
// then process it before painting.
|
||||
arrput(_guiDeleteList, widget);
|
||||
}
|
||||
|
||||
|
||||
static void guiDeleteList(void) {
|
||||
WidgetT **w = NULL;
|
||||
|
||||
while (arrlen(_guiDeleteList) > 0) {
|
||||
w = arrpop(_guiDeleteList);
|
||||
guiDeleteListItem(w);
|
||||
}
|
||||
|
||||
arrfree(_guiDeleteList);
|
||||
_guiDeleteList = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void guiDeleteListItem(WidgetT **widget) {
|
||||
WidgetT *w = *widget;
|
||||
size_t len = arrlenu(w->children);
|
||||
size_t plen = arrlen(w->parent != NULL ? w->parent->children : 0);
|
||||
size_t x = 0;
|
||||
uint8_t nuke = 1;
|
||||
static uint16_t depth = 0;
|
||||
|
||||
// Delete children.
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
guiDelete(&w->children[x]);
|
||||
depth++;
|
||||
guiDeleteListItem(&w->children[x]);
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove us from parent children list.
|
||||
if (depth == 0) {
|
||||
if (plen > 0) {
|
||||
for (x=0; x<plen; x++) {
|
||||
if (w == w->parent->children[x]) {
|
||||
arrdel(w->parent->children, x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Was this the last child in the list?
|
||||
if (plen == 1) {
|
||||
// Erase the list.
|
||||
arrfree(w->parent->children);
|
||||
w->parent->children = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we were involved in a mouse event, get out of it.
|
||||
if (w == _guiLastWidgetLeft) _guiLastWidgetLeft = NULL;
|
||||
if (w == _guiFocused) _guiFocused = NULL;
|
||||
|
||||
// Delete us.
|
||||
w->delMethod(&w);
|
||||
//logWrite("Deleting %s %p\n", _magicDebugNames[w->magic], w);
|
||||
if (w->delMethod != NULL) w->delMethod(&w);
|
||||
arrfree(w->children);
|
||||
if (w->surface != NULL) {
|
||||
// Only free the surface if we own it. If it's our parent's, ignore.
|
||||
if (w->parent != NULL) {
|
||||
if (w->surface == w->parent->surface) nuke = 0;
|
||||
}
|
||||
if (nuke) surfaceDestroy(&w->surface);
|
||||
}
|
||||
free(w);
|
||||
w = NULL;
|
||||
*widget = w;
|
||||
|
||||
// Make sure we're not drawing into oblivion.
|
||||
surfaceSet(NULL);
|
||||
|
@ -195,6 +291,11 @@ void guiFocusSet(WidgetT *widget) {
|
|||
}
|
||||
|
||||
|
||||
uint8_t guiHasStopped(void) {
|
||||
return _guiHasStopped;
|
||||
}
|
||||
|
||||
|
||||
static void guiKeyboardChildrenProcess(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
|
||||
size_t len;
|
||||
size_t x;
|
||||
|
@ -246,21 +347,13 @@ static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse) {
|
|||
uint8_t event = MOUSE_EVENT_NONE;
|
||||
static WidgetT *focusDown = NULL;
|
||||
|
||||
// Search children backwards for active widget before checking this widget.
|
||||
len = arrlenu(widget->children);
|
||||
for (x=len-1; x>=0; --x) {
|
||||
if (guiMouseChildrenProcess(widget->children[x], mouse)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Get widget and screen coordinates of pointer.
|
||||
guiWidgetPositionOnScreenGet(widget, &r);
|
||||
sx = r.x;
|
||||
sy = r.y;
|
||||
guiMousePositionOnWidgetGet(widget, mouse, &mx, &my);
|
||||
|
||||
//logWrite("Mouse %dx%d Widget %s %dx%d\n", mouse->x, mouse->y, MagicDebugNames[widget->magic], sx, sy);
|
||||
//logWrite("Mouse %dx%d Widget %s %dx%d Screen %dx%d\n", mouse->x, mouse->y, _magicDebugNames[widget->magic], mx, my, sx, sy);
|
||||
|
||||
// Serious hack to make window dragging work better.
|
||||
// This is because it's possible to move the mouse faster than METRIC_WINDOW_TITLE_GRAB_HEIGHT pixels
|
||||
|
@ -270,6 +363,14 @@ static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Search children backwards for active widget before checking this widget.
|
||||
len = arrlenu(widget->children);
|
||||
for (x=len-1; x>=0; --x) {
|
||||
if (guiMouseChildrenProcess(widget->children[x], mouse)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the mouse inside this widget?
|
||||
if (mouse->x >= sx && mouse->y >= sy && mouse->x < sx + widget->pos.w && mouse->y < sy + widget->pos.h) {
|
||||
|
||||
|
@ -277,7 +378,9 @@ static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse) {
|
|||
if (_guiLastWidgetLeft != widget) {
|
||||
|
||||
// Tell previous widget we're moving out.
|
||||
if (_guiLastWidgetLeft->mouseEventMethod) _guiLastWidgetLeft->mouseEventMethod(_guiLastWidgetLeft, mouse, mx, my, MOUSE_EVENT_OUT);
|
||||
if (_guiLastWidgetLeft) {
|
||||
if (_guiLastWidgetLeft->mouseEventMethod) _guiLastWidgetLeft->mouseEventMethod(_guiLastWidgetLeft, mouse, mx, my, MOUSE_EVENT_OUT);
|
||||
}
|
||||
|
||||
// Tell new widget we've moved in.
|
||||
event = MOUSE_EVENT_IN;
|
||||
|
@ -329,10 +432,13 @@ void guiMouseProcess(MouseT *mouse) {
|
|||
|
||||
|
||||
void guiPaint(WidgetT *widget) {
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t len;
|
||||
size_t x;
|
||||
RectT pos;
|
||||
|
||||
// Process any pending widget deletions.
|
||||
guiDeleteList();
|
||||
|
||||
// Paint us. Widget handles dirty flag so they can animate if needed.
|
||||
if (widget->paintMethod) {
|
||||
surfaceSet(widget->surface);
|
||||
|
@ -341,6 +447,7 @@ void guiPaint(WidgetT *widget) {
|
|||
}
|
||||
|
||||
// Paint all children.
|
||||
len = arrlenu(widget->children);
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
guiPaint(widget->children[x]);
|
||||
|
@ -368,6 +475,19 @@ WidgetT *guiRootGet(void) {
|
|||
}
|
||||
|
||||
|
||||
void guiShutdown(void) {
|
||||
// Unload fonts.
|
||||
fontUnload(&_guiFont16);
|
||||
fontUnload(&_guiFont14);
|
||||
fontUnload(&_guiFont8);
|
||||
_guiFont = NULL;
|
||||
|
||||
// Delete all widgets in GUI tree.
|
||||
guiDelete((WidgetT **)&_guiDesktop);
|
||||
guiDeleteList();
|
||||
}
|
||||
|
||||
|
||||
DesktopT *guiStartup(void) {
|
||||
|
||||
_guiMetric[METRIC_BUTTON_BEZEL_SIZE] = 2;
|
||||
|
@ -457,15 +577,8 @@ DesktopT *guiStartup(void) {
|
|||
}
|
||||
|
||||
|
||||
void guiShutdown(void) {
|
||||
// Unload fonts.
|
||||
fontUnload(&_guiFont16);
|
||||
fontUnload(&_guiFont14);
|
||||
fontUnload(&_guiFont8);
|
||||
_guiFont = NULL;
|
||||
|
||||
// Delete all widgets in GUI tree.
|
||||
guiDelete((WidgetT **)&_guiDesktop);
|
||||
void guiStop(void) {
|
||||
_guiHasStopped = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -525,28 +638,3 @@ void guiWidgetPositionOnScreenGet(WidgetT *widget, RectT *pos) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void guiWidgetTreeDump(WidgetT *widget, uint16_t depth) {
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t x;
|
||||
char line[256];
|
||||
|
||||
for (x=0; x<depth*2; x++) line[x] = '-';
|
||||
line[x] = 0;
|
||||
|
||||
logWrite("%s %s P:%dx%d-%dx%d M:%dx%d-%dx%d C:%dx%d-%dx%d F:%d\n",
|
||||
line,
|
||||
_magicDebugNames[widget->magic],
|
||||
widget->pos.x, widget->pos.y, widget->pos.w, widget->pos.h,
|
||||
widget->margin.x, widget->margin.y, widget->margin.w, widget->margin.h,
|
||||
widget->clip.x, widget->clip.y, widget->clip.w, widget->clip.h,
|
||||
widget->flags);
|
||||
|
||||
// Mark all children.
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
guiWidgetTreeDump(widget->children[x], depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define GUI_CLEAR_FLAG(w,f) ((w)->flags &= (~(1 << (f))))
|
||||
|
||||
#define W(w) ((WidgetT *)w)
|
||||
#define D(w) ((WidgetT **)&w)
|
||||
|
||||
|
||||
// Widget Magics
|
||||
|
@ -161,22 +162,25 @@ extern WindowT *_guiActiveWindow;
|
|||
|
||||
void guiAttach(WidgetT *parent, WidgetT *child);
|
||||
void guiComposite(void);
|
||||
void guiDebugAreaShow(WidgetT *widget);
|
||||
void guiDebugWidgetTreeDump(WidgetT *widget, uint16_t depth);
|
||||
void guiDelete(WidgetT **widget);
|
||||
WidgetT *guiFocusGet(void);
|
||||
void guiFocusSet(WidgetT *widget);
|
||||
uint8_t guiHasStopped(void);
|
||||
void guiKeyboardProcess(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
|
||||
void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y);
|
||||
void guiMouseProcess(MouseT *mouse);
|
||||
void guiPaint(WidgetT *widget);
|
||||
WidgetT *guiRootGet(void);
|
||||
DesktopT *guiStartup(void);
|
||||
void guiShutdown(void);
|
||||
DesktopT *guiStartup(void);
|
||||
void guiStop(void);
|
||||
void *guiUserDataGet(WidgetT *widget);
|
||||
void guiUserDataSet(WidgetT *widget, void *userData);
|
||||
void guiWidgetAndChildrenDirtySet(WidgetT *widget);
|
||||
void guiWidgetBoundsDrawableOnScreenGet(WidgetT *widget, RectT *bounds);
|
||||
void guiWidgetPositionOnScreenGet(WidgetT *widget, RectT *pos);
|
||||
void guiWidgetTreeDump(WidgetT *widget, uint16_t depth);
|
||||
|
||||
|
||||
#endif // GUI_H
|
||||
|
|
|
@ -52,11 +52,7 @@ void labelColorForegroundSet(LabelT *label, ColorT color) {
|
|||
static void labelDel(WidgetT **widget) {
|
||||
LabelT *l = (LabelT *)*widget;
|
||||
|
||||
arrfree(l->base.children);
|
||||
if (l->title) free(l->title);
|
||||
free(l);
|
||||
l = NULL;
|
||||
*widget = W(l);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,12 +52,6 @@ static void listboxDel(WidgetT **widget) {
|
|||
}
|
||||
}
|
||||
arrfree(l->values);
|
||||
|
||||
arrfree(l->base.children);
|
||||
if (l->title) free(l->title);
|
||||
free(l);
|
||||
l = NULL;
|
||||
*widget = W(l);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,12 +34,8 @@ void pictureClickHandlerSet(PictureT *picture, widgetCallback callback) {
|
|||
static void pictureDel(WidgetT **widget) {
|
||||
PictureT *p = (PictureT *)*widget;
|
||||
|
||||
arrfree(p->base.children);
|
||||
if (p->image) imageUnload(&p->image);
|
||||
if (p->filename) free(p->filename);
|
||||
free(p);
|
||||
p = NULL;
|
||||
*widget = W(p);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,11 +36,7 @@ void radioClickHandlerSet(RadioT *radio, widgetCallback callback) {
|
|||
static void radioDel(WidgetT **widget) {
|
||||
RadioT *r = (RadioT *)*widget;
|
||||
|
||||
arrfree(r->base.children);
|
||||
if (r->title) free(r->title);
|
||||
free(r);
|
||||
r = NULL;
|
||||
*widget = W(r);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -502,11 +502,6 @@ static void terminalDel(WidgetT **widget) {
|
|||
free(t->cells[x]);
|
||||
}
|
||||
free(t->cells);
|
||||
|
||||
arrfree(t->base.children);
|
||||
free(t);
|
||||
t = NULL;
|
||||
*widget = W(t);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,12 +32,8 @@ static void textboxPaint(WidgetT *widget, RectT pos);
|
|||
static void textboxDel(WidgetT **widget) {
|
||||
TextboxT *t = (TextboxT *)*widget;
|
||||
|
||||
arrfree(t->base.children);
|
||||
if (t->title) free(t->title);
|
||||
if (t->value) free(t->value);
|
||||
free(t);
|
||||
t = NULL;
|
||||
*widget = W(t);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,11 +47,7 @@ static void updownVisibleSet(UpdownT *updown);
|
|||
static void updownDel(WidgetT **widget) {
|
||||
UpdownT *u = (UpdownT *)*widget;
|
||||
|
||||
arrfree(u->base.children);
|
||||
if (u->title) free(u->title);
|
||||
free(u);
|
||||
u = NULL;
|
||||
*widget = W(u);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,19 +22,6 @@
|
|||
#include "window.h"
|
||||
|
||||
|
||||
static void widgetDel(WidgetT **widget);
|
||||
|
||||
|
||||
static void widgetDel(WidgetT **widget) {
|
||||
WidgetT *w = (WidgetT *)*widget;
|
||||
|
||||
arrfree(w->children);
|
||||
free(w);
|
||||
w = NULL;
|
||||
*widget = w;
|
||||
}
|
||||
|
||||
|
||||
uint16_t widgetHeightGet(WidgetT *widget) {
|
||||
return widget->pos.h;
|
||||
}
|
||||
|
@ -59,7 +46,7 @@ WidgetT *widgetInit(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint
|
|||
widget->children = NULL;
|
||||
widget->parent = NULL;
|
||||
widget->window = NULL;
|
||||
widget->delMethod = widgetDel;
|
||||
widget->delMethod = NULL;
|
||||
widget->focusMethod = NULL;
|
||||
widget->keyboardEventMethod = NULL;
|
||||
widget->paintMethod = NULL;
|
||||
|
|
|
@ -79,12 +79,7 @@ static void windowAllDeactivate(WidgetT *widget) {
|
|||
static void windowDel(WidgetT **widget) {
|
||||
WindowT *w = (WindowT *)*widget;
|
||||
|
||||
surfaceDestroy(&w->base.surface);
|
||||
arrfree(w->base.children);
|
||||
if (w->title) free(w->title);
|
||||
free(w);
|
||||
w = NULL;
|
||||
*widget = W(w);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ static MouseT _mouse;
|
|||
static SDL_Window *_window = NULL;
|
||||
static SDL_Renderer *_renderer = NULL;
|
||||
static SDL_Surface *_surface = NULL;
|
||||
static SDL_Texture *_texture = NULL;
|
||||
static uint16_t _width = 0;
|
||||
static uint16_t _height = 0;
|
||||
static uint8_t _windowScale = 1;
|
||||
|
@ -253,40 +254,28 @@ uint16_t vbeDisplayWidthGet(void) {
|
|||
|
||||
|
||||
ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
// Pixels are 8:8:8:8 RGBA - SDL_PIXELFORMAT_RGBA8888
|
||||
return
|
||||
(red << 24) |
|
||||
(green << 16) |
|
||||
(blue << 8);
|
||||
(blue << 8) |
|
||||
255;
|
||||
}
|
||||
|
||||
|
||||
void vbePresent(void) {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
SurfaceT *s = surfaceOffScreenGet();
|
||||
uint32_t p;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
|
||||
SDL_SetRenderTarget(_renderer, NULL);
|
||||
|
||||
//***TODO*** This is stupid inefficient.
|
||||
for (y=0; y<s->height; y++) {
|
||||
for (x=0; x<s->width; x++) {
|
||||
p = s->buffer.bits32[y * s->width + x];
|
||||
r = (p & 0xFF000000) >> 24;
|
||||
g = (p & 0x00FF0000) >> 16;
|
||||
b = (p & 0x0000FF00) >> 8;
|
||||
SDL_SetRenderDrawColor(_renderer, r, g, b, 255);
|
||||
SDL_RenderDrawPoint(_renderer, x, y);
|
||||
}
|
||||
}
|
||||
void *pixels;
|
||||
int pitch;
|
||||
SurfaceT *s = surfaceOffScreenGet();
|
||||
|
||||
SDL_LockTexture(_texture, NULL, &pixels, &pitch);
|
||||
memcpy(pixels, s->buffer.bits8, s->bytes);
|
||||
SDL_UnlockTexture(_texture);
|
||||
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
|
||||
SDL_RenderPresent(_renderer);
|
||||
|
||||
// Throttle this to some sane frame rate.
|
||||
//SDL_Delay(32);
|
||||
SDL_Delay(32);
|
||||
}
|
||||
|
||||
|
||||
|
@ -297,6 +286,11 @@ int16_t vbeInfoShow(void) {
|
|||
|
||||
|
||||
int16_t vbeShutdown(void) {
|
||||
if (_texture) {
|
||||
SDL_DestroyTexture(_texture);
|
||||
_texture = NULL;
|
||||
}
|
||||
|
||||
if (_renderer) {
|
||||
SDL_DestroyRenderer(_renderer);
|
||||
_renderer = NULL;
|
||||
|
@ -327,6 +321,7 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
|
|||
_window = SDL_CreateWindow("GUI Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xRes, yRes, SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
_surface = SDL_GetWindowSurface(_window);
|
||||
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
_texture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, xRes, yRes);
|
||||
|
||||
SDL_RenderSetLogicalSize(_renderer, xRes, yRes);
|
||||
SDL_SetWindowSize(_window, xRes * _windowScale, yRes * _windowScale);
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
|
||||
|
||||
//#define TESTING
|
||||
|
||||
|
||||
/*
|
||||
* To Do:
|
||||
*
|
||||
|
@ -29,7 +32,6 @@
|
|||
* - Use LabelT in all widgets that have a label
|
||||
* - Find a light grey to replace white widget data areas
|
||||
* - No thumb in listbox scrollbar
|
||||
* - Window dragging is being screwball
|
||||
*
|
||||
* - Random crash on exit - looks memwatch / task related - hasn't happened on DOS yet
|
||||
*/
|
||||
|
@ -45,48 +47,25 @@
|
|||
#include "image.h"
|
||||
#include "font.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "gui.h"
|
||||
#include "widget.h"
|
||||
#include "desktop.h"
|
||||
#include "window.h"
|
||||
#include "button.h"
|
||||
#include "label.h"
|
||||
#include "checkbox.h"
|
||||
#include "radio.h"
|
||||
#include "picture.h"
|
||||
#include "frame.h"
|
||||
#include "textbox.h"
|
||||
#include "updown.h"
|
||||
#include "listbox.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include "taglist.h"
|
||||
#include "welcome.h"
|
||||
|
||||
#ifdef TESTING
|
||||
#include "test.h"
|
||||
#endif
|
||||
|
||||
|
||||
static TerminalT *t1 = NULL;
|
||||
static uint8_t lastKey = 0;
|
||||
static void taskGuiEventLoop(void *data);
|
||||
|
||||
|
||||
static void buttonClick(WidgetT *widget);
|
||||
static void mainLoop(void *data);
|
||||
//static void test(void *data);
|
||||
static void testTagList(void *data);
|
||||
static void testTerminal(void *data);
|
||||
static void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle);
|
||||
|
||||
|
||||
static void buttonClick(WidgetT *widget) {
|
||||
logWrite("'%s' was clicked.\n", ((ButtonT *)widget)->title);
|
||||
}
|
||||
|
||||
|
||||
static void mainLoop(void *data) {
|
||||
static void taskGuiEventLoop(void *data) {
|
||||
MouseT *mouse = NULL;
|
||||
ImageT *pointer = NULL;
|
||||
ColorT alpha;
|
||||
int8_t key = 0;
|
||||
#ifdef TESTING
|
||||
int8_t debugState = 0;
|
||||
#endif
|
||||
|
||||
(void)data;
|
||||
|
||||
|
@ -97,17 +76,17 @@ static void mainLoop(void *data) {
|
|||
timerUpdate();
|
||||
mouse = mouseRead();
|
||||
if (keyHit()) {
|
||||
key = keyASCIIGet();
|
||||
lastKey = key; //***DEBUG***
|
||||
#ifdef TESTING
|
||||
lastKey = keyASCIIGet(); //***DEBUG***
|
||||
#endif
|
||||
guiKeyboardProcess(keyASCIIGet(), keyExtendedGet(), keyScanCodeGet(), keyShiftGet(), keyControlGet(), keyAltGet());
|
||||
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", key, keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
|
||||
} else {
|
||||
key = 0;
|
||||
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", keyASCIIGet(), keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
|
||||
}
|
||||
guiMouseProcess(mouse);
|
||||
guiComposite();
|
||||
imageRenderWithAlpha(pointer, mouse->x, mouse->y, alpha);
|
||||
|
||||
#ifdef TESTING
|
||||
if (key == '=') guiWidgetTreeDump(guiRootGet(), 0);
|
||||
if (key == '+') {
|
||||
debugState++;
|
||||
|
@ -115,308 +94,30 @@ static void mainLoop(void *data) {
|
|||
}
|
||||
if (debugState > 0) widgetDebugDraw(guiRootGet(), debugState - 1);
|
||||
//if (timerHalfSecondOn) guiDrawRectangle(0, 0, vbeSurfaceWidthGet() - 1, vbeSurfaceHeightGet() - 1, vbeMakeColor(255, 255, 255));
|
||||
#endif
|
||||
|
||||
vbeVBlankWait();
|
||||
vbePresent();
|
||||
taskYield();
|
||||
#ifdef TESTING
|
||||
} while (key != 27); // Exit on ESC.
|
||||
#else
|
||||
} while (!guiHasStopped());
|
||||
#endif
|
||||
|
||||
imageUnload(&pointer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static void test(void *data) {
|
||||
DesktopT *desktop = (DesktopT *)guiRootGet();
|
||||
WindowT *w1 = NULL;
|
||||
WindowT *w2 = NULL;
|
||||
WindowT *w3 = NULL;
|
||||
WindowT *w4 = NULL;
|
||||
ButtonT *b1 = NULL;
|
||||
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;
|
||||
TextboxT *tb1 = NULL;
|
||||
TextboxT *tb2 = NULL;
|
||||
UpdownT *u1 = NULL;
|
||||
ListboxT *lb1 = NULL;
|
||||
|
||||
(void)data;
|
||||
|
||||
// Windows
|
||||
w1 = windowNew(300, 25, 300, 200, "Window 1");
|
||||
guiAttach(W(desktop), W(w1));
|
||||
w2 = windowNew(150, 150, 300, 200, "Window 2");
|
||||
guiAttach(W(desktop), W(w2));
|
||||
w3 = windowNew(300, 300, 300, 200, "Window 3");
|
||||
guiAttach(W(desktop), W(w3));
|
||||
w4 = windowNew(10, 10, 7 + 8 + (80 * 8), 26 + 8 + (24 * 14), "Terminal");
|
||||
guiAttach(W(desktop), W(w4));
|
||||
|
||||
// Window 1
|
||||
p1 = pictureNew(0, 0, "kanga.png");
|
||||
guiAttach(W(w1), W(p1));
|
||||
lb1 = listboxNew(155, 10, 120, 140, "List Box");
|
||||
listboxItemAdd(lb1, "One");
|
||||
listboxItemAdd(lb1, "Two");
|
||||
listboxItemAdd(lb1, "Three");
|
||||
listboxItemAdd(lb1, "Four");
|
||||
listboxItemAdd(lb1, "Five");
|
||||
listboxItemAdd(lb1, "Six");
|
||||
listboxItemAdd(lb1, "Seven");
|
||||
listboxItemAdd(lb1, "Eight");
|
||||
listboxItemAdd(lb1, "Nine");
|
||||
listboxItemAdd(lb1, "Ten");
|
||||
listboxStepSet(lb1, 3);
|
||||
guiAttach(W(w1), W(lb1));
|
||||
|
||||
// Window 2
|
||||
r1a = radioNew(10, 10, "Radio 1a", 1);
|
||||
guiAttach(W(w2), W(r1a));
|
||||
r2a = radioNew(20 + widgetWidthGet(W(r1a)), 10, "Radio 2a", 1);
|
||||
guiAttach(W(w2), W(r2a));
|
||||
r3a = radioNew(30 + widgetWidthGet(W(r1a)) + widgetWidthGet(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 + widgetWidthGet(W(r1b)), 35, "Radio 2b", 2);
|
||||
guiAttach(W(w2), W(r2b));
|
||||
r3b = radioNew(30 + widgetWidthGet(W(r1b)) + widgetWidthGet(W(r2b)), 35, "Radio 3b", 2);
|
||||
guiAttach(W(w2), W(r3b));
|
||||
radioSelectedSet(r1a);
|
||||
radioSelectedSet(r2b);
|
||||
tb1 = textboxNew(10, 60, 265, "Test Textbox");
|
||||
textboxValueSet(tb1, "Really long text string to edit!");
|
||||
guiAttach(W(w2), W(tb1));
|
||||
tb2 = textboxNew(10, 85, 265, "Test Textbox");
|
||||
textboxValueSet(tb2, "Short string.");
|
||||
guiAttach(W(w2), W(tb2));
|
||||
u1 = updownNew(10, 110, 0, 1024, 5, "UpDown");
|
||||
guiAttach(W(w2), W(u1));
|
||||
|
||||
// Window 3
|
||||
f1 = frameNew(10, 5, 175, 125, "Test Frame");
|
||||
guiAttach(W(w3), W(f1));
|
||||
b1 = buttonNew(0, 0, "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));
|
||||
|
||||
// Window 4 - Terminal
|
||||
t1 = terminalNew(0, 0, 80, 24);
|
||||
guiAttach(W(w4), W(t1));
|
||||
|
||||
taskCreate(testTerminal, "terminalTest");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static void testTagList(void *data) {
|
||||
WindowT *w1 = NULL;
|
||||
WindowT *w2 = NULL;
|
||||
WindowT *w3 = NULL;
|
||||
WindowT *w4 = NULL;
|
||||
ButtonT *b1 = NULL;
|
||||
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;
|
||||
TextboxT *tb1 = NULL;
|
||||
TextboxT *tb2 = NULL;
|
||||
UpdownT *u1 = NULL;
|
||||
ListboxT *lb1 = NULL;
|
||||
|
||||
(void)data;
|
||||
|
||||
TagItemT ui[] = {
|
||||
T_START,
|
||||
|
||||
T_WINDOW, O(w1),
|
||||
T_TITLE, P("Window 1"),
|
||||
T_X, 300, T_Y, 25, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_PICTURE, O(p1),
|
||||
T_X, 0, T_Y, 0,
|
||||
T_FILENAME, P("kanga.png"),
|
||||
T_PICTURE, T_DONE,
|
||||
T_LISTBOX, O(lb1),
|
||||
T_TITLE, P("Listbox"),
|
||||
T_X, 155, T_Y, 10, T_WIDTH, 120, T_HEIGHT, 140,
|
||||
T_ITEM, P("One"),
|
||||
T_ITEM, P("Two"),
|
||||
T_ITEM, P("Three"),
|
||||
T_ITEM, P("Four"),
|
||||
T_ITEM, P("Five"),
|
||||
T_ITEM, P("Six"),
|
||||
T_ITEM, P("Seven"),
|
||||
T_ITEM, P("Eight"),
|
||||
T_ITEM, P("Nine"),
|
||||
T_ITEM, P("Ten"),
|
||||
T_STEP, 3,
|
||||
T_LISTBOX, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w2),
|
||||
T_TITLE, P("Window 2"),
|
||||
T_X, 150, T_Y, 150, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_RADIOBUTTON, O(r1a),
|
||||
T_TITLE, P("Radio 1a"),
|
||||
T_X, 10, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_SELECTED, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r2a),
|
||||
T_TITLE, P("Radio 2a"),
|
||||
T_X, 20 + 80, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r3a),
|
||||
T_TITLE, P("Radio 3a"),
|
||||
T_X, 30 + 80 * 2, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r1b),
|
||||
T_TITLE, P("Radio 1b"),
|
||||
T_X, 10, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r2b),
|
||||
T_TITLE, P("Radio 2b"),
|
||||
T_X, 20 + 80, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_SELECTED, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r3b),
|
||||
T_TITLE, P("Radio 3b"),
|
||||
T_X, 30 + 80 * 2, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_TEXTBOX, O(tb1),
|
||||
T_TITLE, P("Test Textbox"),
|
||||
T_X, 10, T_Y, 60, T_WIDTH, 265,
|
||||
T_VALUE, P("Really long text string to edit!"),
|
||||
T_TEXTBOX, T_DONE,
|
||||
T_TEXTBOX, O(tb2),
|
||||
T_TITLE, P("Test Textbox"),
|
||||
T_X, 10, T_Y, 85, T_WIDTH, 265,
|
||||
T_VALUE, P("Short String."),
|
||||
T_TEXTBOX, T_DONE,
|
||||
T_UPDOWN, O(u1),
|
||||
T_TITLE, P("UpDown"),
|
||||
T_X, 10, T_Y, 120,
|
||||
T_MINIMUM, 0, T_MAXIMUM, 1024, T_STEP, 5,
|
||||
T_UPDOWN, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w3),
|
||||
T_TITLE, P("Window 3"),
|
||||
T_X, 300, T_Y, 300, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_FRAME, O(f1),
|
||||
T_TITLE, P("Test Frame"),
|
||||
T_X, 10, T_Y, 5, T_WIDTH, 175, T_HEIGHT, 125,
|
||||
T_BUTTON, O(b1),
|
||||
T_TITLE, P("Test Button"),
|
||||
T_X, 0, T_Y, 0,
|
||||
T_CLICK, P(buttonClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_LABEL, O(l1),
|
||||
T_TITLE, P("Test Label"),
|
||||
T_X, 10, T_Y, 40,
|
||||
T_LABEL, T_DONE,
|
||||
T_CHECKBOX, O(c1),
|
||||
T_TITLE, P("Test Checkbox"),
|
||||
T_X, 10, T_Y, 65,
|
||||
T_CHECKBOX, T_DONE,
|
||||
T_FRAME, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w4),
|
||||
T_TITLE, P("Terminal"),
|
||||
T_X, 10, T_Y, 10, T_WIDTH, 7 + 8 + (80 * 8), T_HEIGHT, 26 + 8 + (24 * 14),
|
||||
T_TERMINAL, O(t1),
|
||||
T_X, 0, T_Y, 0, T_WIDTH, 80, T_HEIGHT, 24,
|
||||
T_TERMINAL, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_END
|
||||
};
|
||||
|
||||
tagListRun(ui);
|
||||
|
||||
taskCreate(testTerminal, "terminalTest");
|
||||
}
|
||||
|
||||
|
||||
static void testTerminal(void *data) {
|
||||
FILE *in = NULL;
|
||||
char *buffer = NULL;
|
||||
uint16_t length = 0;
|
||||
|
||||
(void)data;
|
||||
|
||||
// Load ANSI file for terminal test.
|
||||
in = fopen("kanga.ans", "rt");
|
||||
fseek(in, 0, SEEK_END);
|
||||
length = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
buffer = (char *)malloc(length + 1);
|
||||
fread(buffer, 1, length, in);
|
||||
fclose(in);
|
||||
buffer[length] = 0;
|
||||
|
||||
terminalStringPrint(t1, buffer);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle) {
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t i;
|
||||
RectT r;
|
||||
|
||||
if (debugToggle) {
|
||||
// Clipping region (blue)
|
||||
guiWidgetBoundsDrawableOnScreenGet(widget, &r);
|
||||
surfaceRectangleDraw(r.x, r.y, r.x + r.w, r.y + r.h, vbeColorMake(0, 0, 255));
|
||||
} else {
|
||||
// Widget border (red)
|
||||
guiWidgetPositionOnScreenGet(widget, &r);
|
||||
surfaceRectangleDraw(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeColorMake(255, 0, 0));
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
for (i=0; i<len; i++) {
|
||||
widgetDebugDraw(widget->children[i], debugToggle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
uint16_t xResolution = 0;
|
||||
uint16_t yResolution = 0;
|
||||
uint16_t colorDepth = 0;
|
||||
char logName[32] = { "log.log" };
|
||||
char *c = NULL;
|
||||
int16_t x = strlen(argv[0]);
|
||||
|
||||
memoryStartup();
|
||||
memoryStartup(argv[0]);
|
||||
logOpenByHandle(memoryLogHandleGet());
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
|
@ -424,21 +125,6 @@ int main(int argc, char *argv[]) {
|
|||
printf("Copyright (C) 2020-2021 Scott Duensing scott@kangaroopunch.com\n\n");
|
||||
fflush(stdout);
|
||||
|
||||
// Find last portion of filename.
|
||||
while (x > 0) {
|
||||
if (argv[0][x] == '/' || argv[0][x] == '\\') break;
|
||||
x--;
|
||||
}
|
||||
if (strlen(argv[0]) - x < 32) {
|
||||
// Replace any extension with ".log"
|
||||
strncpy(logName, &argv[0][x + 1], 31);
|
||||
c = strstr(logName, ".");
|
||||
if (c) *c = 0;
|
||||
strncat(logName, ".log", 31);
|
||||
}
|
||||
|
||||
logOpen(logName, 0);
|
||||
|
||||
// Command line needs to have the desired resolution and color depth on it.
|
||||
if (argc != 4) {
|
||||
vbeInfoShow();
|
||||
|
@ -463,8 +149,13 @@ int main(int argc, char *argv[]) {
|
|||
guiStartup();
|
||||
taskStartup();
|
||||
|
||||
taskCreate(testTagList, "testTagList");
|
||||
taskCreate(mainLoop, "mainLoop");
|
||||
#ifdef TESTING
|
||||
taskCreate(taskTestTagList, NULL);
|
||||
#else
|
||||
taskCreate(taskWelcome, NULL);
|
||||
#endif
|
||||
|
||||
taskCreate(taskGuiEventLoop, NULL);
|
||||
taskRun();
|
||||
|
||||
taskShutdown();
|
||||
|
@ -475,7 +166,6 @@ int main(int argc, char *argv[]) {
|
|||
vbeShutdown();
|
||||
|
||||
logClose();
|
||||
|
||||
memoryShutdown();
|
||||
|
||||
return 0;
|
||||
|
|
69
client/src/settings.c
Normal file
69
client/src/settings.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 "settings.h"
|
||||
#include "welcome.h"
|
||||
|
||||
#include "taglist.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "button.h"
|
||||
#include "frame.h"
|
||||
#include "radio.h"
|
||||
|
||||
|
||||
static WindowT *winSettings;
|
||||
static FrameT *frmComPorts;
|
||||
static ButtonT *btnOkay;
|
||||
|
||||
|
||||
static void btnOkayClick(WidgetT *widget);
|
||||
|
||||
|
||||
static void btnOkayClick(WidgetT *widget) {
|
||||
(void)widget;
|
||||
taskCreate(taskWelcome, NULL);
|
||||
guiDelete(D(winSettings));
|
||||
}
|
||||
|
||||
|
||||
void taskSettings(void *data) {
|
||||
|
||||
(void)data;
|
||||
|
||||
TagItemT ui[] = {
|
||||
T_START,
|
||||
T_WINDOW, O(winSettings),
|
||||
T_TITLE, P("Settings"),
|
||||
T_WIDTH, 200, T_HEIGHT, 200,
|
||||
T_BUTTON, O(btnOkay),
|
||||
T_TITLE, P("Okay"),
|
||||
T_CLICK, P(btnOkayClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
T_END
|
||||
};
|
||||
|
||||
tagListRun(ui);
|
||||
|
||||
guiDebugAreaShow(W(winSettings));
|
||||
guiDebugAreaShow(W(btnOkay));
|
||||
}
|
31
client/src/settings.h
Normal file
31
client/src/settings.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
|
||||
#include "os.h"
|
||||
|
||||
|
||||
void taskSettings(void *data);
|
||||
|
||||
|
||||
#endif // SETTINGS_H
|
|
@ -21,19 +21,29 @@
|
|||
#include "log.h"
|
||||
|
||||
|
||||
FILE *_log = NULL;
|
||||
static FILE *_log = NULL;
|
||||
static uint8_t _ourHandle = 0;
|
||||
|
||||
|
||||
uint8_t logOpen(char *filename, uint8_t append) {
|
||||
_log = fopen(filename, append ? "a" : "w");
|
||||
if (_log) return 1;
|
||||
if (_log) {
|
||||
return 1;
|
||||
_ourHandle = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void logOpenByHandle(FILE *handle) {
|
||||
_log = handle;
|
||||
}
|
||||
|
||||
|
||||
void logClose(void) {
|
||||
if (_log) {
|
||||
if (_log && _ourHandle) {
|
||||
fclose(_log);
|
||||
_ourHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,8 +54,8 @@ void logWrite(char *format, ...) {
|
|||
va_start(args, format);
|
||||
|
||||
#ifdef __linux__
|
||||
// Also output to stdout on Linux.
|
||||
va_list args2;
|
||||
|
||||
va_copy(args2, args);
|
||||
vfprintf(stdout, format, args2);
|
||||
fflush(stdout);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
|
||||
uint8_t logOpen(char *filename, uint8_t append);
|
||||
void logOpenByHandle(FILE *handle);
|
||||
void logClose(void);
|
||||
void logWrite(char *format, ...);
|
||||
|
||||
|
|
|
@ -21,20 +21,60 @@
|
|||
#include "memory.h"
|
||||
|
||||
|
||||
#ifdef MEMWATCH_STDIO
|
||||
FILE *_memoryLog = NULL;
|
||||
|
||||
|
||||
#ifdef MEMORY_CHECK_ENABLED
|
||||
void mwLogW(FILE *p);
|
||||
#endif
|
||||
|
||||
|
||||
FILE *memoryLogHandleGet(void) {
|
||||
return _memoryLog;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MEMORY_CHECK_ENABLED
|
||||
void memoryOutput(int c) {
|
||||
logWrite("%c", c);
|
||||
fputc(c, _memoryLog);
|
||||
fflush(_memoryLog);
|
||||
|
||||
fputc(c, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void memoryShutdown(void) {
|
||||
// Nada.
|
||||
}
|
||||
|
||||
|
||||
void memoryStartup(void) {
|
||||
#ifdef MEMWATCH_STDIO
|
||||
mwSetOutFunc(memoryOutput);
|
||||
#ifdef MEMORY_CHECK_ENABLED
|
||||
mwTerm();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void memoryStartup(char *appName) {
|
||||
char logName[32] = { "log.log" };
|
||||
char *c = NULL;
|
||||
int16_t x = strlen(appName);
|
||||
|
||||
// Find last portion of filename.
|
||||
while (x > 0) {
|
||||
if (appName[x] == '/' || appName[x] == '\\') break;
|
||||
x--;
|
||||
}
|
||||
if (strlen(appName) - x < 32) {
|
||||
// Replace any extension with ".log"
|
||||
strncpy(logName, &appName[x + 1], 31);
|
||||
c = strstr(logName, ".");
|
||||
if (c) *c = 0;
|
||||
strncat(logName, ".log", 31);
|
||||
}
|
||||
|
||||
_memoryLog = fopen(logName, "w");
|
||||
|
||||
#ifdef MEMORY_CHECK_ENABLED
|
||||
mwLogW(_memoryLog);
|
||||
mwSetOutFunc(memoryOutput);
|
||||
mwInit();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -24,16 +24,15 @@
|
|||
|
||||
#include "os.h"
|
||||
|
||||
|
||||
#ifdef MEMORY_CHECK_ENABLED
|
||||
#define MEMWATCH
|
||||
#define MEMWATCH_STDIO
|
||||
#include "memwatch/memwatch.h"
|
||||
#endif
|
||||
#include "memwatch/memwatch.h"
|
||||
|
||||
|
||||
void memoryShutdown(void);
|
||||
void memoryStartup(void);
|
||||
FILE *memoryLogHandleGet(void);
|
||||
void memoryShutdown(void);
|
||||
void memoryStartup(char *appName);
|
||||
|
||||
|
||||
#endif // MEMORY_H
|
||||
|
|
|
@ -247,6 +247,12 @@ static void tagListWidgetAttributeHandle(void) {
|
|||
parent = *w->parent;
|
||||
}
|
||||
|
||||
// Auto-center windows if position not specified.
|
||||
if (pos.x == 0 && pos.y == 0 && w->type == T_WINDOW) {
|
||||
pos.x = vbeDisplayWidthGet() / 2 - pos.w / 2;
|
||||
pos.y = vbeDisplayHeightGet() / 2 - pos.h / 2;
|
||||
}
|
||||
|
||||
// Create the widget.
|
||||
switch (w->type) {
|
||||
|
||||
|
@ -316,7 +322,7 @@ static void tagListWidgetAttributeHandle(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
guiUserDataSet(widget, userdata);
|
||||
if (userdata != NULL) guiUserDataSet(widget, userdata);
|
||||
|
||||
// Store everything we did.
|
||||
*w->widget = widget;
|
||||
|
|
336
client/src/test.c
Normal file
336
client/src/test.c
Normal file
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* 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 "test.h"
|
||||
|
||||
#include "task.h"
|
||||
#include "gui.h"
|
||||
#include "widget.h"
|
||||
#include "desktop.h"
|
||||
#include "window.h"
|
||||
#include "button.h"
|
||||
#include "label.h"
|
||||
#include "checkbox.h"
|
||||
#include "radio.h"
|
||||
#include "picture.h"
|
||||
#include "frame.h"
|
||||
#include "textbox.h"
|
||||
#include "updown.h"
|
||||
#include "listbox.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include "taglist.h"
|
||||
|
||||
|
||||
uint8_t lastKey = 0;
|
||||
|
||||
static TerminalT *t1 = NULL;
|
||||
|
||||
|
||||
static void buttonClick(WidgetT *widget);
|
||||
//static void test(void *data);
|
||||
static void testTerminal(void *data);
|
||||
|
||||
|
||||
static void buttonClick(WidgetT *widget) {
|
||||
logWrite("'%s' was clicked.\n", ((ButtonT *)widget)->title);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static void test(void *data) {
|
||||
DesktopT *desktop = (DesktopT *)guiRootGet();
|
||||
WindowT *w1 = NULL;
|
||||
WindowT *w2 = NULL;
|
||||
WindowT *w3 = NULL;
|
||||
WindowT *w4 = NULL;
|
||||
ButtonT *b1 = NULL;
|
||||
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;
|
||||
TextboxT *tb1 = NULL;
|
||||
TextboxT *tb2 = NULL;
|
||||
UpdownT *u1 = NULL;
|
||||
ListboxT *lb1 = NULL;
|
||||
|
||||
(void)data;
|
||||
|
||||
// Windows
|
||||
w1 = windowNew(300, 25, 300, 200, "Window 1");
|
||||
guiAttach(W(desktop), W(w1));
|
||||
w2 = windowNew(150, 150, 300, 200, "Window 2");
|
||||
guiAttach(W(desktop), W(w2));
|
||||
w3 = windowNew(300, 300, 300, 200, "Window 3");
|
||||
guiAttach(W(desktop), W(w3));
|
||||
w4 = windowNew(10, 10, 7 + 8 + (80 * 8), 26 + 8 + (24 * 14), "Terminal");
|
||||
guiAttach(W(desktop), W(w4));
|
||||
|
||||
// Window 1
|
||||
p1 = pictureNew(0, 0, "kanga.png");
|
||||
guiAttach(W(w1), W(p1));
|
||||
lb1 = listboxNew(155, 10, 120, 140, "List Box");
|
||||
listboxItemAdd(lb1, "One");
|
||||
listboxItemAdd(lb1, "Two");
|
||||
listboxItemAdd(lb1, "Three");
|
||||
listboxItemAdd(lb1, "Four");
|
||||
listboxItemAdd(lb1, "Five");
|
||||
listboxItemAdd(lb1, "Six");
|
||||
listboxItemAdd(lb1, "Seven");
|
||||
listboxItemAdd(lb1, "Eight");
|
||||
listboxItemAdd(lb1, "Nine");
|
||||
listboxItemAdd(lb1, "Ten");
|
||||
listboxStepSet(lb1, 3);
|
||||
guiAttach(W(w1), W(lb1));
|
||||
|
||||
// Window 2
|
||||
r1a = radioNew(10, 10, "Radio 1a", 1);
|
||||
guiAttach(W(w2), W(r1a));
|
||||
r2a = radioNew(20 + widgetWidthGet(W(r1a)), 10, "Radio 2a", 1);
|
||||
guiAttach(W(w2), W(r2a));
|
||||
r3a = radioNew(30 + widgetWidthGet(W(r1a)) + widgetWidthGet(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 + widgetWidthGet(W(r1b)), 35, "Radio 2b", 2);
|
||||
guiAttach(W(w2), W(r2b));
|
||||
r3b = radioNew(30 + widgetWidthGet(W(r1b)) + widgetWidthGet(W(r2b)), 35, "Radio 3b", 2);
|
||||
guiAttach(W(w2), W(r3b));
|
||||
radioSelectedSet(r1a);
|
||||
radioSelectedSet(r2b);
|
||||
tb1 = textboxNew(10, 60, 265, "Test Textbox");
|
||||
textboxValueSet(tb1, "Really long text string to edit!");
|
||||
guiAttach(W(w2), W(tb1));
|
||||
tb2 = textboxNew(10, 85, 265, "Test Textbox");
|
||||
textboxValueSet(tb2, "Short string.");
|
||||
guiAttach(W(w2), W(tb2));
|
||||
u1 = updownNew(10, 110, 0, 1024, 5, "UpDown");
|
||||
guiAttach(W(w2), W(u1));
|
||||
|
||||
// Window 3
|
||||
f1 = frameNew(10, 5, 175, 125, "Test Frame");
|
||||
guiAttach(W(w3), W(f1));
|
||||
b1 = buttonNew(0, 0, "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));
|
||||
|
||||
// Window 4 - Terminal
|
||||
t1 = terminalNew(0, 0, 80, 24);
|
||||
guiAttach(W(w4), W(t1));
|
||||
|
||||
taskCreate(testTerminal, "terminalTest");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void taskTestTagList(void *data) {
|
||||
WindowT *w1 = NULL;
|
||||
WindowT *w2 = NULL;
|
||||
WindowT *w3 = NULL;
|
||||
WindowT *w4 = NULL;
|
||||
ButtonT *b1 = NULL;
|
||||
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;
|
||||
TextboxT *tb1 = NULL;
|
||||
TextboxT *tb2 = NULL;
|
||||
UpdownT *u1 = NULL;
|
||||
ListboxT *lb1 = NULL;
|
||||
|
||||
(void)data;
|
||||
|
||||
TagItemT ui[] = {
|
||||
T_START,
|
||||
|
||||
T_WINDOW, O(w1),
|
||||
T_TITLE, P("Window 1"),
|
||||
T_X, 300, T_Y, 25, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_PICTURE, O(p1),
|
||||
T_X, 0, T_Y, 0,
|
||||
T_FILENAME, P("kanga.png"),
|
||||
T_PICTURE, T_DONE,
|
||||
T_LISTBOX, O(lb1),
|
||||
T_TITLE, P("Listbox"),
|
||||
T_X, 155, T_Y, 10, T_WIDTH, 120, T_HEIGHT, 140,
|
||||
T_ITEM, P("One"),
|
||||
T_ITEM, P("Two"),
|
||||
T_ITEM, P("Three"),
|
||||
T_ITEM, P("Four"),
|
||||
T_ITEM, P("Five"),
|
||||
T_ITEM, P("Six"),
|
||||
T_ITEM, P("Seven"),
|
||||
T_ITEM, P("Eight"),
|
||||
T_ITEM, P("Nine"),
|
||||
T_ITEM, P("Ten"),
|
||||
T_STEP, 3,
|
||||
T_LISTBOX, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w2),
|
||||
T_TITLE, P("Window 2"),
|
||||
T_X, 150, T_Y, 150, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_RADIOBUTTON, O(r1a),
|
||||
T_TITLE, P("Radio 1a"),
|
||||
T_X, 10, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_SELECTED, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r2a),
|
||||
T_TITLE, P("Radio 2a"),
|
||||
T_X, 20 + 80, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r3a),
|
||||
T_TITLE, P("Radio 3a"),
|
||||
T_X, 30 + 80 * 2, T_Y, 10,
|
||||
T_GROUP, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r1b),
|
||||
T_TITLE, P("Radio 1b"),
|
||||
T_X, 10, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r2b),
|
||||
T_TITLE, P("Radio 2b"),
|
||||
T_X, 20 + 80, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_SELECTED, 1,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_RADIOBUTTON, O(r3b),
|
||||
T_TITLE, P("Radio 3b"),
|
||||
T_X, 30 + 80 * 2, T_Y, 35,
|
||||
T_GROUP, 2,
|
||||
T_RADIOBUTTON, T_DONE,
|
||||
T_TEXTBOX, O(tb1),
|
||||
T_TITLE, P("Test Textbox"),
|
||||
T_X, 10, T_Y, 60, T_WIDTH, 265,
|
||||
T_VALUE, P("Really long text string to edit!"),
|
||||
T_TEXTBOX, T_DONE,
|
||||
T_TEXTBOX, O(tb2),
|
||||
T_TITLE, P("Test Textbox"),
|
||||
T_X, 10, T_Y, 85, T_WIDTH, 265,
|
||||
T_VALUE, P("Short String."),
|
||||
T_TEXTBOX, T_DONE,
|
||||
T_UPDOWN, O(u1),
|
||||
T_TITLE, P("UpDown"),
|
||||
T_X, 10, T_Y, 120,
|
||||
T_MINIMUM, 0, T_MAXIMUM, 1024, T_STEP, 5,
|
||||
T_UPDOWN, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w3),
|
||||
T_TITLE, P("Window 3"),
|
||||
T_X, 300, T_Y, 300, T_WIDTH, 300, T_HEIGHT, 200,
|
||||
T_FRAME, O(f1),
|
||||
T_TITLE, P("Test Frame"),
|
||||
T_X, 10, T_Y, 5, T_WIDTH, 175, T_HEIGHT, 125,
|
||||
T_BUTTON, O(b1),
|
||||
T_TITLE, P("Test Button"),
|
||||
T_X, 0, T_Y, 0,
|
||||
T_CLICK, P(buttonClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_LABEL, O(l1),
|
||||
T_TITLE, P("Test Label"),
|
||||
T_X, 10, T_Y, 40,
|
||||
T_LABEL, T_DONE,
|
||||
T_CHECKBOX, O(c1),
|
||||
T_TITLE, P("Test Checkbox"),
|
||||
T_X, 10, T_Y, 65,
|
||||
T_CHECKBOX, T_DONE,
|
||||
T_FRAME, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_WINDOW, O(w4),
|
||||
T_TITLE, P("Terminal"),
|
||||
T_X, 10, T_Y, 10, T_WIDTH, 7 + 8 + (80 * 8), T_HEIGHT, 26 + 8 + (24 * 14),
|
||||
T_TERMINAL, O(t1),
|
||||
T_X, 0, T_Y, 0, T_WIDTH, 80, T_HEIGHT, 24,
|
||||
T_TERMINAL, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
|
||||
T_END
|
||||
};
|
||||
|
||||
tagListRun(ui);
|
||||
|
||||
taskCreate(testTerminal, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void testTerminal(void *data) {
|
||||
FILE *in = NULL;
|
||||
char *buffer = NULL;
|
||||
uint16_t length = 0;
|
||||
|
||||
(void)data;
|
||||
|
||||
// Load ANSI file for terminal test.
|
||||
in = fopen("kanga.ans", "rt");
|
||||
fseek(in, 0, SEEK_END);
|
||||
length = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
buffer = (char *)malloc(length + 1);
|
||||
fread(buffer, 1, length, in);
|
||||
fclose(in);
|
||||
buffer[length] = 0;
|
||||
|
||||
terminalStringPrint(t1, buffer);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle) {
|
||||
size_t len = arrlenu(widget->children);
|
||||
size_t i;
|
||||
RectT r;
|
||||
|
||||
if (debugToggle) {
|
||||
// Clipping region (blue)
|
||||
guiWidgetBoundsDrawableOnScreenGet(widget, &r);
|
||||
surfaceRectangleDraw(r.x, r.y, r.x + r.w, r.y + r.h, vbeColorMake(0, 0, 255));
|
||||
} else {
|
||||
// Widget border (red)
|
||||
guiWidgetPositionOnScreenGet(widget, &r);
|
||||
surfaceRectangleDraw(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeColorMake(255, 0, 0));
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
for (i=0; i<len; i++) {
|
||||
widgetDebugDraw(widget->children[i], debugToggle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
client/src/test.h
Normal file
36
client/src/test.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 TEST_H
|
||||
#define TEST_H
|
||||
|
||||
|
||||
#include "os.h"
|
||||
#include "terminal.h"
|
||||
|
||||
|
||||
extern uint8_t lastKey;
|
||||
|
||||
|
||||
void taskTestTagList(void *data);
|
||||
void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle);
|
||||
|
||||
|
||||
#endif // TEST_H
|
6
client/src/thirdparty/memwatch/memwatch.c
vendored
6
client/src/thirdparty/memwatch/memwatch.c
vendored
|
@ -307,7 +307,7 @@ typedef pthread_mutex_t mwMutex;
|
|||
***********************************************************************/
|
||||
|
||||
static int mwInited = 0;
|
||||
static int mwInfoWritten = 0;
|
||||
static int mwInfoWritten = 1;
|
||||
static int mwUseAtexit = 0;
|
||||
static FILE* mwLog = NULL;
|
||||
static int mwFlushing = 0;
|
||||
|
@ -370,7 +370,7 @@ static mwMutex mwGlobalMutex;
|
|||
|
||||
static void mwAutoInit( void );
|
||||
static FILE* mwLogR( void );
|
||||
static void mwLogW( FILE* );
|
||||
/* static */ void mwLogW( FILE* );
|
||||
static int mwFlushR( void );
|
||||
static void mwFlushW( int );
|
||||
static void mwFlush( void );
|
||||
|
@ -1531,7 +1531,7 @@ static FILE *mwLogR() {
|
|||
return mwSTDERR;
|
||||
}
|
||||
|
||||
static void mwLogW( FILE *p ) {
|
||||
/* static */ void mwLogW( FILE *p ) {
|
||||
mwLog = mwLogB1 = mwLogB2 = p;
|
||||
}
|
||||
|
||||
|
|
97
client/src/welcome.c
Normal file
97
client/src/welcome.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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 "welcome.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "taglist.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "picture.h"
|
||||
#include "button.h"
|
||||
|
||||
|
||||
static WindowT *winWelcome = NULL;
|
||||
static PictureT *picLogo = NULL;
|
||||
static ButtonT *btnQuit = NULL;
|
||||
static ButtonT *btnSettings = NULL;
|
||||
static ButtonT *btnConnect = NULL;
|
||||
|
||||
|
||||
static void btnConnectClick(WidgetT *widget);
|
||||
static void btnQuitClick(WidgetT *widget);
|
||||
static void btnSettingsClick(WidgetT *widget);
|
||||
|
||||
|
||||
static void btnConnectClick(WidgetT *widget) {
|
||||
(void)widget;
|
||||
}
|
||||
|
||||
|
||||
static void btnQuitClick(WidgetT *widget) {
|
||||
(void)widget;
|
||||
guiStop();
|
||||
}
|
||||
|
||||
|
||||
static void btnSettingsClick(WidgetT *widget) {
|
||||
(void)widget;
|
||||
taskCreate(taskSettings, NULL);
|
||||
guiDelete(D(winWelcome));
|
||||
}
|
||||
|
||||
|
||||
void taskWelcome(void *data) {
|
||||
|
||||
(void)data;
|
||||
|
||||
// 450x128 logo
|
||||
|
||||
TagItemT ui[] = {
|
||||
T_START,
|
||||
T_WINDOW, O(winWelcome),
|
||||
T_TITLE, P("Welcome to KangaWorld!"),
|
||||
T_WIDTH, 500, T_HEIGHT, 225,
|
||||
T_PICTURE, O(picLogo),
|
||||
T_FILENAME, P("logo.png"),
|
||||
T_X, 18, T_Y, 18,
|
||||
T_PICTURE, T_DONE,
|
||||
T_BUTTON, O(btnQuit),
|
||||
T_TITLE, P("Quit"),
|
||||
T_X, 30, T_Y, 157,
|
||||
T_CLICK, P(btnQuitClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_BUTTON, O(btnSettings),
|
||||
T_TITLE, P("Settings"),
|
||||
T_X, 201, T_Y, 157,
|
||||
T_CLICK, P(btnSettingsClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_BUTTON, O(btnConnect),
|
||||
T_TITLE, P("Connect"),
|
||||
T_X, 379, T_Y, 157,
|
||||
T_CLICK, P(btnConnectClick),
|
||||
T_BUTTON, T_DONE,
|
||||
T_WINDOW, T_DONE,
|
||||
T_END
|
||||
};
|
||||
|
||||
tagListRun(ui);
|
||||
}
|
31
client/src/welcome.h
Normal file
31
client/src/welcome.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 WELCOME_H
|
||||
#define WELCOME_H
|
||||
|
||||
|
||||
#include "os.h"
|
||||
|
||||
|
||||
void taskWelcome(void *data);
|
||||
|
||||
|
||||
#endif // WELCOME_H
|
Loading…
Add table
Reference in a new issue