168 lines
3.8 KiB
C
168 lines
3.8 KiB
C
#include "gui.h"
|
|
#include "font.h"
|
|
#include "wmwindow.h"
|
|
#include "image.h"
|
|
#include "array.h"
|
|
|
|
|
|
typedef struct WidgetCatalogS {
|
|
uint8_t key; // Magic
|
|
RegisterT *value;
|
|
} WidgetCatalogT;
|
|
|
|
|
|
ColorT *__guiBaseColors = NULL;
|
|
SurfaceT *__guiBackBuffer = NULL;
|
|
FontT *__guiFontVGA8x8 = NULL;
|
|
FontT *__guiFontVGA8x14 = NULL;
|
|
FontT *__guiFontVGA8x16 = NULL;
|
|
|
|
|
|
static uint8_t _magicCount = 0;
|
|
static WidgetCatalogT *_widgetCatalog = NULL;
|
|
static uint8_t _guiRunning = 1;
|
|
static SurfaceT *_mousePointer = NULL;
|
|
static ColorT _mouseTransparency;
|
|
|
|
|
|
void guiEventsDo(void) {
|
|
EventT event = { 0 };
|
|
|
|
// Read mouse & keyboard.
|
|
platformEventGet(&event);
|
|
|
|
// Paint desktop.
|
|
surfaceSet(__guiBackBuffer);
|
|
surfaceClear(GUI_CYAN);
|
|
|
|
// Paint GUI.
|
|
wmPaint(&event);
|
|
|
|
// Paint mouse pointer.
|
|
surfaceBlitWithTransparency(__guiBackBuffer, event.x, event.y, _mousePointer, _mouseTransparency);
|
|
|
|
// Copy to screen.
|
|
videoBlit(0, 0, __guiBackBuffer);
|
|
|
|
// Emergency Exit?
|
|
if (event.flags & EVENT_FLAG_KEYPRESS && event.key == KEY_ESC) guiStop();
|
|
}
|
|
|
|
|
|
void guiRegister(WidgetRegisterT widgetRegister) {
|
|
RegisterT *reg = widgetRegister(_magicCount);
|
|
hmput(_widgetCatalog, _magicCount, reg);
|
|
_magicCount++;
|
|
}
|
|
|
|
|
|
void guiRun(void) {
|
|
|
|
while (_guiRunning) {
|
|
|
|
// Process all GUI events.
|
|
guiEventsDo();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void guiShutdown(void) {
|
|
|
|
DEL(__guiBaseColors);
|
|
|
|
while (hmlen(_widgetCatalog) > 0) {
|
|
if (_widgetCatalog[0].value->unregister) _widgetCatalog[0].value->unregister(NULL);
|
|
hmdel(_widgetCatalog, _widgetCatalog[0].key);
|
|
}
|
|
hmfree(_widgetCatalog);
|
|
|
|
wmShutdown();
|
|
|
|
fontUnload(&__guiFontVGA8x16);
|
|
fontUnload(&__guiFontVGA8x14);
|
|
fontUnload(&__guiFontVGA8x8);
|
|
|
|
surfaceDestroy(&_mousePointer);
|
|
surfaceDestroy(&__guiBackBuffer);
|
|
|
|
platformShutdown();
|
|
}
|
|
|
|
|
|
uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
|
|
uint8_t i;
|
|
uint8_t EGA[16][3] = {
|
|
{ 0, 0, 0 }, /* black */
|
|
{ 0, 0, 170 }, /* blue */
|
|
{ 0, 170, 0 }, /* green */
|
|
{ 0, 170, 170 }, /* cyan */
|
|
{ 170, 0, 0 }, /* red */
|
|
{ 170, 0, 170 }, /* magenta */
|
|
{ 170, 85, 0 }, /* brown */
|
|
{ 170, 170, 170 }, /* light gray */
|
|
{ 85, 85, 85 }, /* dark gray */
|
|
{ 85, 85, 255 }, /* light blue */
|
|
{ 85, 255, 85 }, /* light green */
|
|
{ 85, 255, 255 }, /* light cyan */
|
|
{ 255, 85, 85 }, /* light red */
|
|
{ 255, 85, 255 }, /* light magenta */
|
|
{ 255, 255, 85 }, /* yellow */
|
|
{ 255, 255, 255 } /* white */
|
|
};
|
|
|
|
if (platformStartup(width, height, depth) == FAIL) return FAIL;
|
|
|
|
__guiBaseColors = (ColorT *)malloc(sizeof(ColorT) * 16);
|
|
for (i=0; i<16; i++) {
|
|
__guiBaseColors[i] = surfaceColorMake(EGA[i][0], EGA[i][1], EGA[i][2]);
|
|
}
|
|
|
|
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
|
|
surfaceSet(__guiBackBuffer);
|
|
|
|
_mousePointer = imageLoad("mouse.png");
|
|
_mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet(_mousePointer) - 2, 0); // Find our transparency color.
|
|
|
|
__guiFontVGA8x8 = fontLoad("vga8x8.dat");
|
|
__guiFontVGA8x14 = fontLoad("vga8x14.dat");
|
|
__guiFontVGA8x16 = fontLoad("vga8x16.dat");
|
|
fontSet(__guiFontVGA8x14);
|
|
fontColorSet(GUI_WHITE, GUI_BLACK);
|
|
|
|
wmStartup();
|
|
|
|
// Register all known widgets with the GUI.
|
|
guiRegister(windowRegister);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
void guiStop(void) {
|
|
_guiRunning = 0;
|
|
}
|
|
|
|
|
|
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
|
widget->magic = magic;
|
|
|
|
widget->r.x = x;
|
|
widget->r.y = y;
|
|
widget->r.w = w;
|
|
widget->r.h = h;
|
|
|
|
widget->reg = hmget(_widgetCatalog, magic);
|
|
|
|
widget->dirty = 1; // Everything starts dirty to force a paint.
|
|
}
|
|
|
|
|
|
uint8_t guiWidgetDirtyGet(WidgetT *widget) {
|
|
return widget->dirty;
|
|
}
|
|
|
|
|
|
void guiWidgetDirtySet(WidgetT *widget, uint8_t dirty) {
|
|
widget->dirty = dirty;
|
|
}
|