diff options
Diffstat (limited to 'src/gwin/gwin.c')
-rw-r--r-- | src/gwin/gwin.c | 383 |
1 files changed, 294 insertions, 89 deletions
diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 2f9d2dfd..e5997bc8 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -9,127 +9,278 @@ #if GFX_USE_GWIN -#include "gwin/internal.h" +#include "gwin/class_gwin.h" + +// Needed if there is no window manager +#define MIN_WIN_WIDTH 1 +#define MIN_WIN_HEIGHT 1 + +/*----------------------------------------------- + * Data + *-----------------------------------------------*/ + +static const gwinVMT basegwinVMT = { + "GWIN", // The classname + sizeof(GWindowObject), // The object size + 0, // The destroy routine + 0, // The redraw routine + 0, // The after-clear routine +}; + +static color_t defaultFgColor = White; +static color_t defaultBgColor = Black; +#if GDISP_NEED_TEXT + static font_t defaultFont; +#endif + +/*----------------------------------------------- + * Helper Routines + *-----------------------------------------------*/ + +#if !GWIN_NEED_WINDOWMANAGER + static void _gwm_vis(GHandle gh) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } else + gwinClear(gh); + } + static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t width, coord_t height) { + gh->x = x; gh->y = y; + gh->width = width; gh->height = height; + if (gh->x < 0) { gh->width += gh->x; gh->x = 0; } + if (gh->y < 0) { gh->height += gh->y; gh->y = 0; } + if (gh->x > gdispGetWidth()-MIN_WIN_WIDTH) gh->x = gdispGetWidth()-MIN_WIN_WIDTH; + if (gh->y > gdispGetHeight()-MIN_WIN_HEIGHT) gh->y = gdispGetHeight()-MIN_WIN_HEIGHT; + if (gh->width < MIN_WIN_WIDTH) { gh->width = MIN_WIN_WIDTH; } + if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; } + if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x; + if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y; + + // Redraw the window + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } + } +#endif + +/*----------------------------------------------- + * Class Routines + *-----------------------------------------------*/ + +void _gwinInit(void) { + #if GWIN_NEED_WIDGET + extern void _gwidgetInit(void); + + _gwidgetInit(); + #endif + #if GWIN_NEED_WINDOWMANAGER + extern void _gwmInit(void); + + _gwmInit(); + #endif +} // Internal routine for use by GWIN components only -// Initialise a window creating it dynamicly if required. -GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size) { - coord_t w, h; - - // Check the window size against the screen size - w = gdispGetWidth(); - h = gdispGetHeight(); - if (x < 0) { width += x; x = 0; } - if (y < 0) { height += y; y = 0; } - if (x >= w || y >= h) return 0; - if (x+width > w) width = w - x; - if (y+height > h) height = h - y; - +// Initialise a window creating it dynamically if required. +GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary - if (!gw) { - if (!(gw = (GWindowObject *)gfxAlloc(size))) + if (!pgw) { + if (!(pgw = (GWindowObject *)gfxAlloc(vmt->size))) return 0; - gw->flags = GWIN_FLG_DYNAMIC; + pgw->flags = flags|GWIN_FLG_DYNAMIC; } else - gw->flags = 0; + pgw->flags = flags; - // Initialise all basic fields (except the type) - gw->x = x; - gw->y = y; - gw->width = width; - gw->height = height; - gw->color = White; - gw->bgcolor = Black; + // Initialise all basic fields + pgw->vmt = vmt; + pgw->color = defaultFgColor; + pgw->bgcolor = defaultBgColor; #if GDISP_NEED_TEXT - gw->font = 0; + pgw->font = defaultFont; #endif - return (GHandle)gw; -} -GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gw = (GWindowObject *)_gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject)))) +#if GWIN_NEED_WINDOWMANAGER + if (!_GWINwm->vmt->Add(pgw, pInit)) { + if ((pgw->flags & GWIN_FLG_DYNAMIC)) + gfxFree(pgw); return 0; - gw->type = GW_WINDOW; - return (GHandle)gw; + } +#else + _gwm_redim(pgw, pInit->x, pInit->y, pInit->width, pInit->height); +#endif + + return (GHandle)pgw; } -void gwinSetEnabled(GHandle gh, bool_t enabled) { - (void)gh; - (void)enabled; +/*----------------------------------------------- + * Routines that affect all windows + *-----------------------------------------------*/ + +void gwinSetDefaultColor(color_t clr) { + defaultFgColor = clr; } -void gwinDestroyWindow(GHandle gh) { - // Clean up any type specific dynamic memory allocations - switch(gh->type) { -#if GWIN_NEED_BUTTON - case GW_BUTTON: - if ((gh->flags & GBTN_FLG_ALLOCTXT)) { - gh->flags &= ~GBTN_FLG_ALLOCTXT; // To be sure, to be sure - gfxFree((void *)((GButtonObject *)gh)->txt); - } - geventDetachSource(&((GButtonObject *)gh)->listener, 0); - geventDetachSourceListeners((GSourceHandle)gh); - break; -#endif -#if GWIN_NEED_SLIDER - case GW_SLIDER: - geventDetachSource(&((GSliderObject *)gh)->listener, 0); - geventDetachSourceListeners((GSourceHandle)gh); - break; -#endif - default: - break; +color_t gwinGetDefaultColor(void) { + return defaultFgColor; +} + +void gwinSetDefaultBgColor(color_t bgclr) { + defaultBgColor = bgclr; +} + +color_t gwinGetDefaultBgColor(void) { + return defaultBgColor; +} + +#if GDISP_NEED_TEXT + void gwinSetDefaultFont(font_t font) { + defaultFont = font; + } + + font_t gwinGetDefaultFont(void) { + return defaultFont; } +#endif + +/*----------------------------------------------- + * The GWindow Routines + *-----------------------------------------------*/ + +GHandle gwinWindowCreate(GWindowObject *pgw, const GWindowInit *pInit) { + if (!(pgw = _gwindowCreate(pgw, pInit, &basegwinVMT, 0))) + return 0; + gwinSetVisible(pgw, pInit->show); + return pgw; +} + +void gwinDestroy(GHandle gh) { + // Remove from the window manager + #if GWIN_NEED_WINDOWMANAGER + _GWINwm->vmt->Delete(gh); + #endif + + // Class destroy routine + if (gh->vmt->Destroy) + gh->vmt->Destroy(gh); // Clean up the structure - if (gh->flags & GWIN_FLG_DYNAMIC) { - gh->flags = 0; // To be sure, to be sure + if (gh->flags & GWIN_FLG_DYNAMIC) gfxFree((void *)gh); + + gh->flags = 0; // To be sure, to be sure +} + +const char *gwinGetClassName(GHandle gh) { + return gh->vmt->classname; +} + +void gwinSetVisible(GHandle gh, bool_t visible) { + if (visible) { + if (!(gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags |= GWIN_FLG_VISIBLE; + #if GWIN_NEED_WINDOWMANAGER + _GWINwm->vmt->Visible(gh); + #else + _gwm_vis(gh); + #endif + } + } else { + if ((gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags &= ~GWIN_FLG_VISIBLE; + #if GWIN_NEED_WINDOWMANAGER + _GWINwm->vmt->Visible(gh); + #endif + } + } +} + +bool_t gwinGetVisible(GHandle gh) { + return (gh->flags & GWIN_FLG_VISIBLE) ? TRUE : FALSE; +} + +void gwinSetEnabled(GHandle gh, bool_t enabled) { + if (enabled) { + if (!(gh->flags & GWIN_FLG_ENABLED)) { + gh->flags |= GWIN_FLG_ENABLED; + if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } + } else { + if ((gh->flags & GWIN_FLG_ENABLED)) { + gh->flags &= ~GWIN_FLG_ENABLED; + if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } } } -void gwinDraw(GHandle gh) { - switch(gh->type) { - #if GWIN_NEED_BUTTON - case GW_BUTTON: - gwinButtonDraw(gh); - break; +bool_t gwinGetEnabled(GHandle gh) { + return (gh->flags & GWIN_FLG_ENABLED) ? TRUE : FALSE; +} + +void gwinMove(GHandle gh, coord_t x, coord_t y) { + #if GWIN_NEED_WINDOWMANAGER + _GWINwm->vmt->Redim(gh, x, y, gh->width, gh->height); + #else + _gwm_redim(gh, x, y, gh->width, gh->height); #endif - #if GWIN_NEED_SLIDER - case GW_SLIDER: - gwinSliderDraw(gh); - break; +} + +void gwinResize(GHandle gh, coord_t width, coord_t height) { + #if GWIN_NEED_WINDOWMANAGER + _GWINwm->vmt->Redim(gh, gh->x, gh->y, width, height); + #else + _gwm_redim(gh, gh->x, gh->y, width, height); + #endif +} + +void gwinRedraw(GHandle gh) { + #if GWIN_NEED_WINDOWMANAGER + gwinRaise(gh); + #else + if ((gh->flags & GWIN_FLG_VISIBLE)) + _gwm_vis(gh); #endif - } } #if GDISP_NEED_TEXT void gwinSetFont(GHandle gh, font_t font) { gh->font = font; - #if GWIN_NEED_CONSOLE - if (font && gh->type == GW_CONSOLE) { - ((GConsoleObject *)gh)->fy = gdispGetFontMetric(font, fontHeight); - ((GConsoleObject *)gh)->fp = gdispGetFontMetric(font, fontCharPadding); - } - #endif } #endif void gwinClear(GHandle gh) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor); - - #if GWIN_NEED_CONSOLE - if (gh->type == GW_CONSOLE) { - ((GConsoleObject *)gh)->cx = 0; - ((GConsoleObject *)gh)->cy = 0; - } - #endif + if (gh->vmt->AfterClear) + gh->vmt->AfterClear(gh); } void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -137,6 +288,9 @@ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { } void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -144,6 +298,9 @@ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) { } void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -151,6 +308,9 @@ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { } void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -158,6 +318,9 @@ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { } void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -166,6 +329,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_CIRCLE void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -173,6 +339,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -182,6 +351,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_ELLIPSE void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -189,6 +361,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -198,6 +373,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_ARC void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -205,6 +383,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -214,6 +395,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_PIXELREAD color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -223,7 +407,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_TEXT void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -231,7 +417,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -239,7 +427,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -247,7 +437,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -255,7 +447,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -263,7 +457,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -273,6 +469,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_CONVEX_POLYGON void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -280,6 +479,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -288,7 +490,10 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #endif #if GDISP_NEED_IMAGE - gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return GDISP_IMAGE_ERR_OK; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif |