2013-03-02 12:03:40 +00:00
|
|
|
/*
|
2013-06-15 11:09:02 +00:00
|
|
|
* This file is subject to the terms of the GFX License. If a copy of
|
2013-05-03 14:36:17 +00:00
|
|
|
* the license was not distributed with this file, you can obtain one at:
|
2013-03-02 12:03:40 +00:00
|
|
|
*
|
2013-07-21 20:20:37 +00:00
|
|
|
* http://ugfx.org/license.html
|
2013-03-02 12:03:40 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "gfx.h"
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GFX_USE_GWIN
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2014-02-18 14:36:52 +00:00
|
|
|
#include "src/gwin/class_gwin.h"
|
2013-06-06 04:33:32 +00:00
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
// Needed if there is no window manager
|
|
|
|
#define MIN_WIN_WIDTH 1
|
|
|
|
#define MIN_WIN_HEIGHT 1
|
|
|
|
|
|
|
|
/*-----------------------------------------------
|
|
|
|
* Data
|
|
|
|
*-----------------------------------------------*/
|
|
|
|
|
2013-06-06 04:33:32 +00:00
|
|
|
static const gwinVMT basegwinVMT = {
|
|
|
|
"GWIN", // The classname
|
2013-06-24 12:58:37 +00:00
|
|
|
sizeof(GWindowObject), // The object size
|
2013-06-06 04:33:32 +00:00
|
|
|
0, // The destroy routine
|
2013-06-07 16:27:59 +00:00
|
|
|
0, // The redraw routine
|
2013-06-06 04:33:32 +00:00
|
|
|
0, // The after-clear routine
|
|
|
|
};
|
|
|
|
|
2013-06-06 06:48:30 +00:00
|
|
|
static color_t defaultFgColor = White;
|
|
|
|
static color_t defaultBgColor = Black;
|
2013-06-07 16:27:59 +00:00
|
|
|
#if GDISP_NEED_TEXT
|
|
|
|
static font_t defaultFont;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*-----------------------------------------------
|
|
|
|
* Helper Routines
|
|
|
|
*-----------------------------------------------*/
|
|
|
|
|
2013-11-15 16:01:16 +00:00
|
|
|
#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);
|
|
|
|
#else
|
|
|
|
static void _gwm_redraw(GHandle gh, int flags) {
|
|
|
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
|
|
|
if (gh->vmt->Redraw) {
|
|
|
|
#if GDISP_NEED_CLIP
|
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
|
|
#endif
|
|
|
|
gh->vmt->Redraw(gh);
|
2013-11-23 02:58:07 +00:00
|
|
|
} else if (!(flags & GWIN_WMFLG_PRESERVE)) {
|
2013-11-15 16:01:16 +00:00
|
|
|
#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);
|
|
|
|
}
|
|
|
|
} else if (!(flags & GWIN_WMFLG_NOBGCLEAR)) {
|
2013-06-07 16:27:59 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-11-15 16:01:16 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-06-07 16:27:59 +00:00
|
|
|
#endif
|
2013-11-15 16:01:16 +00:00
|
|
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, defaultBgColor);
|
|
|
|
}
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
2013-07-07 09:40:37 +00:00
|
|
|
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;
|
2013-06-24 12:58:37 +00:00
|
|
|
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;
|
2013-07-03 14:20:32 +00:00
|
|
|
|
|
|
|
// Redraw the window
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*-----------------------------------------------
|
|
|
|
* Class Routines
|
|
|
|
*-----------------------------------------------*/
|
|
|
|
|
2014-02-02 18:24:43 +00:00
|
|
|
void _gwinInit(void)
|
|
|
|
{
|
2013-06-10 07:18:01 +00:00
|
|
|
#if GWIN_NEED_WIDGET
|
|
|
|
extern void _gwidgetInit(void);
|
|
|
|
|
|
|
|
_gwidgetInit();
|
|
|
|
#endif
|
2013-06-07 16:27:59 +00:00
|
|
|
#if GWIN_NEED_WINDOWMANAGER
|
2013-07-07 09:40:37 +00:00
|
|
|
extern void _gwmInit(void);
|
|
|
|
|
|
|
|
_gwmInit();
|
2013-06-07 16:27:59 +00:00
|
|
|
#endif
|
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2014-02-02 18:24:43 +00:00
|
|
|
void _gwinDeinit(void)
|
|
|
|
{
|
|
|
|
#if GWIN_NEED_WIDGET
|
|
|
|
extern void _gwidgetDeinit(void);
|
|
|
|
|
|
|
|
_gwidgetDeinit();
|
|
|
|
#endif
|
|
|
|
#if GWIN_NEED_WINDOWMANAGER
|
|
|
|
extern void _gwmDeinit(void);
|
|
|
|
|
|
|
|
_gwmDeinit();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
// Internal routine for use by GWIN components only
|
2013-06-07 16:27:59 +00:00
|
|
|
// Initialise a window creating it dynamically if required.
|
2013-10-24 08:36:11 +00:00
|
|
|
GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) {
|
2013-03-02 12:03:40 +00:00
|
|
|
// Allocate the structure if necessary
|
2013-06-06 04:33:32 +00:00
|
|
|
if (!pgw) {
|
2014-02-02 11:59:36 +00:00
|
|
|
if (!(pgw = gfxAlloc(vmt->size)))
|
2013-03-02 12:03:40 +00:00
|
|
|
return 0;
|
2013-06-07 16:27:59 +00:00
|
|
|
pgw->flags = flags|GWIN_FLG_DYNAMIC;
|
2013-03-02 12:03:40 +00:00
|
|
|
} else
|
2013-06-07 16:27:59 +00:00
|
|
|
pgw->flags = flags;
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-06-06 04:33:32 +00:00
|
|
|
// Initialise all basic fields
|
2013-10-24 08:36:11 +00:00
|
|
|
pgw->display = g;
|
2013-06-06 04:33:32 +00:00
|
|
|
pgw->vmt = vmt;
|
2013-06-06 06:48:30 +00:00
|
|
|
pgw->color = defaultFgColor;
|
|
|
|
pgw->bgcolor = defaultBgColor;
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_TEXT
|
2013-06-06 04:33:32 +00:00
|
|
|
pgw->font = defaultFont;
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-06-07 16:27:59 +00:00
|
|
|
|
2013-11-15 16:01:16 +00:00
|
|
|
#if GWIN_NEED_WINDOWMANAGER
|
|
|
|
if (!_GWINwm->vmt->Add(pgw, pInit)) {
|
|
|
|
if ((pgw->flags & GWIN_FLG_DYNAMIC))
|
|
|
|
gfxFree(pgw);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
_gwm_redim(pgw, pInit->x, pInit->y, pInit->width, pInit->height);
|
|
|
|
#endif
|
2013-06-07 16:27:59 +00:00
|
|
|
|
2014-02-02 15:15:08 +00:00
|
|
|
#if GWIN_NEED_HIERARCHY
|
|
|
|
pgw->parent = NULL;
|
|
|
|
pgw->sibling = NULL;
|
|
|
|
pgw->child = NULL;
|
|
|
|
#endif
|
|
|
|
|
2013-06-06 04:33:32 +00:00
|
|
|
return (GHandle)pgw;
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
/*-----------------------------------------------
|
|
|
|
* Routines that affect all windows
|
|
|
|
*-----------------------------------------------*/
|
|
|
|
|
|
|
|
void gwinSetDefaultColor(color_t clr) {
|
|
|
|
defaultFgColor = clr;
|
|
|
|
}
|
|
|
|
|
2013-07-03 14:20:32 +00:00
|
|
|
color_t gwinGetDefaultColor(void) {
|
|
|
|
return defaultFgColor;
|
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
void gwinSetDefaultBgColor(color_t bgclr) {
|
|
|
|
defaultBgColor = bgclr;
|
|
|
|
}
|
|
|
|
|
2013-07-03 14:20:32 +00:00
|
|
|
color_t gwinGetDefaultBgColor(void) {
|
|
|
|
return defaultBgColor;
|
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
#if GDISP_NEED_TEXT
|
|
|
|
void gwinSetDefaultFont(font_t font) {
|
|
|
|
defaultFont = font;
|
|
|
|
}
|
2013-07-02 17:26:48 +00:00
|
|
|
|
|
|
|
font_t gwinGetDefaultFont(void) {
|
|
|
|
return defaultFont;
|
|
|
|
}
|
2013-06-07 16:27:59 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*-----------------------------------------------
|
|
|
|
* The GWindow Routines
|
|
|
|
*-----------------------------------------------*/
|
|
|
|
|
2013-10-24 08:36:11 +00:00
|
|
|
GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit) {
|
|
|
|
if (!(pgw = _gwindowCreate(g, pgw, pInit, &basegwinVMT, 0)))
|
2013-06-24 12:58:37 +00:00
|
|
|
return 0;
|
2014-01-04 03:41:32 +00:00
|
|
|
|
2013-06-24 12:58:37 +00:00
|
|
|
gwinSetVisible(pgw, pInit->show);
|
2014-01-04 03:41:32 +00:00
|
|
|
|
2013-06-24 12:58:37 +00:00
|
|
|
return pgw;
|
2013-05-20 14:18:10 +00:00
|
|
|
}
|
|
|
|
|
2013-06-06 04:33:32 +00:00
|
|
|
void gwinDestroy(GHandle gh) {
|
2014-01-05 19:42:19 +00:00
|
|
|
if (!gh) {
|
|
|
|
// should log a runtime error here
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-04 20:10:10 +00:00
|
|
|
#if GWIN_NEED_HIERARCHY
|
2014-01-05 19:42:19 +00:00
|
|
|
GHandle tmp;
|
|
|
|
|
|
|
|
// recursively destroy our children first
|
|
|
|
for(tmp = gh->child; tmp; tmp = tmp->sibling)
|
|
|
|
gwinDestroy(tmp);
|
|
|
|
|
|
|
|
// remove myself from the hierarchy
|
2014-01-05 21:37:01 +00:00
|
|
|
gwinRemoveChild(gh);
|
|
|
|
|
|
|
|
// issue a redraw of my parent if any
|
|
|
|
if (gh->parent) {
|
|
|
|
gwinRedraw(gh->parent);
|
|
|
|
}
|
2014-01-04 20:10:10 +00:00
|
|
|
#endif
|
|
|
|
|
2013-11-15 16:01:16 +00:00
|
|
|
// Make the window invisible
|
|
|
|
gwinSetVisible(gh, FALSE);
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
// Remove from the window manager
|
|
|
|
#if GWIN_NEED_WINDOWMANAGER
|
2013-07-07 09:40:37 +00:00
|
|
|
_GWINwm->vmt->Delete(gh);
|
2013-06-07 16:27:59 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Class destroy routine
|
2013-06-06 04:33:32 +00:00
|
|
|
if (gh->vmt->Destroy)
|
|
|
|
gh->vmt->Destroy(gh);
|
2013-03-02 12:03:40 +00:00
|
|
|
|
|
|
|
// Clean up the structure
|
2013-09-18 22:28:26 +00:00
|
|
|
if (gh->flags & GWIN_FLG_DYNAMIC) {
|
|
|
|
gh->flags = 0; // To be sure, to be sure
|
2013-05-24 15:26:52 +00:00
|
|
|
gfxFree((void *)gh);
|
2013-09-18 22:28:26 +00:00
|
|
|
} else
|
|
|
|
gh->flags = 0; // To be sure, to be sure
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
2013-06-06 04:33:32 +00:00
|
|
|
const char *gwinGetClassName(GHandle gh) {
|
|
|
|
return gh->vmt->classname;
|
2013-04-06 12:31:40 +00:00
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
void gwinSetVisible(GHandle gh, bool_t visible) {
|
|
|
|
if (visible) {
|
|
|
|
if (!(gh->flags & GWIN_FLG_VISIBLE)) {
|
|
|
|
gh->flags |= GWIN_FLG_VISIBLE;
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redraw(gh, 0);
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
|
|
|
gh->flags &= ~GWIN_FLG_VISIBLE;
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redraw(gh, 0);
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
2013-06-06 06:48:30 +00:00
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
bool_t gwinGetVisible(GHandle gh) {
|
2014-01-04 14:51:18 +00:00
|
|
|
#if GWIN_NEED_HIERARCHY
|
|
|
|
// return TRUE if all widgets (itself + parents) are visble, false otherwise
|
|
|
|
GHandle e = gh;
|
2014-01-04 20:21:51 +00:00
|
|
|
for (e = gh; e; e = e->parent) {
|
2014-01-04 14:51:18 +00:00
|
|
|
if (!(e->flags & GWIN_FLG_VISIBLE))
|
|
|
|
return FALSE;
|
2014-01-04 15:05:42 +00:00
|
|
|
}
|
2014-01-04 14:51:18 +00:00
|
|
|
return TRUE;
|
|
|
|
#else
|
|
|
|
return (gh->flags & GWIN_FLG_VISIBLE) ? TRUE : FALSE;
|
|
|
|
#endif
|
2013-06-06 06:48:30 +00:00
|
|
|
}
|
|
|
|
|
2013-07-03 14:59:12 +00:00
|
|
|
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
|
|
|
if (enabled) {
|
|
|
|
if (!(gh->flags & GWIN_FLG_ENABLED)) {
|
|
|
|
gh->flags |= GWIN_FLG_ENABLED;
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
2013-07-03 14:59:12 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((gh->flags & GWIN_FLG_ENABLED)) {
|
|
|
|
gh->flags &= ~GWIN_FLG_ENABLED;
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
2013-07-03 14:59:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool_t gwinGetEnabled(GHandle gh) {
|
2014-01-04 14:12:06 +00:00
|
|
|
#if GWIN_NEED_HIERARCHY
|
2014-01-04 14:51:18 +00:00
|
|
|
// return TRUE if all widgets (itself + parents) are enabled, false otherwise
|
2014-01-04 14:12:06 +00:00
|
|
|
GHandle e = gh;
|
2014-01-04 20:21:51 +00:00
|
|
|
for (e = gh; e; e = e->parent) {
|
2014-01-04 14:51:18 +00:00
|
|
|
if (!(e->flags & GWIN_FLG_ENABLED))
|
|
|
|
return FALSE;
|
2014-01-04 15:05:42 +00:00
|
|
|
}
|
2014-01-04 14:51:18 +00:00
|
|
|
return TRUE;
|
2014-01-04 14:12:06 +00:00
|
|
|
#else
|
|
|
|
return (gh->flags & GWIN_FLG_ENABLED) ? TRUE : FALSE;
|
|
|
|
#endif
|
2013-07-03 14:59:12 +00:00
|
|
|
}
|
|
|
|
|
2013-06-07 16:27:59 +00:00
|
|
|
void gwinMove(GHandle gh, coord_t x, coord_t y) {
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redim(gh, x, y, gh->width, gh->height);
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinResize(GHandle gh, coord_t width, coord_t height) {
|
2013-11-15 16:01:16 +00:00
|
|
|
_gwm_redim(gh, gh->x, gh->y, width, height);
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
2013-06-06 04:33:32 +00:00
|
|
|
|
2013-07-07 09:40:37 +00:00
|
|
|
void gwinRedraw(GHandle gh) {
|
2014-01-05 03:02:03 +00:00
|
|
|
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE | GWIN_WMFLG_NOBGCLEAR);
|
|
|
|
|
|
|
|
#if GWIN_NEED_HIERARCHY
|
|
|
|
GHandle tmp;
|
2014-01-05 21:37:01 +00:00
|
|
|
for (tmp = gh->child; tmp; tmp = tmp->sibling)
|
|
|
|
gwinRedraw(tmp);
|
2014-01-05 03:02:03 +00:00
|
|
|
#endif
|
2013-06-07 16:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if GDISP_NEED_TEXT
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinSetFont(GHandle gh, font_t font) {
|
|
|
|
gh->font = font;
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-01-04 03:41:32 +00:00
|
|
|
#if GWIN_NEED_HIERARCHY
|
2014-01-05 03:02:03 +00:00
|
|
|
void gwinAddChild(GHandle parent, GHandle child, bool_t last) {
|
2014-01-04 03:41:32 +00:00
|
|
|
child->parent = parent;
|
|
|
|
child->sibling = NULL;
|
|
|
|
child->child = NULL;
|
|
|
|
|
2014-01-04 20:10:10 +00:00
|
|
|
if (!parent)
|
2014-01-04 03:41:32 +00:00
|
|
|
return;
|
|
|
|
|
2014-01-04 20:10:10 +00:00
|
|
|
if (last && parent->child) {
|
2014-01-04 03:41:32 +00:00
|
|
|
GHandle s = parent->child;
|
2014-01-04 20:10:10 +00:00
|
|
|
while (s->sibling)
|
2014-01-04 15:11:54 +00:00
|
|
|
s = s->sibling;
|
2014-01-04 03:41:32 +00:00
|
|
|
s->sibling = child;
|
|
|
|
} else {
|
|
|
|
child->sibling = parent->child;
|
2014-01-05 03:02:03 +00:00
|
|
|
parent->child = child;
|
2014-01-04 03:41:32 +00:00
|
|
|
}
|
2014-01-05 03:02:03 +00:00
|
|
|
|
2014-01-05 04:05:59 +00:00
|
|
|
// clear the area of the current child position as it will be moved
|
|
|
|
gwinClear(child);
|
|
|
|
|
|
|
|
// window coordinates until now are relative, make them absolute now.
|
|
|
|
child->x += parent->x;
|
|
|
|
child->y += parent->y;
|
2014-01-05 03:02:03 +00:00
|
|
|
|
2014-01-05 04:05:59 +00:00
|
|
|
// redraw the window
|
2014-01-05 03:02:03 +00:00
|
|
|
gwinRedraw(parent);
|
2014-01-04 03:41:32 +00:00
|
|
|
}
|
2014-01-04 20:10:10 +00:00
|
|
|
|
2014-01-05 19:42:19 +00:00
|
|
|
void gwinRemoveChild(GHandle gh) {
|
|
|
|
if(!gh || !gh->parent) {
|
|
|
|
// without a parent, removing is impossible
|
|
|
|
// should log a runtime error here
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gh->parent->child == gh) {
|
|
|
|
// we are the first child, update parent
|
|
|
|
gh->parent->child = gh->sibling;
|
|
|
|
} else {
|
|
|
|
// otherwise find our predecessor
|
|
|
|
GHandle tmp = gh->parent->child;
|
|
|
|
while (tmp && tmp->sibling != gh)
|
|
|
|
tmp = tmp->sibling;
|
|
|
|
|
|
|
|
if(!tmp) {
|
|
|
|
// our parent's children list is corrupted
|
|
|
|
// should log a runtime error here
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp->sibling = gh->sibling;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:43:25 +00:00
|
|
|
void gwinRedrawChildren(GHandle gh) {
|
|
|
|
GHandle tmp;
|
|
|
|
for (tmp = gh->child; tmp; tmp = tmp->sibling)
|
|
|
|
gwinRedraw(tmp);
|
|
|
|
}
|
|
|
|
|
2014-01-04 20:10:10 +00:00
|
|
|
GHandle gwinGetFirstChild(GHandle gh) {
|
|
|
|
return gh->child;
|
|
|
|
}
|
|
|
|
|
|
|
|
GHandle gwinGetNextChild(GHandle gh) {
|
|
|
|
return gh->sibling;
|
|
|
|
}
|
2014-01-04 03:41:32 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
void gwinClear(GHandle gh) {
|
2013-12-18 15:49:49 +00:00
|
|
|
/*
|
|
|
|
* Don't render anything when the window is not visible but
|
2014-01-05 21:37:01 +00:00
|
|
|
* still call tthe AfterClear() routine as some widgets will
|
2013-12-18 15:49:49 +00:00
|
|
|
* need this to clear internal buffers or similar
|
|
|
|
*/
|
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE))) {
|
|
|
|
if (gh->vmt->AfterClear)
|
|
|
|
gh->vmt->AfterClear(gh);
|
|
|
|
} else {
|
2013-06-07 16:27:59 +00:00
|
|
|
|
2014-01-06 23:08:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
|
|
#endif
|
2013-12-18 15:49:49 +00:00
|
|
|
|
2014-01-06 23:08:28 +00:00
|
|
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
|
|
|
if (gh->vmt->AfterClear)
|
|
|
|
gh->vmt->AfterClear(gh);
|
2013-12-18 15:49:49 +00:00
|
|
|
}
|
2014-01-06 23:08:28 +00:00
|
|
|
|
|
|
|
#if GWIN_NEED_HIERARCHY
|
|
|
|
GHandle tmp;
|
|
|
|
for (tmp = gh->child; tmp; tmp = tmp->sibling)
|
|
|
|
gwinClear(tmp);
|
|
|
|
#endif
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawPixel(gh->display, gh->x+x, gh->y+y, gh->color);
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawBox(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillArea(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGBlitArea(gh->display, gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
|
2013-03-02 12:03:40 +00:00
|
|
|
}
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CIRCLE
|
|
|
|
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_ELLIPSE
|
|
|
|
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_ARC
|
|
|
|
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_PIXELREAD
|
|
|
|
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
2013-07-29 06:33:20 +00:00
|
|
|
return defaultBgColor;
|
2013-06-07 16:27:59 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
return gdispGGetPixelColor(gh->display, gh->x+x, gh->y+y);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_TEXT
|
|
|
|
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font)
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CONVEX_POLYGON
|
|
|
|
void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGDrawPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
2013-06-07 16:27:59 +00:00
|
|
|
if (!((gh->flags & GWIN_FLG_VISIBLE)))
|
|
|
|
return;
|
|
|
|
|
2013-03-18 08:29:28 +00:00
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-03-18 08:29:28 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
2013-03-18 08:29:28 +00:00
|
|
|
}
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif
|
|
|
|
|
2013-07-22 07:05:42 +00:00
|
|
|
#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)))
|
|
|
|
return GDISP_IMAGE_ERR_OK;
|
|
|
|
|
|
|
|
#if GDISP_NEED_CLIP
|
2013-10-24 08:36:11 +00:00
|
|
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
2013-07-22 07:05:42 +00:00
|
|
|
#endif
|
2013-10-24 08:36:11 +00:00
|
|
|
return gdispGImageDraw(gh->display, img, gh->x+x, gh->y+y, cx, cy, sx, sy);
|
2013-07-22 07:05:42 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-03-02 12:03:40 +00:00
|
|
|
#endif /* GFX_USE_GWIN */
|
|
|
|
/** @} */
|
|
|
|
|