Framework bits needed for widgets and basic label added.

This commit is contained in:
Scott Duensing 2022-06-25 19:12:02 -05:00
parent 451c95a0ca
commit 018ccedd46
8 changed files with 495 additions and 293 deletions

View file

@ -28,6 +28,7 @@ HEADERS += \
src/gui/gui.h \ src/gui/gui.h \
src/gui/image.h \ src/gui/image.h \
src/gui/surface.h \ src/gui/surface.h \
src/gui/widgets/label.h \
src/gui/wmwindow.h \ src/gui/wmwindow.h \
src/os.h \ src/os.h \
src/platform/platform.h \ src/platform/platform.h \
@ -43,6 +44,7 @@ SOURCES += \
src/gui/gui.c \ src/gui/gui.c \
src/gui/image.c \ src/gui/image.c \
src/gui/surface.c \ src/gui/surface.c \
src/gui/widgets/label.c \
src/gui/wmwindow.c \ src/gui/wmwindow.c \
src/main.c \ src/main.c \
src/platform/djgpp.c \ src/platform/djgpp.c \

View file

@ -1,9 +1,11 @@
#include "gui.h" #include "gui.h"
#include "font.h" #include "font.h"
#include "wmwindow.h"
#include "image.h" #include "image.h"
#include "array.h" #include "array.h"
#include "wmwindow.h"
#include "widgets/label.h"
typedef struct WidgetCatalogS { typedef struct WidgetCatalogS {
uint8_t key; // Magic uint8_t key; // Magic
@ -21,13 +23,24 @@ FontT *__guiFontVGA8x16 = NULL;
static uint8_t _magicCount = 0; static uint8_t _magicCount = 0;
static WidgetCatalogT *_widgetCatalog = NULL; static WidgetCatalogT *_widgetCatalog = NULL;
static uint8_t _guiRunning = 1; static uint8_t _guiRunning = 1;
static WidgetT **_deleteList = NULL;
static SurfaceT *_mousePointer[MOUSE_COUNT] = { 0 }; static SurfaceT *_mousePointer[MOUSE_COUNT] = { 0 };
static ColorT _mouseTransparency = 0; static ColorT _mouseTransparency = 0;
static uint8_t _mouseCurrent = MOUSE_POINTER; static uint8_t _mouseCurrent = MOUSE_POINTER;
static PointT _mouseHotspot[MOUSE_COUNT] = { static PointT _mouseHotspot[MOUSE_COUNT] = { { 0, 0 }, { 8, 8 } };
{ 0, 0 },
{ 8, 8 }
}; static void guiDeleteListProcess(void);
static void guiDeleteListProcess(void) {
// Process any pending deletions.
while (arrlen(_deleteList) > 0) {
_deleteList[0]->reg->destroy(_deleteList[0]);
arrdel(_deleteList, 0);
}
arrfree(_deleteList);
}
void guiEventsDo(void) { void guiEventsDo(void) {
@ -50,6 +63,9 @@ void guiEventsDo(void) {
// Copy to screen. // Copy to screen.
videoBlit(0, 0, __guiBackBuffer); videoBlit(0, 0, __guiBackBuffer);
// Process any pending deletions.
guiDeleteListProcess();
// Emergency Exit? // Emergency Exit?
if (event.flags & EVENT_FLAG_KEYPRESS && event.key == KEY_ESC) guiStop(); if (event.flags & EVENT_FLAG_KEYPRESS && event.key == KEY_ESC) guiStop();
} }
@ -85,6 +101,9 @@ void guiShutdown(void) {
uint8_t i; uint8_t i;
wmShutdown();
guiDeleteListProcess();
DEL(__guiBaseColors); DEL(__guiBaseColors);
while (hmlen(_widgetCatalog) > 0) { while (hmlen(_widgetCatalog) > 0) {
@ -93,8 +112,6 @@ void guiShutdown(void) {
} }
hmfree(_widgetCatalog); hmfree(_widgetCatalog);
wmShutdown();
fontUnload(&__guiFontVGA8x16); fontUnload(&__guiFontVGA8x16);
fontUnload(&__guiFontVGA8x14); fontUnload(&__guiFontVGA8x14);
fontUnload(&__guiFontVGA8x8); fontUnload(&__guiFontVGA8x8);
@ -151,6 +168,7 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
// Register all known widgets with the GUI. // Register all known widgets with the GUI.
guiRegister(windowRegister); guiRegister(windowRegister);
guiRegister(labelRegister);
return SUCCESS; return SUCCESS;
} }
@ -175,6 +193,12 @@ void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, ui
} }
void guiWidgetDestroy(WidgetT *widget) {
// Add to list of widgets to delete.
arrput(_deleteList, widget);
}
uint8_t guiWidgetDirtyGet(WidgetT *widget) { uint8_t guiWidgetDirtyGet(WidgetT *widget) {
return widget->dirty; return widget->dirty;
} }

View file

@ -32,8 +32,9 @@ typedef struct RectS {
typedef struct RegisterS { typedef struct RegisterS {
char *widgetName; // Text name of widget. char *widgetName; // Text name of widget.
WidgetEventT paint; // Paint routine. WidgetEventT click; // Click handler.
WidgetEventT destroy; // Destroy routine. WidgetEventT destroy; // Destroy routine.
WidgetEventT paint; // Paint routine.
GuiCallbackT unregister; // Unregister routine. GuiCallbackT unregister; // Unregister routine.
} RegisterT; } RegisterT;
@ -41,6 +42,7 @@ typedef struct WidgetS {
uint8_t magic; // Magic ID of widget. uint8_t magic; // Magic ID of widget.
RectT r; // Outer bounds, except for windows. RectT r; // Outer bounds, except for windows.
RegisterT *reg; // Registration information. RegisterT *reg; // Registration information.
void *data; // Pointer to arbitrary data for user.
uint8_t dirty; // Is the widget dirty? uint8_t dirty; // Is the widget dirty?
} WidgetT; } WidgetT;
@ -91,6 +93,7 @@ void guiShutdown(void);
uint8_t guiStartup(int16_t width, int16_t height, int16_t depth); uint8_t guiStartup(int16_t width, int16_t height, int16_t depth);
void guiStop(void); void guiStop(void);
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h); void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void guiWidgetDestroy(WidgetT *widget);
uint8_t guiWidgetDirtyGet(WidgetT *widget); uint8_t guiWidgetDirtyGet(WidgetT *widget);
void guiWidgetDirtySet(WidgetT *widget, uint8_t dirty); void guiWidgetDirtySet(WidgetT *widget, uint8_t dirty);

