diff options
Diffstat (limited to 'src/gwin/gwin.c')
-rw-r--r-- | src/gwin/gwin.c | 249 |
1 files changed, 183 insertions, 66 deletions
diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 84443f9f..dfcb8d4c 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -39,10 +39,11 @@ static color_t defaultBgColor = Black; #if GWIN_NEED_WINDOWMANAGER #define _gwm_redraw(gh, flags) _GWINwm->vmt->Redraw(gh, flags) - #define _gwm_redim(gh,x,y,w,h) _GWINwm->vmt->Redim(gh,x,y,w,h); + #define _gwm_move(gh,x,y) _GWINwm->vmt->Move(gh,x,y); + #define _gwm_resize(gh,w,h) _GWINwm->vmt->Size(gh,w,h); #else static void _gwm_redraw(GHandle gh, int flags) { - if ((gh->flags & GWIN_FLG_VISIBLE)) { + if ((gh->flags & GWIN_FLG_SYSVISIBLE)) { if (gh->vmt->Redraw) { #if GDISP_NEED_CLIP gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); @@ -63,19 +64,22 @@ static color_t defaultBgColor = Black; gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, defaultBgColor); } } - static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t width, coord_t height) { - gh->x = x; gh->y = y; + static void _gwm_resize(GHandle gh, coord_t width, coord_t height) { 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 + _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); + } + static void _gwm_move(GHandle gh, coord_t x, coord_t y) { + gh->x = x; gh->y = y; + if (gh->x < 0) gh->x = 0; + if (gh->y < 0) 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->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x; + if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y; _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); } #endif @@ -86,20 +90,30 @@ static color_t defaultBgColor = Black; void _gwinInit(void) { + #if GWIN_NEED_WINDOWMANAGER + extern void _gwmInit(void); + + _gwmInit(); + #endif #if GWIN_NEED_WIDGET extern void _gwidgetInit(void); _gwidgetInit(); #endif - #if GWIN_NEED_WINDOWMANAGER - extern void _gwmInit(void); + #if GWIN_NEED_CONTAINERS + extern void _gcontainerInit(void); - _gwmInit(); + _gcontainerInit(); #endif } void _gwinDeinit(void) { + #if GWIN_NEED_CONTAINERS + extern void _gcontainerDeinit(void); + + _gcontainerDeinit(); + #endif #if GWIN_NEED_WIDGET extern void _gwidgetDeinit(void); @@ -132,6 +146,18 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit pgw->font = defaultFont; #endif + #if GWIN_NEED_CONTAINERS + if (pInit->parent) { + if (!(pInit->parent->flags & GWIN_FLG_CONTAINER) || pgw->display != pInit->parent->display) { + if ((pgw->flags & GWIN_FLG_DYNAMIC)) + gfxFree(pgw); + return 0; + } + pgw->parent = pInit->parent; + } else + pgw->parent = 0; + #endif + #if GWIN_NEED_WINDOWMANAGER if (!_GWINwm->vmt->Add(pgw, pInit)) { if ((pgw->flags & GWIN_FLG_DYNAMIC)) @@ -139,7 +165,15 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit return 0; } #else - _gwm_redim(pgw, pInit->x, pInit->y, pInit->width, pInit->height); + pgw->x = pgw->y = pgw->width = pgw->height = 0; + _gwm_move(pgw, pInit->x, pInit->y); + _gwm_resize(pgw, pInit->width, pInit->height); + #endif + + #if GWIN_NEED_CONTAINERS + // Notify the parent it has been added + if (pgw->parent && ((gcontainerVMT *)pgw->parent->vmt)->NotifyAdd) + ((gcontainerVMT *)pgw->parent->vmt)->NotifyAdd(pgw->parent, pgw); #endif return (GHandle)pgw; @@ -203,6 +237,12 @@ void gwinDestroy(GHandle gh) { // Make the window invisible gwinSetVisible(gh, FALSE); + #if GWIN_NEED_CONTAINERS + // Notify the parent it is about to be deleted + if (gh->parent && ((gcontainerVMT *)gh->parent->vmt)->NotifyDelete) + ((gcontainerVMT *)gh->parent->vmt)->NotifyDelete(gh->parent, gh); + #endif + // Remove from the window manager #if GWIN_NEED_WINDOWMANAGER _GWINwm->vmt->Delete(gh); @@ -224,48 +264,120 @@ 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; - _gwm_redraw(gh, 0); +#if GWIN_NEED_CONTAINERS + // These two sub-functions set/clear system visibility recursively. + static bool_t setSysVisFlag(GHandle gh) { + // If we are now visible and our parent is visible + if ((gh->flags & GWIN_FLG_VISIBLE) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSVISIBLE))) { + gh->flags |= GWIN_FLG_SYSVISIBLE; + return TRUE; } - } else { - if ((gh->flags & GWIN_FLG_VISIBLE)) { - gh->flags &= ~GWIN_FLG_VISIBLE; - _gwm_redraw(gh, 0); + return FALSE; + } + static bool_t clrSysVisFlag(GHandle gh) { + // If we are now not visible but our parent is visible + if (!(gh->flags & GWIN_FLG_VISIBLE) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSVISIBLE))) { + gh->flags &= ~GWIN_FLG_SYSVISIBLE; + return TRUE; } + return FALSE; } -} + void gwinSetVisible(GHandle gh, bool_t visible) { + if (visible) { + if (!(gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags |= GWIN_FLG_VISIBLE; + _gwinRecurse(gh, setSysVisFlag); + _gwm_redraw(gh, 0); + } + } else { + if ((gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags &= ~GWIN_FLG_VISIBLE; + _gwinRecurse(gh, clrSysVisFlag); + _gwm_redraw(gh, 0); + } + } + } +#else + void gwinSetVisible(GHandle gh, bool_t visible) { + if (visible) { + if (!(gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags |= (GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE); + _gwm_redraw(gh, 0); + } + } else { + if ((gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags &= ~(GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE); + _gwm_redraw(gh, 0); + } + } + } +#endif bool_t gwinGetVisible(GHandle gh) { - return (gh->flags & GWIN_FLG_VISIBLE) ? TRUE : FALSE; + return (gh->flags & GWIN_FLG_SYSVISIBLE) ? TRUE : FALSE; } -void gwinSetEnabled(GHandle gh, bool_t enabled) { - if (enabled) { - if (!(gh->flags & GWIN_FLG_ENABLED)) { - gh->flags |= GWIN_FLG_ENABLED; - _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); +#if GWIN_NEED_CONTAINERS + // These two sub-functions set/clear system enable recursively. + static bool_t setSysEnaFlag(GHandle gh) { + // If we are now enabled and our parent is enabled + if ((gh->flags & GWIN_FLG_ENABLED) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSENABLED))) { + gh->flags |= GWIN_FLG_SYSENABLED; + return TRUE; } - } else { - if ((gh->flags & GWIN_FLG_ENABLED)) { - gh->flags &= ~GWIN_FLG_ENABLED; - _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); + return FALSE; + } + static bool_t clrSysEnaFlag(GHandle gh) { + // If we are now not enabled but our parent is enabled + if (!(gh->flags & GWIN_FLG_ENABLED) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSENABLED))) { + gh->flags &= ~GWIN_FLG_SYSENABLED; + return TRUE; } + return FALSE; } -} + void gwinSetEnabled(GHandle gh, bool_t enabled) { + if (enabled) { + if (!(gh->flags & GWIN_FLG_ENABLED)) { + gh->flags |= GWIN_FLG_ENABLED; + _gwinRecurse(gh, setSysEnaFlag); + if ((gh->flags & GWIN_FLG_SYSVISIBLE)) + _gwm_redraw(gh, GWIN_WMFLG_PRESERVE); + } + } else { + if ((gh->flags & GWIN_FLG_ENABLED)) { + gh->flags &= ~GWIN_FLG_ENABLED; + _gwinRecurse(gh, clrSysEnaFlag); + if ((gh->flags & GWIN_FLG_SYSVISIBLE)) + _gwm_redraw(gh, GWIN_WMFLG_PRESERVE); + } + } + } +#else + void gwinSetEnabled(GHandle gh, bool_t enabled) { + if (enabled) { + if (!(gh->flags & GWIN_FLG_ENABLED)) { + gh->flags |= (GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED); + _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); + } + } else { + if ((gh->flags & GWIN_FLG_ENABLED)) { + gh->flags &= ~(GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED); + _gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR); + } + } + } +#endif bool_t gwinGetEnabled(GHandle gh) { - return (gh->flags & GWIN_FLG_ENABLED) ? TRUE : FALSE; + return (gh->flags & GWIN_FLG_SYSENABLED) ? TRUE : FALSE; } void gwinMove(GHandle gh, coord_t x, coord_t y) { - _gwm_redim(gh, x, y, gh->width, gh->height); + _gwm_move(gh, x, y); } void gwinResize(GHandle gh, coord_t width, coord_t height) { - _gwm_redim(gh, gh->x, gh->y, width, height); + _gwm_resize(gh, width, height); } void gwinRedraw(GHandle gh) { @@ -284,23 +396,28 @@ void gwinClear(GHandle gh) { * still call the AfterClear() routine as some widgets will * need this to clear internal buffers or similar */ - if (!((gh->flags & GWIN_FLG_VISIBLE))) { + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) { if (gh->vmt->AfterClear) gh->vmt->AfterClear(gh); } else { - #if GDISP_NEED_CLIP - gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); - #endif + #if GDISP_NEED_CLIP + gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); + #endif - gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor); - if (gh->vmt->AfterClear) - gh->vmt->AfterClear(gh); + gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor); + if (gh->vmt->AfterClear) + gh->vmt->AfterClear(gh); } + + #if GWIN_NEED_CONTAINERS + for (gh = gwinGetFirstChild(gh); gh; gh = gwinGetSibling(gh)) + gwinRedraw(gh); + #endif } void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { - if (!((gh->flags & GWIN_FLG_VISIBLE))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -310,7 +427,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -320,7 +437,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -330,7 +447,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -340,7 +457,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -351,7 +468,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -361,7 +478,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -373,7 +490,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -383,7 +500,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -395,7 +512,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -405,7 +522,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -417,7 +534,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return defaultBgColor; #if GDISP_NEED_CLIP @@ -429,7 +546,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -439,7 +556,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -449,7 +566,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -459,7 +576,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -469,7 +586,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -479,7 +596,7 @@ 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->flags & GWIN_FLG_VISIBLE)) || !gh->font) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font) return; #if GDISP_NEED_CLIP @@ -491,7 +608,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -501,7 +618,7 @@ 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return; #if GDISP_NEED_CLIP @@ -513,7 +630,7 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_IMAGE 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))) + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) return GDISP_IMAGE_ERR_OK; #if GDISP_NEED_CLIP |