From 5544202a26da6ec74c51eb1bac9499d434b133ba Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 10 May 2014 18:20:05 +1000 Subject: [PATCH] All compiling. Containers and Frames still to be tested. --- gfxconf.example.h | 1 + src/gwin/class_gwin.h | 8 +-- src/gwin/frame.c | 132 +++++++++++++++++++---------------------- src/gwin/frame.h | 4 +- src/gwin/gcontainer.c | 98 ++++++++++++++++++++++++++++++ src/gwin/gcontainer.h | 14 +++++ src/gwin/gwm.c | 36 +++++++---- src/gwin/sys_options.h | 7 +++ src/gwin/sys_rules.h | 4 +- 9 files changed, 216 insertions(+), 88 deletions(-) diff --git a/gfxconf.example.h b/gfxconf.example.h index cf3f1b2b..93fa4321 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -150,6 +150,7 @@ #define GWIN_PROGRESSBAR_AUTO FALSE #define GWIN_FLAT_STYLING FALSE #define GWIN_NEED_CONTAINERS FALSE + #define GWIN_NEED_CONTAINER FALSE #define GWIN_NEED_FRAME FALSE diff --git a/src/gwin/class_gwin.h b/src/gwin/class_gwin.h index e3b5e2e3..b38b6bb8 100644 --- a/src/gwin/class_gwin.h +++ b/src/gwin/class_gwin.h @@ -121,8 +121,8 @@ typedef struct gwinVMT { */ typedef struct gcontainerVMT { gwidgetVMT gw; - void (*Pos2Screen) (GHandle gh, coord_t *px, coord_t *py); // @< Translate client coords into absolute coords (mandatory) - void (*Size2Screen) (GHandle gh, coord_t *pwidth, coord_t *pheight); // @< Ensure a window fits in the parent client area (mandatory) + void (*AdjustPosition) (GHandle gh, coord_t *px, coord_t *py); // @< The container can adjust the relative position of a child (optional) + void (*AdjustSize) (GHandle gh, coord_t *pwidth, coord_t *pheight); // @< The container can adjust the size of a child (optional) void (*NotifyAdd) (GHandle gh, GHandle ghChild); // @< Notification that a child has been added (optional) void (*NotifyDelete) (GHandle gh, GHandle ghChild); // @< Notification that a child has been deleted (optional) } gcontainerVMT; @@ -274,7 +274,7 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit * * @notapi */ - #define _gcontainerRedraw(gh) _gwidgetRedraw(gh) + void _gcontainerRedraw(GHandle gh); /** * @brief Redraw the Container object after a container status change. @@ -285,7 +285,7 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit * * @notapi */ - #define _gcontainerUpdate(gh) _gwidgetUpdate(gh) + void _gcontainerUpdate(GHandle gh); /** * @brief Apply the specified action to a window and its children. diff --git a/src/gwin/frame.c b/src/gwin/frame.c index 9877b95e..f86bd11b 100644 --- a/src/gwin/frame.c +++ b/src/gwin/frame.c @@ -17,7 +17,7 @@ #include "gfx.h" -#if (GFX_USE_GWIN && GWIN_NEED_FRAME) || defined(__DOXYGEN__) +#if GFX_USE_GWIN && GWIN_NEED_FRAME /* Some values for the default render */ #define BORDER_X 5 @@ -37,11 +37,11 @@ static void _frameDestroy(GHandle gh) { geventRegisterCallback(&gh2obj->gl, NULL, NULL); geventDetachSource(&gh2obj->gl, NULL); - /* call the gwidget standard destroy routine */ - _gwidgetDestroy(gh); + /* call the gcontainer standard destroy routine */ + _gcontainerDestroy(gh); } -#if GINPUT_NEED_MOUSE +#if 0 && GINPUT_NEED_MOUSE static void _mouseDown(GWidgetObject *gw, coord_t x, coord_t y) { } @@ -55,45 +55,49 @@ static void _frameDestroy(GHandle gh) { } #endif -static const gwidgetVMT frameVMT = { +static const gcontainerVMT frameVMT = { { - "Frame", // The classname - sizeof(GFrameObject), // The object size - _frameDestroy, // The destroy routie - _gwidgetRedraw, // The redraw routine - 0, // The after-clear routine + { + "Frame", // The classname + sizeof(GFrameObject), // The object size + _frameDestroy, // The destroy routie + _gcontainerRedraw, // The redraw routine + 0, // The after-clear routine + }, + gwinFrameDraw_Std, // The default drawing routine + #if GINPUT_NEED_MOUSE + { + 0,//_mouseDown, // Process mouse down event + 0,//_mouseUp, // Process mouse up events + 0,//_mouseMove, // Process mouse move events + }, + #endif + #if GINPUT_NEED_TOGGLE + { + 0, // 1 toggle role + 0, // Assign Toggles + 0, // Get Toggles + 0, // Process toggle off events + 0, // Process toggle on events + }, + #endif + #if GINPUT_NEED_DIAL + { + 0, // 1 dial roles + 0, // Assign Dials + 0, // Get Dials + 0, // Process dial move events + }, + #endif }, - gwinFrameDraw_Std, // The default drawing routine - #if GINPUT_NEED_MOUSE - { - _mouseDown, // Process mouse down event - _mouseUp, // Process mouse up events - _mouseMove, // Process mouse move events - }, - #endif - #if GINPUT_NEED_TOGGLE - { - 0, // 1 toggle role - 0, // Assign Toggles - 0, // Get Toggles - 0, // Process toggle off events - 0, // Process toggle on events - }, - #endif - #if GINPUT_NEED_DIAL - { - 0, // 1 dial roles - 0, // Assign Dials - 0, // Get Dials - 0, // Process dial move events - }, - #endif + 0, // Adjust the relative position of a child (optional) + 0, // Adjust the size of a child (optional) + 0, // A child has been added (optional) + 0, // A child has been deleted (optional) }; -GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint16_t flags) { - uint16_t tmp; - - if (!(fo = (GFrameObject *)_gwidgetCreate(g, &fo->w, pInit, &frameVMT))) +GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint32_t flags) { + if (!(fo = (GFrameObject *)_gcontainerCreate(g, &fo->gc, pInit, &frameVMT))) return 0; fo->btnClose = NULL; @@ -101,68 +105,61 @@ GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint fo->btnMax = NULL; /* Buttons require a border */ - tmp = flags; - if ((tmp & GWIN_FRAME_CLOSE_BTN || tmp & GWIN_FRAME_MINMAX_BTN) && !(tmp & GWIN_FRAME_BORDER)) { - tmp |= GWIN_FRAME_BORDER; - } + if ((flags & GWIN_FRAME_CLOSE_BTN || flags & GWIN_FRAME_MINMAX_BTN) && !(flags & GWIN_FRAME_BORDER)) + flags |= GWIN_FRAME_BORDER; /* apply flags */ - fo->w.g.flags |= tmp; + fo->gc.g.flags |= flags; /* create and initialize the listener if any button is present. */ - if ((fo->w.g.flags & GWIN_FRAME_CLOSE_BTN) || (fo->w.g.flags & GWIN_FRAME_MINMAX_BTN)) { + if ((flags & GWIN_FRAME_CLOSE_BTN) || (flags & GWIN_FRAME_MINMAX_BTN)) { geventListenerInit(&fo->gl); gwinAttachListener(&fo->gl); geventRegisterCallback(&fo->gl, _callbackBtn, (GHandle)fo); } /* create close button if necessary */ - if (fo->w.g.flags & GWIN_FRAME_CLOSE_BTN) { + if (flags & GWIN_FRAME_CLOSE_BTN) { GWidgetInit wi; - wi.customDraw = 0; - wi.customParam = 0; - wi.customStyle = 0; + gwinWidgetClearInit(&wi); wi.g.show = TRUE; + wi.g.parent = &fo->gc.g; - wi.g.x = fo->w.g.width - BORDER_X - BUTTON_X; + wi.g.x = fo->gc.g.width - BORDER_X - BUTTON_X; wi.g.y = (BORDER_Y - BUTTON_Y) / 2; wi.g.width = BUTTON_X; wi.g.height = BUTTON_Y; wi.text = "X"; fo->btnClose = gwinButtonCreate(NULL, &wi); - gwinAddChild((GHandle)fo, fo->btnClose, FALSE); } /* create minimize and maximize buttons if necessary */ - if (fo->w.g.flags & GWIN_FRAME_MINMAX_BTN) { + if (flags & GWIN_FRAME_MINMAX_BTN) { GWidgetInit wi; - wi.customDraw = 0; - wi.customParam = 0; - wi.customStyle = 0; + gwinWidgetClearInit(&wi); wi.g.show = TRUE; + wi.g.parent = &fo->gc.g; - wi.g.x = (fo->w.g.flags & GWIN_FRAME_CLOSE_BTN) ? fo->w.g.width - 2*BORDER_X - 2*BUTTON_X : fo->w.g.width - BORDER_X - BUTTON_X; + wi.g.x = (flags & GWIN_FRAME_CLOSE_BTN) ? fo->gc.g.width - 2*BORDER_X - 2*BUTTON_X : fo->gc.g.width - BORDER_X - BUTTON_X; wi.g.y = (BORDER_Y - BUTTON_Y) / 2; wi.g.width = BUTTON_X; wi.g.height = BUTTON_Y; wi.text = "O"; fo->btnMin = gwinButtonCreate(NULL, &wi); - gwinAddChild((GHandle)fo, fo->btnMin, FALSE); - wi.g.x = (fo->w.g.flags & GWIN_FRAME_CLOSE_BTN) ? fo->w.g.width - 3*BORDER_X - 3*BUTTON_X : fo->w.g.width - BORDER_X - BUTTON_X; + wi.g.x = (flags & GWIN_FRAME_CLOSE_BTN) ? fo->gc.g.width - 3*BORDER_X - 3*BUTTON_X : fo->gc.g.width - BORDER_X - BUTTON_X; wi.g.y = (BORDER_Y - BUTTON_Y) / 2; wi.g.width = BUTTON_X; wi.g.height = BUTTON_Y; wi.text = "_"; fo->btnMax = gwinButtonCreate(NULL, &wi); - gwinAddChild((GHandle)fo, fo->btnMax, FALSE); } - gwinSetVisible(&fo->w.g, pInit->g.show); + gwinSetVisible(&fo->gc.g, pInit->g.show); - return (GHandle)fo; + return &fo->gc.g; } /* Process a button event */ @@ -172,11 +169,12 @@ static void _callbackBtn(void *param, GEvent *pe) { if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnClose) gwinDestroy((GHandle)param); - else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMin) + else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMin) { ;/* ToDo */ - else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMax) + } else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMax) { ;/* ToDo */ + } break; @@ -199,7 +197,7 @@ static const GColorSet* _getDrawColors(GWidgetObject *gw) { } void gwinFrameDraw_Std(GWidgetObject *gw, void *param) { - GColorSet *pcol; + const GColorSet *pcol; color_t border; color_t background; (void)param; @@ -230,12 +228,6 @@ void gwinFrameDraw_Std(GWidgetObject *gw, void *param) { gdispGDrawString(gw->g.display, gw->g.x + BORDER_X, gw->g.y + text_y, gw->text, gw->g.font, pcol->text); } - - #if GDISP_NEED_CLIP - gdispGUnsetClip(gw->g.display); - #endif - - gwinRedrawChildren((GHandle)gw); } #endif /* (GFX_USE_GWIN && GWIN_NEED_FRAME) || defined(__DOXYGEN__) */ diff --git a/src/gwin/frame.h b/src/gwin/frame.h index 9d1d63fb..1b20b931 100644 --- a/src/gwin/frame.h +++ b/src/gwin/frame.h @@ -31,7 +31,7 @@ #define GWIN_FRAME_MINMAX_BTN (GWIN_FIRST_CONTROL_FLAG << 2) typedef struct GFrameObject { - GWidgetObject w; + GContainerObject gc; GListener gl; // internal listener for the buttons // These could probably be removed... I have to think harder later @@ -60,7 +60,7 @@ typedef struct GFrameObject { * * @api */ -GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint16_t flags); +GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint32_t flags); #define gwinFrameCreate(fo, pInit, flags) gwinGFrameCreate(GDISP, fo, pInit, flags); #endif /* _GWIN_FRAME_H */ diff --git a/src/gwin/gcontainer.c b/src/gwin/gcontainer.c index 98281183..704c26c0 100644 --- a/src/gwin/gcontainer.c +++ b/src/gwin/gcontainer.c @@ -5,6 +5,16 @@ * http://ugfx.org/license.html */ +/** + * @file src/gwin/gcontainer.c + * @brief GWIN sub-system container code. + * + * @defgroup Containers Containers + * @ingroup GWIN + * + * @{ + */ + #include "gfx.h" #if GFX_USE_GWIN && GWIN_NEED_CONTAINERS @@ -36,6 +46,33 @@ void _gcontainerDestroy(GHandle gh) { _gwidgetDestroy(gh); } +void _gcontainerRedraw(GHandle gh) { + GHandle child; + + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) + return; + + ((GWidgetObject *)gh)->fnDraw((GWidgetObject *)gh, ((GWidgetObject *)gh)->fnParam); + + for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child)) + gwinRedraw(child); +} + +void _gcontainerUpdate(GHandle gh) { + GHandle child; + + if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) + return; + + #if GDISP_NEED_CLIP + gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); + #endif + ((GWidgetObject *)gh)->fnDraw((GWidgetObject *)gh, ((GWidgetObject *)gh)->fnParam); + + for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child)) + gwinRedraw(child); +} + void _gwinRecurse(GHandle gh, bool_t (*fn)(GHandle gh)) { if (fn(gh) && (gh->flags & GWIN_FLG_CONTAINER)) { // Apply to this windows children @@ -69,3 +106,64 @@ GHandle gwinGetSibling(GHandle gh) { #endif /* GFX_USE_GWIN && GWIN_NEED_CONTAINERS */ /** @} */ + +/*----------------------------------------------- + * The simplest container type - a container + *----------------------------------------------- + * + * @defgroup Containers Containers + * @ingroup GWIN + * + * @{ + */ + +#if GFX_USE_GWIN && GWIN_NEED_CONTAINER + +static void DrawSimpleContainer(GWidgetObject *gw, void *param) { + (void) param; + gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background); +} + +// The container VMT table +static const gcontainerVMT containerVMT = { + { + { + "Container", // The classname + sizeof(GContainerObject), // The object size + _gcontainerDestroy, // The destroy routine + _gcontainerRedraw, // The redraw routine + 0, // The after-clear routine + }, + DrawSimpleContainer, // The default drawing routine + #if GINPUT_NEED_MOUSE + { + 0, 0, 0, // No mouse + }, + #endif + #if GINPUT_NEED_TOGGLE + { + 0, 0, 0, 0, 0, // No toggles + }, + #endif + #if GINPUT_NEED_DIAL + { + 0, 0, 0, 0, // No dials + }, + #endif + }, + 0, // Adjust the relative position of a child (optional) + 0, // Adjust the size of a child (optional) + 0, // A child has been added (optional) + 0, // A child has been deleted (optional) +}; + +GHandle gwinGContainerCreate(GDisplay *g, GContainerObject *gw, const GWidgetInit *pInit) { + if (!(gw = (GContainerObject *)_gcontainerCreate(g, gw, pInit, &containerVMT))) + return 0; + + gwinSetVisible((GHandle)gw, pInit->g.show); + return (GHandle)gw; +} + +#endif +/** @} */ diff --git a/src/gwin/gcontainer.h b/src/gwin/gcontainer.h index 61852c7c..8159797c 100644 --- a/src/gwin/gcontainer.h +++ b/src/gwin/gcontainer.h @@ -79,6 +79,20 @@ extern "C" { * @api */ GHandle gwinGetSibling(GHandle gh); + + /** + * @brief Create a simple container. + * @return NULL if there is no resultant drawing area, otherwise a window handle. + * + * @param[in] g The GDisplay to display this window on + * @param[in] gb The GContainerObject structure to initialise. If this is NULL the structure is dynamically allocated. + * @param[in] pInit The initialisation parameters + * + * @api + */ + GHandle gwinGContainerCreate(GDisplay *g, GContainerObject *gw, const GWidgetInit *pInit); + #define gwinContainerCreate(gc, pInit) gwinGContainerCreate(GDISP, gc, pInit) + #ifdef __cplusplus } #endif diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index 682dcb2d..c5e0f956 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -208,15 +208,20 @@ static void WM_Redraw(GHandle gh, int flags) { } static void WM_Size(GHandle gh, coord_t w, coord_t h) { - #if GWIN_NEED_CONTAINERS - // For a child window - convert to absolute size - if (gh->parent) - ((const gcontainerVMT *)gh->parent->vmt)->Size2Screen(gh, &w, &h); - #endif - - // Clip to the screen and give it a minimum size + // Give it a minimum size if (w < MIN_WIN_WIDTH) w = MIN_WIN_WIDTH; if (h < MIN_WIN_HEIGHT) h = MIN_WIN_HEIGHT; + + #if GWIN_NEED_CONTAINERS + if (gh->parent) { + // Clip to the container + if (gh->x+w > gh->parent->x+gh->parent->width) w = gh->parent->x + gh->parent->width - gh->x; + if (gh->y+h > gh->parent->y+gh->parent->height) h = gh->parent->y + gh->parent->height - gh->y; + ((const gcontainerVMT *)gh->parent->vmt)->AdjustSize(gh, &w, &h); + } + #endif + + // Clip to the screen if (gh->x+w > gdispGGetWidth(gh->display)) w = gdispGGetWidth(gh->display) - gh->x; if (gh->y+h > gdispGGetHeight(gh->display)) h = gdispGGetHeight(gh->display) - gh->y; @@ -238,9 +243,20 @@ static void WM_Size(GHandle gh, coord_t w, coord_t h) { static void WM_Move(GHandle gh, coord_t x, coord_t y) { #if GWIN_NEED_CONTAINERS - // For a child window - convert to absolute position - if (gh->parent) - ((const gcontainerVMT *)gh->parent->vmt)->Pos2Screen(gh, &x, &y); + if (gh->parent) { + // Clip to the parent + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x > gh->parent->width-gh->width) x = gh->parent->width-gh->width; + if (y > gh->parent->height-gh->height) y = gh->parent->height-gh->height; + + // Allow the parent to adjust it + ((const gcontainerVMT *)gh->parent->vmt)->AdjustPosition(gh, &x, &y); + + // Convert to absolute position + x += gh->parent->x; + y += gh->parent->y; + } #endif // Clip to the screen diff --git a/src/gwin/sys_options.h b/src/gwin/sys_options.h index 0f3f3f4b..39630de0 100644 --- a/src/gwin/sys_options.h +++ b/src/gwin/sys_options.h @@ -43,6 +43,13 @@ #ifndef GWIN_NEED_WIDGET #define GWIN_NEED_WIDGET FALSE #endif + /** + * @brief Should the simple container be included. + * @details Defaults to FALSE + */ + #ifndef GWIN_NEED_CONTAINER + #define GWIN_NEED_CONTAINER FALSE + #endif /** * @brief Should the frame widget be included. * @details Defaults to FALSE diff --git a/src/gwin/sys_rules.h b/src/gwin/sys_rules.h index ce3b28c7..ddfea3aa 100644 --- a/src/gwin/sys_rules.h +++ b/src/gwin/sys_rules.h @@ -28,10 +28,10 @@ #endif // Objects require their super-class - #if GWIN_NEED_FRAME + #if GWIN_NEED_FRAME || GWIN_NEED_CONTAINER #if !GWIN_NEED_CONTAINERS #if GFX_DISPLAY_RULE_WARNINGS - #warning "GWIN: GWIN_NEED_CONTAINERS is required when GIWN_NEED_FRAME is enabled. It has been turned on for you." + #warning "GWIN: GWIN_NEED_CONTAINERS is required when a container is enabled. It has been turned on for you." #endif #undef GWIN_NEED_CONTAINERS #define GWIN_NEED_CONTAINERS TRUE