diff --git a/include/gwin/frame.h b/include/gwin/frame.h index d5272ee6..34ba12ac 100644 --- a/include/gwin/frame.h +++ b/include/gwin/frame.h @@ -33,6 +33,7 @@ typedef struct GFrameObject { GWidgetObject w; + GListener gl; // internal listener for the buttons // These could probably be removed... I have to think harder later GHandle btnClose; GHandle btnMin; @@ -52,6 +53,8 @@ typedef struct GFrameObject { * * @note Possible flags are: GWIN_FRAME_BORDER, GWIN_FRAME_CLOSE_BTN, GWIN_FRAME_MINMAX_BTN. * Whether the close or the minimize maximize buttons are used, the boarder is automatically invoked. + * @note These frame buttons are processed internally. The close button will invoke a gwinDestroy() which will + * destroy the window itself and EVERY child it contains (also children of children). * * @api */ diff --git a/src/gwin/frame.c b/src/gwin/frame.c index 6472663c..a6b957f7 100644 --- a/src/gwin/frame.c +++ b/src/gwin/frame.c @@ -30,6 +30,16 @@ /* Forware declarations */ void gwinFrameDraw_Std(GWidgetObject *gw, void *param); +static void _callbackBtn(void *param, GEvent *pe); + +static void _frameDestroy(GHandle gh) { + /* Detach all button sources */ + // ToDo + //geventDetachSource(&gh2obj->gl, NULL); + + /* call the gwidget standard destroy routine */ + _gwidgetDestroy(gh); +} #if GINPUT_NEED_MOUSE static void _mouseDown(GWidgetObject *gw, coord_t x, coord_t y) { @@ -49,7 +59,7 @@ static const gwidgetVMT frameVMT = { { "Frame", // The classname sizeof(GFrameObject), // The object size - _gwidgetDestroy, // The destroy routine + _frameDestroy, // The destroy routie _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, @@ -99,6 +109,13 @@ GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint /* apply flags */ fo->w.g.flags |= tmp; + /* 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)) { + 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) { GWidgetInit wi; @@ -148,6 +165,26 @@ GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint return (GHandle)fo; } +/* Process a button event */ +static void _callbackBtn(void *param, GEvent *pe) { + switch (pe->type) { + case GEVENT_GWIN_BUTTON: + if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnClose) + gwinDestroy((GHandle)param); + + else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMin) + ;/* ToDo */ + + else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMax) + ;/* ToDo */ + + break; + + default: + break; + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // Default render routines // ///////////////////////////////////////////////////////////////////////////////////////////////////