View file

@ -0,0 +1,77 @@
#include "label.h"
uint8_t __MAGIC_LABEL = 0;
static void labelDestroy(struct WidgetS *widget, ...);
static void labelPaint(struct WidgetS *widget, ...);
void labelClickSet(LabelT *label, WidgetEventT handler, void *data) {
label->base.reg->click = handler;
label->base.data = data;
}
void labelColorSet(LabelT *label, ColorT foreground, ColorT background) {
label->foreground = foreground;
label->background = background;
label->base.dirty = 1;
}
LabelT *labelCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, FontT *font, char *contents, ...) {
LabelT *l = NULL;
// ***TODO*** Auto-calculate width/height.
NEW(LabelT, l);
memset(l, 0, sizeof(LabelT));
guiWidgetBaseSet((WidgetT *)l, __MAGIC_LABEL, x, y, w, h);
l->font = font;
l->text = strdup(contents);
l->foreground = GUI_BLACK;
l->background = GUI_LIGHTGRAY;
l->modsEnabled = 0;
return l;
}
static void labelDestroy(struct WidgetS *widget, ...) {
LabelT *l = (LabelT *)widget;
if (l->text) DEL(l->text);
DEL(l);
}
static void labelPaint(struct WidgetS *widget, ...) {
LabelT *l = (LabelT *)widget;
if (l->base.dirty) {
l->base.dirty = 0;
fontSet(l->font);
fontColorSet(l->foreground, l->background);
fontModsEnabledSet(l->modsEnabled);
// ***TODO*** Alignment, clipping, etc.
fontRender(l->text, l->base.r.x, l->base.r.y);
}
}
RegisterT *labelRegister(uint8_t magic) {
static RegisterT reg = {
"Label",
NULL, // No default on-click handler.
labelDestroy,
labelPaint,
NULL // No unregister handler.
};
// One-time widget startup code.
__MAGIC_LABEL = magic;
return ®
}

