Framework bits needed for widgets and basic label added.
This commit is contained in:
parent
451c95a0ca
commit
018ccedd46
8 changed files with 495 additions and 293 deletions
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
@ -18,16 +20,27 @@ FontT *__guiFontVGA8x14 = NULL;
|
||||||
FontT *__guiFontVGA8x16 = NULL;
|
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 SurfaceT *_mousePointer[MOUSE_COUNT] = { 0 };
|
static WidgetT **_deleteList = NULL;
|
||||||
static ColorT _mouseTransparency = 0;
|
static SurfaceT *_mousePointer[MOUSE_COUNT] = { 0 };
|
||||||
static uint8_t _mouseCurrent = MOUSE_POINTER;
|
static ColorT _mouseTransparency = 0;
|
||||||
static PointT _mouseHotspot[MOUSE_COUNT] = {
|
static uint8_t _mouseCurrent = MOUSE_POINTER;
|
||||||
{ 0, 0 },
|
static PointT _mouseHotspot[MOUSE_COUNT] = { { 0, 0 }, { 8, 8 } };
|
||||||
{ 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
77
client/src/gui/widgets/label.c
Normal file
77
client/src/gui/widgets/label.c
Normal 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 ®
|
||||||
|
}
|
27
client/src/gui/widgets/label.h
Normal file
27
client/src/gui/widgets/label.h
Normal 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
|
|
@ -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,241 +64,258 @@ static void windowCache(WindowT *w) {
|
||||||
// Draw into cache.
|
// Draw into cache.
|
||||||
surfaceSet(w->cached);
|
surfaceSet(w->cached);
|
||||||
|
|
||||||
// Determine some colors.
|
if (redrawWindow) {
|
||||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
// Determine some colors.
|
||||||
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||||
|
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||||
|
|
||||||
// Get ready!
|
// Get ready!
|
||||||
x1 = w->base.r.x;
|
x1 = w->base.r.x;
|
||||||
y1 = w->base.r.y;
|
y1 = w->base.r.y;
|
||||||
x2 = w->base.r.x + w->base.r.w - 1;
|
x2 = w->base.r.x + w->base.r.w - 1;
|
||||||
y2 = w->base.r.y + w->base.r.h - 1;
|
y2 = w->base.r.y + w->base.r.h - 1;
|
||||||
|
|
||||||
// Draw border.
|
// Draw border.
|
||||||
surfaceBoxHighlight(x1, y1, x2, y2, GUI_WHITE, GUI_BLACK);
|
surfaceBoxHighlight(x1, y1, x2, y2, GUI_WHITE, GUI_BLACK);
|
||||||
x1++; y1++; x2--; y2--;
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
surfaceBox(x1, y1, x2, y2, GUI_LIGHTGRAY);
|
|
||||||
x1++; y1++; x2--; y2--;
|
x1++; y1++; x2--; y2--;
|
||||||
}
|
for (i=0; i<3; i++) {
|
||||||
surfaceBoxHighlight(x1, y1, x2, y2, GUI_BLACK, GUI_WHITE);
|
surfaceBox(x1, y1, x2, y2, GUI_LIGHTGRAY);
|
||||||
x1++; y1++; x2--; y2--;
|
x1++; y1++; x2--; y2--;
|
||||||
|
|
||||||
// Do we need a titlebar?
|
|
||||||
if (w->title || w->flags & WIN_CLOSE || w->flags & WIN_MAXIMIZE || w->flags & WIN_MINIMIZE) {
|
|
||||||
tx1 = x1;
|
|
||||||
tx2 = x2;
|
|
||||||
ty2 = y1 + WIDGET_SIZE;
|
|
||||||
|
|
||||||
// Close box?
|
|
||||||
if (w->flags & WIN_CLOSE) {
|
|
||||||
tx1 += WIDGET_SIZE;
|
|
||||||
w->close.x = x1;
|
|
||||||
w->close.y = y1;
|
|
||||||
w->close.x2 = tx1 - 1;
|
|
||||||
w->close.y2 = ty2 - 1;
|
|
||||||
surfaceBoxFilled(w->close.x + 1, w->close.y + 1, w->close.x2 - 1, w->close.y2 - 1, titleBackgroundColor);
|
|
||||||
surfaceBoxHighlight(w->close.x + 3, w->close.y + 8, w->close.x2 - 3, w->close.y2 - 8, GUI_WHITE, widgetColor);
|
|
||||||
surfaceBoxHighlight(w->close.x, w->close.y, w->close.x2, w->close.y2, GUI_WHITE, GUI_BLACK);
|
|
||||||
} else {
|
|
||||||
w->close.x = w->close.y = w->close.x2 = w->close.y2 = 0;
|
|
||||||
}
|
}
|
||||||
|
surfaceBoxHighlight(x1, y1, x2, y2, GUI_BLACK, GUI_WHITE);
|
||||||
|
x1++; y1++; x2--; y2--;
|
||||||
|
|
||||||
// Maximize box?
|
// Do we need a titlebar?
|
||||||
if (w->flags & WIN_MAXIMIZE) {
|
if (w->title || w->flags & WIN_CLOSE || w->flags & WIN_MAXIMIZE || w->flags & WIN_MINIMIZE) {
|
||||||
tx2 -= WIDGET_SIZE;
|
tx1 = x1;
|
||||||
w->maximize.x = tx2 + 1;
|
tx2 = x2;
|
||||||
w->maximize.y = y1;
|
ty2 = y1 + WIDGET_SIZE;
|
||||||
w->maximize.x2 = tx2 + WIDGET_SIZE;
|
|
||||||
w->maximize.y2 = ty2 - 1;
|
|
||||||
surfaceBoxFilled(w->maximize.x + 1, w->maximize.y + 1, w->maximize.x2 - 1, w->maximize.y2 - 1, titleBackgroundColor);
|
|
||||||
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y + 4, GUI_WHITE);
|
|
||||||
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y2 - 3, GUI_WHITE);
|
|
||||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y + 4, widgetColor);
|
|
||||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y2 - 3, widgetColor);
|
|
||||||
surfaceBoxHighlight(w->maximize.x, w->maximize.y, w->maximize.x2, w->maximize.y2, GUI_WHITE, GUI_BLACK);
|
|
||||||
} else {
|
|
||||||
w->maximize.x = w->maximize.y = w->maximize.x2 = w->maximize.y2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minimize box?
|
// Close box?
|
||||||
if (w->flags & WIN_MINIMIZE) {
|
if (w->flags & WIN_CLOSE) {
|
||||||
tx2 -= WIDGET_SIZE;
|
tx1 += WIDGET_SIZE;
|
||||||
w->minimize.x = tx2 + 1;
|
w->close.x = x1;
|
||||||
w->minimize.y = y1;
|
w->close.y = y1;
|
||||||
w->minimize.x2 = tx2 + WIDGET_SIZE;
|
w->close.x2 = tx1 - 1;
|
||||||
w->minimize.y2 = ty2 - 1;
|
w->close.y2 = ty2 - 1;
|
||||||
surfaceBoxFilled(w->minimize.x + 1, w->minimize.y + 1, w->minimize.x2 - 1, w->minimize.y2 - 1, titleBackgroundColor);
|
surfaceBoxFilled(w->close.x + 1, w->close.y + 1, w->close.x2 - 1, w->close.y2 - 1, titleBackgroundColor);
|
||||||
surfaceBoxHighlight(w->minimize.x + 7, w->minimize.y + 7, w->minimize.x2 - 7, w->minimize.y2 - 7, GUI_WHITE, widgetColor);
|
surfaceBoxHighlight(w->close.x + 3, w->close.y + 8, w->close.x2 - 3, w->close.y2 - 8, GUI_WHITE, widgetColor);
|
||||||
surfaceBoxHighlight(w->minimize.x, w->minimize.y, w->minimize.x2, w->minimize.y2, GUI_WHITE, GUI_BLACK);
|
surfaceBoxHighlight(w->close.x, w->close.y, w->close.x2, w->close.y2, GUI_WHITE, GUI_BLACK);
|
||||||
} else {
|
|
||||||
w->minimize.x = w->minimize.y = w->minimize.x2 = w->maximize.y2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw titlebar background.
|
|
||||||
w->titlebar.x = tx1;
|
|
||||||
w->titlebar.y = y1;
|
|
||||||
w->titlebar.x2 = tx2;
|
|
||||||
w->titlebar.y2 = ty2 - 1;
|
|
||||||
surfaceBoxFilled(w->titlebar.x + 1, w->titlebar.y + 1, w->titlebar.x2 - 1, w->titlebar.y2 - 1, titleBackgroundColor);
|
|
||||||
if (w->title) {
|
|
||||||
// Prepare font. Don't allow color changes in titles.
|
|
||||||
fontSet(__guiFontVGA8x16);
|
|
||||||
fontColorSet(GUI_WHITE, titleBackgroundColor);
|
|
||||||
fontModsEnabledSet(0);
|
|
||||||
// How many characters do we have room for?
|
|
||||||
i = ((w->titlebar.x2 - w->titlebar.x) >> 3) - 2;
|
|
||||||
// Does the title fit?
|
|
||||||
if ((int16_t)strlen(w->title) <= i) {
|
|
||||||
// Render entire title.
|
|
||||||
fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2);
|
|
||||||
} else {
|
} else {
|
||||||
// Render partial title.
|
w->close.x = w->close.y = w->close.x2 = w->close.y2 = 0;
|
||||||
c = w->title[i];
|
|
||||||
w->title[i] = 0;
|
|
||||||
fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2);
|
|
||||||
w->title[i] = c;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
surfaceBoxHighlight(w->titlebar.x, w->titlebar.y, w->titlebar.x2, w->titlebar.y2, GUI_WHITE, GUI_BLACK);
|
|
||||||
|
|
||||||
y1 += WIDGET_SIZE;
|
// Maximize box?
|
||||||
} else {
|
if (w->flags & WIN_MAXIMIZE) {
|
||||||
w->close.x = w->close.y = w->close.x2 = w->close.y2 = 0;
|
tx2 -= WIDGET_SIZE;
|
||||||
w->maximize.x = w->maximize.y = w->maximize.x2 = w->maximize.y2 = 0;
|
w->maximize.x = tx2 + 1;
|
||||||
w->minimize.x = w->minimize.y = w->minimize.x2 = w->maximize.y2 = 0;
|
w->maximize.y = y1;
|
||||||
w->titlebar.x = w->titlebar.y = w->titlebar.x2 = w->titlebar.y2 = 0;
|
w->maximize.x2 = tx2 + WIDGET_SIZE;
|
||||||
}
|
w->maximize.y2 = ty2 - 1;
|
||||||
|
surfaceBoxFilled(w->maximize.x + 1, w->maximize.y + 1, w->maximize.x2 - 1, w->maximize.y2 - 1, titleBackgroundColor);
|
||||||
|
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y + 4, GUI_WHITE);
|
||||||
|
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y2 - 3, GUI_WHITE);
|
||||||
|
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y + 4, widgetColor);
|
||||||
|
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y2 - 3, widgetColor);
|
||||||
|
surfaceBoxHighlight(w->maximize.x, w->maximize.y, w->maximize.x2, w->maximize.y2, GUI_WHITE, GUI_BLACK);
|
||||||
|
} else {
|
||||||
|
w->maximize.x = w->maximize.y = w->maximize.x2 = w->maximize.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Vertical Scroll Bar?
|
// Minimize box?
|
||||||
if (w->flags & WIN_SCROLL_V) {
|
if (w->flags & WIN_MINIMIZE) {
|
||||||
w->scrollv.x2 = x2;
|
tx2 -= WIDGET_SIZE;
|
||||||
w->scrollv.x = w->scrollv.x2 - (WIDGET_SIZE - 1);
|
w->minimize.x = tx2 + 1;
|
||||||
w->scrollv.y = y1;
|
w->minimize.y = y1;
|
||||||
w->scrollv.y2 = y2;
|
w->minimize.x2 = tx2 + WIDGET_SIZE;
|
||||||
// Draw scroll bar.
|
w->minimize.y2 = ty2 - 1;
|
||||||
surfaceBoxFilled(w->scrollv.x + 1, w->scrollv.y + 1, w->scrollv.x2 - 1, w->scrollv.y2 - 1, titleBackgroundColor);
|
surfaceBoxFilled(w->minimize.x + 1, w->minimize.y + 1, w->minimize.x2 - 1, w->minimize.y2 - 1, titleBackgroundColor);
|
||||||
surfaceBoxHighlight(w->scrollv.x, w->scrollv.y, w->scrollv.x2, w->scrollv.y2, GUI_WHITE, GUI_BLACK);
|
surfaceBoxHighlight(w->minimize.x + 7, w->minimize.y + 7, w->minimize.x2 - 7, w->minimize.y2 - 7, GUI_WHITE, widgetColor);
|
||||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y + (WIDGET_SIZE - 1), GUI_BLACK);
|
surfaceBoxHighlight(w->minimize.x, w->minimize.y, w->minimize.x2, w->minimize.y2, GUI_WHITE, GUI_BLACK);
|
||||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y2 - (WIDGET_SIZE - 1), GUI_WHITE);
|
} else {
|
||||||
// Prepare font.
|
w->minimize.x = w->minimize.y = w->minimize.x2 = w->maximize.y2 = 0;
|
||||||
fontSet(__guiFontVGA8x8);
|
}
|
||||||
fontColorSet(widgetColor, titleBackgroundColor);
|
|
||||||
// Draw arrows.
|
|
||||||
fontRender("\x1e", w->scrollv.x + 7, w->scrollv.y + 7);
|
|
||||||
fontRender("\x1f", w->scrollv.x + 7, w->scrollv.y2 - 12);
|
|
||||||
|
|
||||||
x2 -= (WIDGET_SIZE - 1);
|
// Draw titlebar background.
|
||||||
} else {
|
w->titlebar.x = tx1;
|
||||||
w->scrollv.x = w->scrollv.y = w->scrollv.x2 = w->scrollv.y2 = 0;
|
w->titlebar.y = y1;
|
||||||
}
|
w->titlebar.x2 = tx2;
|
||||||
|
w->titlebar.y2 = ty2 - 1;
|
||||||
|
surfaceBoxFilled(w->titlebar.x + 1, w->titlebar.y + 1, w->titlebar.x2 - 1, w->titlebar.y2 - 1, titleBackgroundColor);
|
||||||
|
if (w->title) {
|
||||||
|
// Prepare font. Don't allow color changes in titles.
|
||||||
|
fontSet(__guiFontVGA8x16);
|
||||||
|
fontColorSet(GUI_WHITE, titleBackgroundColor);
|
||||||
|
fontModsEnabledSet(0);
|
||||||
|
// How many characters do we have room for?
|
||||||
|
i = ((w->titlebar.x2 - w->titlebar.x) >> 3) - 2;
|
||||||
|
// Does the title fit?
|
||||||
|
if ((int16_t)strlen(w->title) <= i) {
|
||||||
|
// Render entire title.
|
||||||
|
fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2);
|
||||||
|
} else {
|
||||||
|
// Render partial title.
|
||||||
|
c = w->title[i];
|
||||||
|
w->title[i] = 0;
|
||||||
|
fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2);
|
||||||
|
w->title[i] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
surfaceBoxHighlight(w->titlebar.x, w->titlebar.y, w->titlebar.x2, w->titlebar.y2, GUI_WHITE, GUI_BLACK);
|
||||||
|
|
||||||
// Horizontal Scroll Bar?
|
y1 += WIDGET_SIZE;
|
||||||
if (w->flags & WIN_SCROLL_H) {
|
|
||||||
w->scrollh.x = x1;
|
|
||||||
w->scrollh.x2 = x2;
|
|
||||||
w->scrollh.y2 = y2;
|
|
||||||
w->scrollh.y = w->scrollh.y2 - (WIDGET_SIZE - 1);
|
|
||||||
// Draw scroll bar.
|
|
||||||
surfaceBoxFilled(w->scrollh.x + 1, w->scrollh.y + 1, w->scrollh.x2 - 1, w->scrollh.y2 - 1, titleBackgroundColor);
|
|
||||||
surfaceBoxHighlight(w->scrollh.x, w->scrollh.y, w->scrollh.x2, w->scrollh.y2, GUI_WHITE, GUI_BLACK);
|
|
||||||
surfaceLineV(w->scrollh.x + (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_BLACK);
|
|
||||||
surfaceLineV(w->scrollh.x2 - (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_WHITE);
|
|
||||||
// If we have both horizontal and vertical scroll bars, we need to fix a shadow.
|
|
||||||
if (w->flags & WIN_SCROLL_V) {
|
|
||||||
surfaceLineV(w->scrollh.x2 - 1, w->scrollh.y, w->scrollh.y2, GUI_BLACK);
|
|
||||||
surfaceLineV(w->scrollh.x2, w->scrollh.y, w->scrollh.y2, GUI_WHITE);
|
|
||||||
}
|
|
||||||
// Prepare font.
|
|
||||||
fontSet(__guiFontVGA8x8);
|
|
||||||
fontColorSet(widgetColor, titleBackgroundColor);
|
|
||||||
// Draw arrows.
|
|
||||||
fontRender("\x11", w->scrollh.x + 7, w->scrollh.y + 7);
|
|
||||||
fontRender("\x10", w->scrollh.x2 - 12, w->scrollh.y + 7);
|
|
||||||
|
|
||||||
y2 -= (WIDGET_SIZE - 1);
|
|
||||||
} else {
|
|
||||||
w->scrollh.x = w->scrollh.y = w->scrollh.x2 = w->scrollh.y2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find content area.
|
|
||||||
w->bounds.x = x1;
|
|
||||||
w->bounds.y = y1;
|
|
||||||
w->bounds.x2 = x2;
|
|
||||||
w->bounds.y2 = y2;
|
|
||||||
|
|
||||||
// Do we have content yet?
|
|
||||||
if (w->content) {
|
|
||||||
|
|
||||||
// Vertical Scroll Bar Thumb?
|
|
||||||
if (w->flags & WIN_SCROLL_V) {
|
|
||||||
// Distance between arrow buttons on scroll bar.
|
|
||||||
i = w->scrollv.y2 - w->scrollv.y - (WIDGET_SIZE * 2 - 2) - 2;
|
|
||||||
// Percentage to scale content height to scroll bar height.
|
|
||||||
d = (double)i / (double)surfaceHeightGet(w->content);
|
|
||||||
// Find position and size of thumb.
|
|
||||||
w->thumbv.x = w->scrollv.x + 1;
|
|
||||||
w->thumbv.x2 = w->scrollv.x2 - 1;
|
|
||||||
w->thumbv.y = w->scrollv.y + WIDGET_SIZE + (w->offset.y * d);
|
|
||||||
w->thumbv.y2 = w->thumbv.y + ((w->bounds.y2 - w->bounds.y) * d);
|
|
||||||
// Clamp overflow due to doubles and my off-by-one brain.
|
|
||||||
if (w->thumbv.y2 >= w->thumbv.y + i - 1) w->thumbv.y2 = w->thumbv.y + i - 1;
|
|
||||||
// Draw thumb.
|
|
||||||
surfaceBoxFilled(w->thumbv.x + 1, w->thumbv.y + 1, w->thumbv.x2 - 1, w->thumbv.y2 - 1, widgetColor);
|
|
||||||
surfaceBoxHighlight(w->thumbv.x, w->thumbv.y, w->thumbv.x2, w->thumbv.y2, GUI_WHITE, GUI_BLACK);
|
|
||||||
} else {
|
} else {
|
||||||
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
w->close.x = w->close.y = w->close.x2 = w->close.y2 = 0;
|
||||||
|
w->maximize.x = w->maximize.y = w->maximize.x2 = w->maximize.y2 = 0;
|
||||||
|
w->minimize.x = w->minimize.y = w->minimize.x2 = w->maximize.y2 = 0;
|
||||||
|
w->titlebar.x = w->titlebar.y = w->titlebar.x2 = w->titlebar.y2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Horizontal Scroll Bar Thumb?
|
// Vertical Scroll Bar?
|
||||||
|
if (w->flags & WIN_SCROLL_V) {
|
||||||
|
w->scrollv.x2 = x2;
|
||||||
|
w->scrollv.x = w->scrollv.x2 - (WIDGET_SIZE - 1);
|
||||||
|
w->scrollv.y = y1;
|
||||||
|
w->scrollv.y2 = y2;
|
||||||
|
// Draw scroll bar.
|
||||||
|
surfaceBoxFilled(w->scrollv.x + 1, w->scrollv.y + 1, w->scrollv.x2 - 1, w->scrollv.y2 - 1, titleBackgroundColor);
|
||||||
|
surfaceBoxHighlight(w->scrollv.x, w->scrollv.y, w->scrollv.x2, w->scrollv.y2, GUI_WHITE, GUI_BLACK);
|
||||||
|
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y + (WIDGET_SIZE - 1), GUI_BLACK);
|
||||||
|
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y2 - (WIDGET_SIZE - 1), GUI_WHITE);
|
||||||
|
// Prepare font.
|
||||||
|
fontSet(__guiFontVGA8x8);
|
||||||
|
fontColorSet(widgetColor, titleBackgroundColor);
|
||||||
|
// Draw arrows.
|
||||||
|
fontRender("\x1e", w->scrollv.x + 7, w->scrollv.y + 7);
|
||||||
|
fontRender("\x1f", w->scrollv.x + 7, w->scrollv.y2 - 12);
|
||||||
|
|
||||||
|
x2 -= (WIDGET_SIZE - 1);
|
||||||
|
} else {
|
||||||
|
w->scrollv.x = w->scrollv.y = w->scrollv.x2 = w->scrollv.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal Scroll Bar?
|
||||||
if (w->flags & WIN_SCROLL_H) {
|
if (w->flags & WIN_SCROLL_H) {
|
||||||
// Distance between arrow buttons on scroll bar.
|
w->scrollh.x = x1;
|
||||||
i = w->scrollh.x2 - w->scrollh.x - (WIDGET_SIZE * 2 - 2) - 2;
|
w->scrollh.x2 = x2;
|
||||||
// Percentage to scale content width to scroll bar width.
|
w->scrollh.y2 = y2;
|
||||||
d = (double)i / (double)surfaceWidthGet(w->content);
|
w->scrollh.y = w->scrollh.y2 - (WIDGET_SIZE - 1);
|
||||||
// Find position and size of thumb.
|
// Draw scroll bar.
|
||||||
w->thumbh.x = w->scrollh.x + WIDGET_SIZE + (w->offset.x * d);
|
surfaceBoxFilled(w->scrollh.x + 1, w->scrollh.y + 1, w->scrollh.x2 - 1, w->scrollh.y2 - 1, titleBackgroundColor);
|
||||||
w->thumbh.x2 = w->thumbh.x + ((w->bounds.x2 - w->bounds.x) * d);
|
surfaceBoxHighlight(w->scrollh.x, w->scrollh.y, w->scrollh.x2, w->scrollh.y2, GUI_WHITE, GUI_BLACK);
|
||||||
w->thumbh.y = w->scrollh.y + 1;
|
surfaceLineV(w->scrollh.x + (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_BLACK);
|
||||||
w->thumbh.y2 = w->scrollh.y2 - 1;
|
surfaceLineV(w->scrollh.x2 - (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_WHITE);
|
||||||
// Clamp overflow due to doubles and my off-by-one brain.
|
// If we have both horizontal and vertical scroll bars, we need to fix a shadow.
|
||||||
if (w->thumbh.x2 >= w->thumbh.x + i - 1) w->thumbh.x2 = w->thumbh.x + i - 1;
|
if (w->flags & WIN_SCROLL_V) {
|
||||||
// Draw thumb.
|
surfaceLineV(w->scrollh.x2 - 1, w->scrollh.y, w->scrollh.y2, GUI_BLACK);
|
||||||
surfaceBoxFilled(w->thumbh.x + 1, w->thumbh.y + 1, w->thumbh.x2 - 1, w->thumbh.y2 - 1, widgetColor);
|
surfaceLineV(w->scrollh.x2, w->scrollh.y, w->scrollh.y2, GUI_WHITE);
|
||||||
surfaceBoxHighlight(w->thumbh.x, w->thumbh.y, w->thumbh.x2, w->thumbh.y2, GUI_WHITE, GUI_BLACK);
|
}
|
||||||
|
// Prepare font.
|
||||||
|
fontSet(__guiFontVGA8x8);
|
||||||
|
fontColorSet(widgetColor, titleBackgroundColor);
|
||||||
|
// Draw arrows.
|
||||||
|
fontRender("\x11", w->scrollh.x + 7, w->scrollh.y + 7);
|
||||||
|
fontRender("\x10", w->scrollh.x2 - 12, w->scrollh.y + 7);
|
||||||
|
|
||||||
|
y2 -= (WIDGET_SIZE - 1);
|
||||||
} else {
|
} else {
|
||||||
|
w->scrollh.x = w->scrollh.y = w->scrollh.x2 = w->scrollh.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find content area.
|
||||||
|
w->bounds.x = x1;
|
||||||
|
w->bounds.y = y1;
|
||||||
|
w->bounds.x2 = x2;
|
||||||
|
w->bounds.y2 = y2;
|
||||||
|
|
||||||
|
// Do we have content yet?
|
||||||
|
if (w->content) {
|
||||||
|
|
||||||
|
// Vertical Scroll Bar Thumb?
|
||||||
|
if (w->flags & WIN_SCROLL_V) {
|
||||||
|
// Distance between arrow buttons on scroll bar.
|
||||||
|
i = w->scrollv.y2 - w->scrollv.y - (WIDGET_SIZE * 2 - 2) - 2;
|
||||||
|
// Percentage to scale content height to scroll bar height.
|
||||||
|
d = (double)i / (double)surfaceHeightGet(w->content);
|
||||||
|
// Find position and size of thumb.
|
||||||
|
w->thumbv.x = w->scrollv.x + 1;
|
||||||
|
w->thumbv.x2 = w->scrollv.x2 - 1;
|
||||||
|
w->thumbv.y = w->scrollv.y + WIDGET_SIZE + (w->offset.y * d);
|
||||||
|
w->thumbv.y2 = w->thumbv.y + ((w->bounds.y2 - w->bounds.y) * d);
|
||||||
|
// Clamp overflow due to doubles and my off-by-one brain.
|
||||||
|
if (w->thumbv.y2 >= w->thumbv.y + i - 1) w->thumbv.y2 = w->thumbv.y + i - 1;
|
||||||
|
// Draw thumb.
|
||||||
|
surfaceBoxFilled(w->thumbv.x + 1, w->thumbv.y + 1, w->thumbv.x2 - 1, w->thumbv.y2 - 1, widgetColor);
|
||||||
|
surfaceBoxHighlight(w->thumbv.x, w->thumbv.y, w->thumbv.x2, w->thumbv.y2, GUI_WHITE, GUI_BLACK);
|
||||||
|
} else {
|
||||||
|
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal Scroll Bar Thumb?
|
||||||
|
if (w->flags & WIN_SCROLL_H) {
|
||||||
|
// Distance between arrow buttons on scroll bar.
|
||||||
|
i = w->scrollh.x2 - w->scrollh.x - (WIDGET_SIZE * 2 - 2) - 2;
|
||||||
|
// Percentage to scale content width to scroll bar width.
|
||||||
|
d = (double)i / (double)surfaceWidthGet(w->content);
|
||||||
|
// Find position and size of thumb.
|
||||||
|
w->thumbh.x = w->scrollh.x + WIDGET_SIZE + (w->offset.x * d);
|
||||||
|
w->thumbh.x2 = w->thumbh.x + ((w->bounds.x2 - w->bounds.x) * d);
|
||||||
|
w->thumbh.y = w->scrollh.y + 1;
|
||||||
|
w->thumbh.y2 = w->scrollh.y2 - 1;
|
||||||
|
// Clamp overflow due to doubles and my off-by-one brain.
|
||||||
|
if (w->thumbh.x2 >= w->thumbh.x + i - 1) w->thumbh.x2 = w->thumbh.x + i - 1;
|
||||||
|
// Draw thumb.
|
||||||
|
surfaceBoxFilled(w->thumbh.x + 1, w->thumbh.y + 1, w->thumbh.x2 - 1, w->thumbh.y2 - 1, widgetColor);
|
||||||
|
surfaceBoxHighlight(w->thumbh.x, w->thumbh.y, w->thumbh.x2, w->thumbh.y2, GUI_WHITE, GUI_BLACK);
|
||||||
|
} else {
|
||||||
|
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // Do we have content yet?
|
||||||
|
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
||||||
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Do we have content yet?
|
// Resize handle.
|
||||||
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
if (w->flags & WIN_RESIZE) {
|
||||||
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
w->resize1.x2 = w->base.r.x + w->base.r.w - 2;
|
||||||
}
|
w->resize1.x = w->resize1.x2 - 3;
|
||||||
|
w->resize1.y2 = w->base.r.y + w->base.r.h;
|
||||||
|
w->resize1.y = w->resize1.y2 - (WIDGET_SIZE + 5);
|
||||||
|
surfaceLineH(w->resize1.x, w->resize1.x2, w->resize1.y, GUI_BLACK);
|
||||||
|
surfaceLineH(w->resize1.x, w->resize1.x2, w->resize1.y + 1, GUI_WHITE);
|
||||||
|
w->resize2.x2 = w->base.r.x + w->base.r.w;
|
||||||
|
w->resize2.x = w->resize2.x2 - (WIDGET_SIZE + 5);
|
||||||
|
w->resize2.y2 = w->base.r.y + w->base.r.h - 2;
|
||||||
|
w->resize2.y = w->resize2.y2 - 3;
|
||||||
|
surfaceLineV(w->resize2.x, w->resize2.y, w->resize2.y2, GUI_BLACK);
|
||||||
|
surfaceLineV(w->resize2.x + 1, w->resize2.y, w->resize2.y2, GUI_WHITE);
|
||||||
|
} else {
|
||||||
|
w->resize1.x = w->resize1.y = w->resize1.x2 = w->resize1.y2 = 0;
|
||||||
|
w->resize2.x = w->resize2.y = w->resize2.x2 = w->resize2.y2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Resize handle.
|
} else { // Redraw window.
|
||||||
if (w->flags & WIN_RESIZE) {
|
|
||||||
w->resize1.x2 = w->base.r.x + w->base.r.w - 2;
|
// Since we didn't calculate them above, adjust bounds for content blit.
|
||||||
w->resize1.x = w->resize1.x2 - 3;
|
originalBounds = w->bounds;
|
||||||
w->resize1.y2 = w->base.r.y + w->base.r.h;
|
w->bounds.x -= originalX;
|
||||||
w->resize1.y = w->resize1.y2 - (WIDGET_SIZE + 5);
|
w->bounds.y -= originalY;
|
||||||
surfaceLineH(w->resize1.x, w->resize1.x2, w->resize1.y, GUI_BLACK);
|
w->bounds.x2 -= originalX;
|
||||||
surfaceLineH(w->resize1.x, w->resize1.x2, w->resize1.y + 1, GUI_WHITE);
|
w->bounds.y2 -= originalY;
|
||||||
w->resize2.x2 = w->base.r.x + w->base.r.w;
|
|
||||||
w->resize2.x = w->resize2.x2 - (WIDGET_SIZE + 5);
|
|
||||||
w->resize2.y2 = w->base.r.y + w->base.r.h - 2;
|
|
||||||
w->resize2.y = w->resize2.y2 - 3;
|
|
||||||
surfaceLineV(w->resize2.x, w->resize2.y, w->resize2.y2, GUI_BLACK);
|
|
||||||
surfaceLineV(w->resize2.x + 1, w->resize2.y, w->resize2.y2, GUI_WHITE);
|
|
||||||
} else {
|
|
||||||
w->resize1.x = w->resize1.y = w->resize1.x2 = w->resize1.y2 = 0;
|
|
||||||
w->resize2.x = w->resize2.y = w->resize2.x2 = w->resize2.y2 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
windowMove(w, originalX, originalY);
|
if (redrawWindow) {
|
||||||
|
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]) {
|
||||||
// Was it the focused window?
|
|
||||||
if (_windowList[i] == _windowTop) {
|
|
||||||
// Find new topmost window on next call to focus.
|
|
||||||
_windowTop = NULL;
|
|
||||||
}
|
|
||||||
// Free the title.
|
|
||||||
if (_windowList[i]->title) DEL(_windowList[i]->title);
|
|
||||||
// Free cached surface.
|
|
||||||
if (_windowList[i]->cached) surfaceDestroy(&_windowList[i]->cached);
|
|
||||||
// Free content surface.
|
|
||||||
if (_windowList[i]->content) surfaceDestroy(&_windowList[i]->content);
|
|
||||||
// Delete the window.
|
|
||||||
DEL(_windowList[i]);
|
|
||||||
// Remove it from window list.
|
|
||||||
arrdel(_windowList, i);
|
arrdel(_windowList, i);
|
||||||
// Fixup focus.
|
|
||||||
windowFocusSet(NULL);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Was it the focused window?
|
||||||
|
if (window == _windowTop) {
|
||||||
|
// Find new topmost window on next call to focus.
|
||||||
|
_windowTop = NULL;
|
||||||
|
}
|
||||||
|
// Free the 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.
|
||||||
|
if (window->cached) surfaceDestroy(&window->cached);
|
||||||
|
// Free content surface.
|
||||||
|
if (window->content) surfaceDestroy(&window->content);
|
||||||
|
// Delete the window.
|
||||||
|
DEL(window);
|
||||||
|
// Fixup focus.
|
||||||
|
windowFocusSet(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,40 +19,41 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct WindowS {
|
typedef struct WindowS {
|
||||||
WidgetT base; // Required by all widgets.
|
WidgetT base; // Required by all widgets.
|
||||||
char *title; // Title of window.
|
char *title; // Title of window.
|
||||||
uint8_t flags; // Window flags (see defines above).
|
uint8_t flags; // Window flags (see defines above).
|
||||||
RectT close; // Coordinates of close box, if any.
|
RectT close; // Coordinates of close box, if any.
|
||||||
RectT titlebar; // Coordinates of title bar, if any.
|
RectT titlebar; // Coordinates of title bar, if any.
|
||||||
RectT minimize; // Coordinates of minimize box, if any.
|
RectT minimize; // Coordinates of minimize box, if any.
|
||||||
RectT maximize; // Coordinates of maximize box, if any.
|
RectT maximize; // Coordinates of maximize box, if any.
|
||||||
RectT resize1; // First resize area.
|
RectT resize1; // First resize area.
|
||||||
RectT resize2; // Second resize area.
|
RectT resize2; // Second resize area.
|
||||||
RectT scrollv; // Vertical scroll bar.
|
RectT scrollv; // Vertical scroll bar.
|
||||||
RectT scrollh; // Horizontal scroll bar.
|
RectT scrollh; // Horizontal scroll bar.
|
||||||
RectT thumbv; // Vertical scroll bar thumb.
|
RectT thumbv; // Vertical scroll bar thumb.
|
||||||
RectT thumbh; // Horizontal scroll bar thumb.
|
RectT thumbh; // Horizontal scroll bar thumb.
|
||||||
RectT bounds; // Inside edge of window frame.
|
RectT bounds; // Inside edge of window frame.
|
||||||
RectT restore; // Size of window if they restore from maximized.
|
RectT restore; // Size of window if they restore from maximized.
|
||||||
PointT restoreOffset; // Scroll position if they restore from maximized.
|
PointT restoreOffset; // Scroll position if they restore from maximized.
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t __MAGIC_WINDOW; // Magic ID assigned to us from the GUI.
|
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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Reference in a new issue