roo_e/client/src/gui/gui.c
2022-06-24 18:41:27 -05:00

185 lines
4.4 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[MOUSE_COUNT] = { 0 };
static ColorT _mouseTransparency = 0;
static uint8_t _mouseCurrent = MOUSE_POINTER;
static PointT _mouseHotspot[MOUSE_COUNT] = {
{ 0, 0 },
{ 8, 8 }
};
void guiEventsDo(void) {
EventT event = { 0 };
// Paint desktop.
surfaceSet(__guiBackBuffer);
surfaceClear(GUI_CYAN);
// Read mouse & keyboard.
platformEventGet(&event);
// Handle GUI window manager and widgets.
wmUpdate(&event);
// Paint mouse pointer.
surfaceSet(__guiBackBuffer);
surfaceBlitWithTransparency(event.x - _mouseHotspot[_mouseCurrent].x, event.y - _mouseHotspot[_mouseCurrent].y, _mousePointer[_mouseCurrent], _mouseTransparency);
// Copy to screen.
videoBlit(0, 0, __guiBackBuffer);
// Emergency Exit?
if (event.flags & EVENT_FLAG_KEYPRESS && event.key == KEY_ESC) guiStop();
}
uint8_t guiMousePointerGet(void) {
return _mouseCurrent;
}
void guiMousePointerSet(uint8_t pointer) {
_mouseCurrent = pointer;
}
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) {
uint8_t i;
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);
for (i=0; i<MOUSE_COUNT; i++) surfaceDestroy(&_mousePointer[i]);
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]);
}
_mousePointer[MOUSE_POINTER] = imageLoad("mouse.png");
_mousePointer[MOUSE_RESIZE] = imageLoad("resize.png");
_mouseTransparency = surfacePixelGet(_mousePointer[MOUSE_POINTER], surfaceWidthGet(_mousePointer[MOUSE_POINTER]) - 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);
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
surfaceSet(__guiBackBuffer);
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;
}