View file

@ -0,0 +1,27 @@
#ifndef LABEL_H
#define LABEL_H
#include "../gui.h"
typedef struct LabelS {
WidgetT base; // Required by all widgets.
char *text; // Contents of label.
FontT *font; // Font to use.
uint8_t modsEnabled; // Escape codes enabled?
ColorT foreground; // Foreground color.
ColorT background; // Background color.
} LabelT;
extern uint8_t __MAGIC_LABEL; // Magic ID assigned to us from the GUI.
void labelClickSet(LabelT *label, WidgetEventT handler, void *data);
void labelColorSet(LabelT *label, ColorT foreground, ColorT background);
LabelT *labelCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, FontT *font, char *contents, ...);
RegisterT *labelRegister(uint8_t magic);
#endif // LABEL_H

View file

@ -17,12 +17,14 @@ static WindowT *_windowTop = NULL;
static int16_t _iconCount = 0; static int16_t _iconCount = 0;
static void windowCache(WindowT *w); static void windowCache(WindowT *w, uint8_t redrawWindow);
static void windowDestroy(struct WidgetS *widget, ...);
static void windowPaint(struct WidgetS *widget, ...);
static void windowScrollHorizontalHandler(EventT *e, WindowT *w); static void windowScrollHorizontalHandler(EventT *e, WindowT *w);
static void windowScrollVerticalHandler(EventT *e, WindowT *w); static void windowScrollVerticalHandler(EventT *e, WindowT *w);
static void windowCache(WindowT *w) { static void windowCache(WindowT *w, uint8_t redrawWindow) {
char c; char c;
int16_t i; int16_t i;
int16_t x1; int16_t x1;
@ -35,6 +37,7 @@ static void windowCache(WindowT *w) {
int16_t originalX; int16_t originalX;
int16_t originalY; int16_t originalY;
double d; double d;
RectT originalBounds;
ColorT titleBackgroundColor; ColorT titleBackgroundColor;
ColorT widgetColor; ColorT widgetColor;
SurfaceT *target = surfaceGet(); SurfaceT *target = surfaceGet();
@ -61,6 +64,7 @@ static void windowCache(WindowT *w) {
// Draw into cache. // Draw into cache.
surfaceSet(w->cached); surfaceSet(w->cached);
if (redrawWindow) {
// Determine some colors. // Determine some colors.
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY; titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY; widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
@ -291,11 +295,27 @@ static void windowCache(WindowT *w) {
w->resize2.x = w->resize2.y = w->resize2.x2 = w->resize2.y2 = 0; w->resize2.x = w->resize2.y = w->resize2.x2 = w->resize2.y2 = 0;
} }
} else { // Redraw window.
// Since we didn't calculate them above, adjust bounds for content blit.
originalBounds = w->bounds;
w->bounds.x -= originalX;
w->bounds.y -= originalY;
w->bounds.x2 -= originalX;
w->bounds.y2 -= originalY;
}
// Blit contents. // Blit contents.
if (w->content) surfaceBlit(w->bounds.x, w->bounds.y, w->offset.x, w->offset.y, w->bounds.x2 - w->bounds.x, w->bounds.y2 - w->bounds.y, w->content); if (w->content) surfaceBlit(w->bounds.x, w->bounds.y, w->offset.x, w->offset.y, w->bounds.x2 - w->bounds.x, w->bounds.y2 - w->bounds.y, w->content);
// Fixup all the widget coordinates. // Fixup all the widget coordinates.
if (redrawWindow) {
windowMove(w, originalX, originalY); windowMove(w, originalX, originalY);
} else {
w->bounds = originalBounds;
w->base.r.x = originalX;
w->base.r.y = originalY;
}
surfaceSet(target); surfaceSet(target);
} }
@ -311,16 +331,16 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
SurfaceT *t = surfaceGet(); SurfaceT *t = surfaceGet();
NEW(WindowT, win); NEW(WindowT, win);
memset(win, 0, sizeof(WindowT)); memset(win, 0, sizeof(WindowT));
guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, x, y, w, h); guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, x, y, w, h);
win->title = strdup(title); win->title = strdup(title);
win->flags = (uint8_t)flags; win->flags = (uint8_t)flags;
//***DEBUG*** Hackery to get contents before we have widgets. /*
// ***DEBUG*** Hackery to get contents before we have widgets.
static uint8_t image = 1; static uint8_t image = 1;
static char name[16]; static char name[16];
windowCache(win); windowCache(win, 1);
width = win->bounds.x2 - win->bounds.x; width = win->bounds.x2 - win->bounds.x;
height = win->bounds.y2 - win->bounds.y; height = win->bounds.y2 - win->bounds.y;
guiWidgetDirtySet(W(win), 1); guiWidgetDirtySet(W(win), 1);
@ -331,7 +351,8 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
win->offset.y = 100;//(surfaceHeightGet(win->content) - height) * 0.5; win->offset.y = 100;//(surfaceHeightGet(win->content) - height) * 0.5;
} }
image++; image++;
/* */
// If the window is resizable, we need to get two more arguments for the content size. // If the window is resizable, we need to get two more arguments for the content size.
if (win->flags & WIN_RESIZE) { if (win->flags & WIN_RESIZE) {
va_start(args, flags); va_start(args, flags);
@ -340,7 +361,7 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
va_end(args); va_end(args);
} else { } else {
// Use whatever the default content area is. This causes an extra draw on create. Oh well. // Use whatever the default content area is. This causes an extra draw on create. Oh well.
windowCache(win); windowCache(win, 1);
width = win->bounds.x2 - win->bounds.x; width = win->bounds.x2 - win->bounds.x;
height = win->bounds.y2 - win->bounds.y; height = win->bounds.y2 - win->bounds.y;
guiWidgetDirtySet(W(win), 1); guiWidgetDirtySet(W(win), 1);
@ -350,7 +371,6 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
surfaceSet(win->content); surfaceSet(win->content);
surfaceClear(GUI_LIGHTGRAY); surfaceClear(GUI_LIGHTGRAY);
surfaceSet(t); surfaceSet(t);
*/
// Add to window list. // Add to window list.
arrput(_windowList, win); arrput(_windowList, win);
@ -362,33 +382,37 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
} }
void windowDestroy(struct WidgetS *widget, ...) { static void windowDestroy(struct WidgetS *widget, ...) {
uint16_t i; uint16_t i;
uint16_t c;
WindowT *window = (WindowT *)widget; WindowT *window = (WindowT *)widget;
// Find the window to delete. // Remove it from the window list, if it exists there.
for (i=0; i<arrlen(_windowList); i++) { for (i=0; i<arrlen(_windowList); i++) {
if (window == _windowList[i]) { if (window == _windowList[i]) {
arrdel(_windowList, i);
break;
}
}
// Was it the focused window? // Was it the focused window?
if (_windowList[i] == _windowTop) { if (window == _windowTop) {
// Find new topmost window on next call to focus. // Find new topmost window on next call to focus.
_windowTop = NULL; _windowTop = NULL;
} }
// Free the title. // Free the title.
if (_windowList[i]->title) DEL(_windowList[i]->title); if (window->title) DEL(window->title);
// Free children.
for (c=0; c<arrlen(window->children); c++) guiWidgetDestroy(window->children[c]);
arrfree(window->children);
// Free cached surface. // Free cached surface.
if (_windowList[i]->cached) surfaceDestroy(&_windowList[i]->cached); if (window->cached) surfaceDestroy(&window->cached);
// Free content surface. // Free content surface.
if (_windowList[i]->content) surfaceDestroy(&_windowList[i]->content); if (window->content) surfaceDestroy(&window->content);
// Delete the window. // Delete the window.
DEL(_windowList[i]); DEL(window);
// Remove it from window list.
arrdel(_windowList, i);
// Fixup focus. // Fixup focus.
windowFocusSet(NULL); windowFocusSet(NULL);
break;
}
}
} }
@ -509,7 +533,7 @@ void windowMaximizeRestore(WindowT *win) {
} // Maximized? } // Maximized?
// Update. // Update.
windowCache(win); windowCache(win, 1);
} }
@ -600,7 +624,7 @@ void windowMove(WindowT *w, uint16_t x, uint16_t y) {
} }
void windowPaint(struct WidgetS *widget, ...) { static void windowPaint(struct WidgetS *widget, ...) {
int16_t x; int16_t x;
int16_t y; int16_t y;
int16_t px; int16_t px;
@ -610,13 +634,32 @@ void windowPaint(struct WidgetS *widget, ...) {
int16_t xc; int16_t xc;
int16_t yc; int16_t yc;
WindowT *w = (WindowT *)widget; WindowT *w = (WindowT *)widget;
SurfaceT *t = surfaceGet();
// Do we need redrawn? // Are any child widgets dirty?
y = 0;
for (x=0; x<arrlen(w->children); x++) {
if (w->children[x]->dirty) {
y = 1;
if (w->children[x]->reg->paint) {
surfaceSet(w->content);
w->children[x]->reg->paint(w->children[x]);
}
}
}
surfaceSet(t);
// Does the window itself need redrawn?
if (guiWidgetDirtyGet(widget)) { if (guiWidgetDirtyGet(widget)) {
guiWidgetDirtySet(widget, 0); guiWidgetDirtySet(widget, 0);
windowCache(w); x = 1;
} else {
x = 0;
} }
// Did a widget or the window need redrawn?
if (x || y) windowCache(w, x);
// Are we minimized? // Are we minimized?
if (w->flags & WIN_IS_ICON) { if (w->flags & WIN_IS_ICON) {
// Draw iconized version of contents. There are too many counters here but it's the only way it worked reliably. // Draw iconized version of contents. There are too many counters here but it's the only way it worked reliably.
@ -645,9 +688,10 @@ void windowPaint(struct WidgetS *widget, ...) {
RegisterT *windowRegister(uint8_t magic) { RegisterT *windowRegister(uint8_t magic) {
static RegisterT reg = { static RegisterT reg = {
"Window", "Window",
windowPaint, NULL, // Click event is special for windows.
windowDestroy, windowDestroy, // Destroy.
NULL windowPaint, // Paint.
NULL // Unregister.
}; };
// One-time widget startup code. // One-time widget startup code.
@ -693,7 +737,7 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) {
// Do resize. // Do resize.
win->base.r.w = width; win->base.r.w = width;
win->base.r.h =height; win->base.r.h =height;
windowCache(win); windowCache(win, 1);
} }
} }
@ -707,7 +751,7 @@ static void windowScrollHorizontalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.x < 0) w->offset.x = 0; if (w->offset.x < 0) w->offset.x = 0;
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -718,7 +762,7 @@ static void windowScrollHorizontalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x); if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x);
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -729,7 +773,7 @@ static void windowScrollHorizontalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.x < 0) w->offset.x = 0; if (w->offset.x < 0) w->offset.x = 0;
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -740,7 +784,7 @@ static void windowScrollHorizontalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x); if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x);
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
} }
@ -755,7 +799,7 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.y < 0) w->offset.y = 0; if (w->offset.y < 0) w->offset.y = 0;
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -766,7 +810,7 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y); if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y);
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -777,7 +821,7 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.y < 0) w->offset.y = 0; if (w->offset.y < 0) w->offset.y = 0;
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
@ -788,16 +832,33 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
// Clip. // Clip.
if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y); if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y);
// Update. // Update.
windowCache(w); windowCache(w, 1);
return; return;
} }
} }
void wmShutdown(void) { void windowWidgetAdd(WindowT *window, WidgetT *widget) {
while (arrlen(_windowList) > 0) { arrput(window->children, widget);
windowDestroy((WidgetT *)_windowList[0]); }
void windowWidgetRemove(WindowT *window, WidgetT *widget) {
uint16_t i;
for (i=0; i<arrlen(window->children); i++) {
if (window->children[i] == widget) {
arrdel(window->children, i);
break;
} }
}
}
void wmShutdown(void) {
uint16_t i;
for (i=0; i<arrlen(_windowList); i++) guiWidgetDestroy((WidgetT *)_windowList[i]);
arrfree(_windowList); arrfree(_windowList);
} }

