aboutsummaryrefslogtreecommitdiffstats
path: root/src/gwin
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-05-10 18:20:05 +1000
committerinmarket <andrewh@inmarket.com.au>2014-05-10 18:20:05 +1000
commit5544202a26da6ec74c51eb1bac9499d434b133ba (patch)
tree5533f2b5854270c94e395e6693272735559cf8a0 /src/gwin
parent890653111b978f13b9f168c7308926d7e6a04e6c (diff)
downloaduGFX-5544202a26da6ec74c51eb1bac9499d434b133ba.tar.gz
uGFX-5544202a26da6ec74c51eb1bac9499d434b133ba.tar.bz2
uGFX-5544202a26da6ec74c51eb1bac9499d434b133ba.zip
All compiling.
Containers and Frames still to be tested.
Diffstat (limited to 'src/gwin')
-rw-r--r--src/gwin/class_gwin.h8
-rw-r--r--src/gwin/frame.c130
-rw-r--r--src/gwin/frame.h4
-rw-r--r--src/gwin/gcontainer.c98
-rw-r--r--src/gwin/gcontainer.h14
-rw-r--r--src/gwin/gwm.c34
-rw-r--r--src/gwin/sys_options.h7
-rw-r--r--src/gwin/sys_rules.h4
8 files changed, 213 insertions, 86 deletions
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
- },
- 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
+ "Frame", // The classname
+ sizeof(GFrameObject), // The object size
+ _frameDestroy, // The destroy routie
+ _gcontainerRedraw, // The redraw routine
+ 0, // The after-clear routine
},
- #endif
+ 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
+ },
+ 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) {
+ // 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
- // For a child window - convert to absolute size
- if (gh->parent)
- ((const gcontainerVMT *)gh->parent->vmt)->Size2Screen(gh, &w, &h);
+ 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 and give it a minimum size
- if (w < MIN_WIN_WIDTH) w = MIN_WIN_WIDTH;
- if (h < MIN_WIN_HEIGHT) h = MIN_WIN_HEIGHT;
+ // 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
@@ -44,6 +44,13 @@
#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