2014-01-06 20:20:35 +00:00
|
|
|
/*
|
|
|
|
* This file is subject to the terms of the GFX License. If a copy of
|
|
|
|
* the license was not distributed with this file, you can obtain one at:
|
|
|
|
*
|
|
|
|
* http://ugfx.org/license.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file src/gwin/frame.c
|
|
|
|
* @brief GWIN sub-system frame code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "gfx.h"
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
#if GFX_USE_GWIN && GWIN_NEED_FRAME
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-11 10:11:16 +00:00
|
|
|
#include "src/gwin/class_gwin.h"
|
|
|
|
|
|
|
|
#if GWIN_FRAME_BORDER != GWIN_FIRST_CONTROL_FLAG
|
|
|
|
#error "GWIN Frame: - Flag definitions don't match"
|
|
|
|
#endif
|
|
|
|
|
2014-01-06 20:20:35 +00:00
|
|
|
/* Some values for the default render */
|
|
|
|
#define BORDER_X 5
|
|
|
|
#define BORDER_Y 30
|
|
|
|
#define BUTTON_X 20
|
|
|
|
#define BUTTON_Y 20
|
|
|
|
|
|
|
|
/* Some useful macros for data type conversions */
|
|
|
|
#define gh2obj ((GFrameObject *)gh)
|
|
|
|
|
|
|
|
/* Forware declarations */
|
2014-05-11 10:11:16 +00:00
|
|
|
static void gwinFrameDraw_Std(GWidgetObject *gw, void *param);
|
2014-01-07 00:24:54 +00:00
|
|
|
static void _callbackBtn(void *param, GEvent *pe);
|
|
|
|
|
2014-05-11 10:11:16 +00:00
|
|
|
static coord_t BorderSizeLRB(GHandle gh) { return (gh->flags & GWIN_FRAME_BORDER) ? BORDER_X : 0; }
|
|
|
|
static coord_t BorderSizeT(GHandle gh) { return (gh->flags & GWIN_FRAME_BORDER) ? BORDER_Y : 0; }
|
|
|
|
|
2014-01-07 00:24:54 +00:00
|
|
|
static void _frameDestroy(GHandle gh) {
|
2014-01-07 22:59:06 +00:00
|
|
|
/* Deregister the button callback */
|
2014-07-16 06:42:37 +00:00
|
|
|
if ((gh->flags & (GWIN_FRAME_CLOSE_BTN|GWIN_FRAME_MINMAX_BTN))) {
|
2014-07-15 03:47:12 +00:00
|
|
|
geventRegisterCallback(&gh2obj->gl, NULL, NULL);
|
|
|
|
geventDetachSource(&gh2obj->gl, NULL);
|
|
|
|
}
|
2014-01-07 00:24:54 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
/* call the gcontainer standard destroy routine */
|
|
|
|
_gcontainerDestroy(gh);
|
2014-01-07 00:24:54 +00:00
|
|
|
}
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-29 23:11:25 +00:00
|
|
|
static void _closeBtnDraw(struct GWidgetObject *gw, void *param) {
|
2014-05-30 02:45:19 +00:00
|
|
|
(void) param;
|
|
|
|
|
2014-05-29 23:11:25 +00:00
|
|
|
// the background
|
|
|
|
if (gwinButtonIsPressed( (GHandle)gw)) {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gdispBlendColor(Black, HTML2COLOR(0xC55152), 50));
|
|
|
|
} else {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, HTML2COLOR(0xC55152));
|
|
|
|
}
|
|
|
|
|
|
|
|
// the cross
|
|
|
|
gdispDrawLine(gw->g.x+4, gw->g.y+4, gw->g.x+gw->g.width-5, gw->g.y+gw->g.height-5, White);
|
|
|
|
gdispDrawLine(gw->g.x+gw->g.width-5, gw->g.y+4, gw->g.x+4, gw->g.y+gw->g.height-5, White);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _closeBtnMin(struct GWidgetObject *gw, void *param) {
|
2014-05-30 02:45:19 +00:00
|
|
|
(void) param;
|
|
|
|
|
2014-05-29 23:11:25 +00:00
|
|
|
// the background
|
|
|
|
if (gwinButtonIsPressed( (GHandle)gw)) {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gdispBlendColor(Black, Grey, 50));
|
|
|
|
} else {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gdispBlendColor(White, Grey, 50));
|
|
|
|
}
|
|
|
|
|
|
|
|
// the symbol
|
|
|
|
gdispDrawLine(gw->g.x+5, gw->g.y+gw->g.height-5, gw->g.x+gw->g.width-5, gw->g.y+gw->g.height-5, White);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _closeBtnMax(struct GWidgetObject *gw, void *param) {
|
2014-05-30 02:45:19 +00:00
|
|
|
(void) param;
|
|
|
|
|
2014-05-29 23:11:25 +00:00
|
|
|
// the background
|
|
|
|
if (gwinButtonIsPressed( (GHandle)gw)) {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gdispBlendColor(Black, Grey, 50));
|
|
|
|
} else {
|
|
|
|
gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gdispBlendColor(White, Grey, 50));
|
|
|
|
}
|
|
|
|
|
|
|
|
// the symbol
|
|
|
|
gdispDrawBox(gw->g.x+4, gw->g.y+4, gw->g.width-8, gw->g.height-8, White);
|
|
|
|
gdispDrawLine(gw->g.x+4, gw->g.y+5, gw->g.x+gw->g.width-5, gw->g.y+5, White);
|
|
|
|
gdispDrawLine(gw->g.x+4, gw->g.y+6, gw->g.x+gw->g.width-5, gw->g.y+6, White);
|
|
|
|
}
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
#if 0 && GINPUT_NEED_MOUSE
|
2014-02-01 21:42:30 +00:00
|
|
|
static void _mouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _mouseUp(GWidgetObject *gw, coord_t x, coord_t y) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _mouseMove(GWidgetObject *gw, coord_t x, coord_t y) {
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
static const gcontainerVMT frameVMT = {
|
2014-01-06 20:20:35 +00:00
|
|
|
{
|
2014-02-01 21:42:30 +00:00
|
|
|
{
|
2014-05-10 08:20:05 +00:00
|
|
|
"Frame", // The classname
|
|
|
|
sizeof(GFrameObject), // The object size
|
|
|
|
_frameDestroy, // The destroy routie
|
|
|
|
_gcontainerRedraw, // The redraw routine
|
|
|
|
0, // The after-clear routine
|
2014-02-01 21:42:30 +00:00
|
|
|
},
|
2014-05-10 08:20:05 +00:00
|
|
|
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
|
|
|
|
},
|
2014-05-11 10:11:16 +00:00
|
|
|
BorderSizeLRB, // The size of the left border (mandatory)
|
|
|
|
BorderSizeT, // The size of the top border (mandatory)
|
|
|
|
BorderSizeLRB, // The size of the right border (mandatory)
|
|
|
|
BorderSizeLRB, // The size of the bottom border (mandatory)
|
2014-05-10 08:20:05 +00:00
|
|
|
0, // A child has been added (optional)
|
|
|
|
0, // A child has been deleted (optional)
|
2014-01-06 20:20:35 +00:00
|
|
|
};
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
GHandle gwinGFrameCreate(GDisplay *g, GFrameObject *fo, GWidgetInit *pInit, uint32_t flags) {
|
|
|
|
if (!(fo = (GFrameObject *)_gcontainerCreate(g, &fo->gc, pInit, &frameVMT)))
|
2014-01-06 20:20:35 +00:00
|
|
|
return 0;
|
|
|
|
|
2014-05-11 03:09:36 +00:00
|
|
|
fo->btnClose = 0;
|
|
|
|
fo->btnMin = 0;
|
|
|
|
fo->btnMax = 0;
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-02-01 21:42:30 +00:00
|
|
|
/* Buttons require a border */
|
2014-05-11 03:09:36 +00:00
|
|
|
if ((flags & (GWIN_FRAME_CLOSE_BTN|GWIN_FRAME_MINMAX_BTN)))
|
2014-05-10 08:20:05 +00:00
|
|
|
flags |= GWIN_FRAME_BORDER;
|
2014-02-01 21:42:30 +00:00
|
|
|
|
2014-01-07 00:24:54 +00:00
|
|
|
/* create and initialize the listener if any button is present. */
|
2014-05-11 03:09:36 +00:00
|
|
|
if ((flags & (GWIN_FRAME_CLOSE_BTN|GWIN_FRAME_MINMAX_BTN))) {
|
2014-01-07 00:24:54 +00:00
|
|
|
geventListenerInit(&fo->gl);
|
|
|
|
gwinAttachListener(&fo->gl);
|
|
|
|
geventRegisterCallback(&fo->gl, _callbackBtn, (GHandle)fo);
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:20:35 +00:00
|
|
|
/* create close button if necessary */
|
2014-05-11 03:09:36 +00:00
|
|
|
if ((flags & GWIN_FRAME_CLOSE_BTN)) {
|
2014-01-06 20:20:35 +00:00
|
|
|
GWidgetInit wi;
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
gwinWidgetClearInit(&wi);
|
2014-01-06 20:20:35 +00:00
|
|
|
wi.g.show = TRUE;
|
2014-05-10 08:20:05 +00:00
|
|
|
wi.g.parent = &fo->gc.g;
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
wi.g.x = fo->gc.g.width - BORDER_X - BUTTON_X;
|
2014-01-06 20:20:35 +00:00
|
|
|
wi.g.y = (BORDER_Y - BUTTON_Y) / 2;
|
|
|
|
wi.g.width = BUTTON_X;
|
|
|
|
wi.g.height = BUTTON_Y;
|
2014-05-29 23:11:25 +00:00
|
|
|
wi.text = "Frame Close Button";
|
|
|
|
wi.customDraw = _closeBtnDraw;
|
2014-05-11 03:09:36 +00:00
|
|
|
fo->btnClose = gwinGButtonCreate(g, 0, &wi);
|
2014-01-06 20:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* create minimize and maximize buttons if necessary */
|
2014-05-11 03:09:36 +00:00
|
|
|
if ((flags & GWIN_FRAME_MINMAX_BTN)) {
|
2014-01-06 20:20:35 +00:00
|
|
|
GWidgetInit wi;
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
gwinWidgetClearInit(&wi);
|
2014-01-06 20:20:35 +00:00
|
|
|
wi.g.show = TRUE;
|
2014-05-10 08:20:05 +00:00
|
|
|
wi.g.parent = &fo->gc.g;
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
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;
|
2014-01-06 20:20:35 +00:00
|
|
|
wi.g.y = (BORDER_Y - BUTTON_Y) / 2;
|
|
|
|
wi.g.width = BUTTON_X;
|
|
|
|
wi.g.height = BUTTON_Y;
|
2014-05-29 23:11:25 +00:00
|
|
|
wi.text = "Frame Max Button";
|
|
|
|
wi.customDraw = _closeBtnMax;
|
|
|
|
fo->btnMax = gwinGButtonCreate(g, 0, &wi);
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
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;
|
2014-01-06 20:20:35 +00:00
|
|
|
wi.g.y = (BORDER_Y - BUTTON_Y) / 2;
|
|
|
|
wi.g.width = BUTTON_X;
|
|
|
|
wi.g.height = BUTTON_Y;
|
2014-05-29 23:11:25 +00:00
|
|
|
wi.text = "Frame Min Button";
|
|
|
|
wi.customDraw = _closeBtnMin;
|
|
|
|
fo->btnMin = gwinGButtonCreate(g, 0, &wi);
|
2014-01-06 20:20:35 +00:00
|
|
|
}
|
|
|
|
|
2014-05-11 10:11:16 +00:00
|
|
|
/* Apply flags. We apply these here so the controls above are outside the child area */
|
|
|
|
fo->gc.g.flags |= flags;
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
gwinSetVisible(&fo->gc.g, pInit->g.show);
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
return &fo->gc.g;
|
2014-01-06 20:20:35 +00:00
|
|
|
}
|
|
|
|
|
2014-01-07 00:24:54 +00:00
|
|
|
/* 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)
|
2014-05-30 00:57:30 +00:00
|
|
|
gwinDestroy((GHandle)param);
|
2014-01-07 00:24:54 +00:00
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMin) {
|
2014-01-07 00:24:54 +00:00
|
|
|
;/* ToDo */
|
|
|
|
|
2014-05-10 08:20:05 +00:00
|
|
|
} else if (((GEventGWinButton *)pe)->button == ((GFrameObject*)(GHandle)param)->btnMax) {
|
2014-01-07 00:24:54 +00:00
|
|
|
;/* ToDo */
|
2014-05-10 08:20:05 +00:00
|
|
|
}
|
2014-01-07 00:24:54 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:20:35 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2014-02-01 21:42:30 +00:00
|
|
|
// Default render routines //
|
2014-01-06 20:20:35 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-02-01 21:42:30 +00:00
|
|
|
static const GColorSet* _getDrawColors(GWidgetObject *gw) {
|
2014-05-09 15:11:30 +00:00
|
|
|
if (!(gw->g.flags & GWIN_FLG_SYSENABLED))
|
2014-02-01 21:42:30 +00:00
|
|
|
return &gw->pstyle->disabled;
|
|
|
|
//if ((gw->g.flags & GBUTTON_FLG_PRESSED))
|
|
|
|
// return &gw->pstyle->pressed;
|
|
|
|
|
|
|
|
return &gw->pstyle->enabled;
|
|
|
|
}
|
|
|
|
|
2014-05-11 10:11:16 +00:00
|
|
|
static void gwinFrameDraw_Std(GWidgetObject *gw, void *param) {
|
2014-05-10 08:20:05 +00:00
|
|
|
const GColorSet *pcol;
|
2014-02-01 21:42:30 +00:00
|
|
|
(void)param;
|
2014-01-06 20:20:35 +00:00
|
|
|
|
2014-02-01 21:42:30 +00:00
|
|
|
if (gw->g.vmt != (gwinVMT *)&frameVMT)
|
2014-01-06 20:20:35 +00:00
|
|
|
return;
|
|
|
|
|
2014-02-01 21:42:30 +00:00
|
|
|
pcol = _getDrawColors(gw);
|
|
|
|
|
2014-01-06 20:53:43 +00:00
|
|
|
// Render the actual frame (with border, if any)
|
2014-02-01 21:42:30 +00:00
|
|
|
if (gw->g.flags & GWIN_FRAME_BORDER) {
|
2014-05-11 10:11:16 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x + BORDER_X, gw->g.y + BORDER_Y, gw->g.width - 2*BORDER_X, gw->g.height - BORDER_Y - BORDER_X, gw->pstyle->background);
|
|
|
|
gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, BORDER_Y, gw->text, gw->g.font, gdispContrastColor(pcol->edge), pcol->edge, justifyCenter);
|
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+BORDER_Y, BORDER_X, gw->g.height-(BORDER_Y+BORDER_X), pcol->edge);
|
|
|
|
gdispGFillArea(gw->g.display, gw->g.x+gw->g.width-BORDER_X, gw->g.y+BORDER_Y, BORDER_X, gw->g.height-(BORDER_Y+BORDER_X), pcol->edge);
|
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gw->g.height-BORDER_X, gw->g.width, BORDER_X, pcol->edge);
|
2014-01-06 20:20:35 +00:00
|
|
|
} else {
|
2014-05-11 10:11:16 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
|
2014-01-06 20:53:43 +00:00
|
|
|
}
|
2014-01-06 20:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* (GFX_USE_GWIN && GWIN_NEED_FRAME) || defined(__DOXYGEN__) */
|