View file

@ -38,6 +38,7 @@ typedef struct WindowS {
PointT offset; // Content scroll offset in window. PointT offset; // Content scroll offset in window.
SurfaceT *content; // Actual window contents - widgets and such. SurfaceT *content; // Actual window contents - widgets and such.
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing. SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
WidgetT **children; // Widgets contained in the window.
} WindowT; } WindowT;
@ -45,14 +46,14 @@ extern uint8_t __MAGIC_WINDOW; // Magic ID assigned to us from the GUI.
WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title, int flags, ...); WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title, int flags, ...);
void windowDestroy(struct WidgetS *widget, ...);
void windowFocusSet(WindowT *win); void windowFocusSet(WindowT *win);
void windowMaximizeRestore(WindowT *win); void windowMaximizeRestore(WindowT *win);
void windowMinimize(WindowT *win); void windowMinimize(WindowT *win);
void windowMove(WindowT *win, uint16_t x, uint16_t y); void windowMove(WindowT *win, uint16_t x, uint16_t y);
void windowPaint(struct WidgetS *widget, ...);
RegisterT *windowRegister(uint8_t magic); RegisterT *windowRegister(uint8_t magic);
void windowResize(WindowT *win, uint16_t width, uint16_t height); void windowResize(WindowT *win, uint16_t width, uint16_t height);
void windowWidgetAdd(WindowT *window, WidgetT *widget);
void windowWidgetRemove(WindowT *window, WidgetT *widget);
void wmShutdown(void); void wmShutdown(void);

View file

@ -1,10 +1,13 @@
#include "gui/gui.h" #include "gui/gui.h"
#include "gui/wmwindow.h" #include "gui/wmwindow.h"
#include "gui/widgets/label.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char title[256]; char title[256];
uint16_t i; uint16_t i;
LabelT *l = NULL;
WindowT *w = NULL;
(void)argc; (void)argc;
@ -14,7 +17,11 @@ int main(int argc, char *argv[]) {
if (guiStartup(800, 600, 16) == SUCCESS) { if (guiStartup(800, 600, 16) == SUCCESS) {
for (i=1; i<4; i++) { for (i=1; i<4; i++) {
sprintf(title, "Testing %d", i); sprintf(title, "Testing %d", i);
windowCreate(i * 50, i * 50, 300, 200, title, WIN_STANDARD); w = windowCreate(i * 50, i * 50, 300, 200, title, WIN_STANDARD, 640, 480);
l = labelCreate(10, 10, 0, 0, __guiFontVGA8x16, "Label Test");
labelColorSet(l, __guiBaseColors[i], GUI_BLACK);
windowWidgetAdd(w, W(l));
} }
guiRun(); guiRun();
guiShutdown(); guiShutdown();