aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-08-16 23:35:50 +1000
committerinmarket <andrewh@inmarket.com.au>2014-08-16 23:35:50 +1000
commit362c25f9673f96ade74b9316b3db356c28e66aa6 (patch)
treeb919a2d611c8f410a13d41c64ec4ce4ef3817f79 /src
parent045140a1338cbff569081ad89c06c09ffa216534 (diff)
downloaduGFX-362c25f9673f96ade74b9316b3db356c28e66aa6.tar.gz
uGFX-362c25f9673f96ade74b9316b3db356c28e66aa6.tar.bz2
uGFX-362c25f9673f96ade74b9316b3db356c28e66aa6.zip
Update the simple container to support custom draws such as transparent client area or tiled image client area.
Diffstat (limited to 'src')
-rw-r--r--src/gwin/gcontainer.c75
-rw-r--r--src/gwin/gcontainer.h28
2 files changed, 90 insertions, 13 deletions
diff --git a/src/gwin/gcontainer.c b/src/gwin/gcontainer.c
index 2d711ffd..97b5fabb 100644
--- a/src/gwin/gcontainer.c
+++ b/src/gwin/gcontainer.c
@@ -90,17 +90,9 @@ coord_t gwinGetInnerHeight(GHandle gh) {
#error "GWIN Container: - Flag definitions don't match"
#endif
-static coord_t BorderSize(GHandle gh) { return (gh->flags & GWIN_CONTAINER_BORDER) ? 2 : 0; }
+#define BORDER_WIDTH 2
-static void DrawSimpleContainer(GWidgetObject *gw, void *param) {
- (void)param;
-
- if (!(gw->g.flags & GWIN_CONTAINER_TRANSPARENT))
- gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
-
- if ((gw->g.flags & GWIN_CONTAINER_BORDER))
- gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_SYSENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge);
-}
+static coord_t BorderSize(GHandle gh) { return (gh->flags & GWIN_CONTAINER_BORDER) ? BORDER_WIDTH : 0; }
// The container VMT table
static const gcontainerVMT containerVMT = {
@@ -112,7 +104,7 @@ static const gcontainerVMT containerVMT = {
_gcontainerRedraw, // The redraw routine
0, // The after-clear routine
},
- DrawSimpleContainer, // The default drawing routine
+ gwinContainerDraw_Std, // The default drawing routine
#if GINPUT_NEED_MOUSE
{
0, 0, 0, // No mouse
@@ -141,10 +133,69 @@ GHandle gwinGContainerCreate(GDisplay *g, GContainerObject *gc, const GWidgetIni
if (!(gc = (GContainerObject *)_gcontainerCreate(g, gc, pInit, &containerVMT)))
return 0;
- gc->g.flags |= flags;
+ gc->g.flags |= (flags & GWIN_CONTAINER_BORDER);
gwinSetVisible((GHandle)gc, pInit->g.show);
return (GHandle)gc;
}
+void gwinContainerDraw_Transparent(GWidgetObject *gw, void *param) {
+ (void)param;
+
+ if (gw->g.vmt != (gwinVMT *)&containerVMT)
+ return;
+
+ if ((gw->g.flags & GWIN_CONTAINER_BORDER))
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_SYSENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge);
+
+ // Don't touch the client area
+}
+
+void gwinContainerDraw_Std(GWidgetObject *gw, void *param) {
+ (void)param;
+
+ if (gw->g.vmt != (gwinVMT *)&containerVMT)
+ return;
+
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gwinContainerDraw_Transparent(gw, param);
+}
+
+#if GDISP_NEED_IMAGE
+ void gwinContainerDraw_Image(GWidgetObject *gw, void *param) {
+ #define gi ((gdispImage *)param)
+ coord_t x, y, iw, ih, mx, my;
+
+ if (gw->g.vmt != (gwinVMT *)&containerVMT)
+ return;
+
+ // Draw the frame
+ gwinContainerDraw_Transparent(gw, param);
+
+ // Draw the client area by tiling the image
+ mx = gw->g.x+gw->g.width;
+ my = gw->g.y+gw->g.height;
+ y = gw->g.y;
+ if ((gw->g.flags & GWIN_CONTAINER_BORDER)) {
+ mx--;
+ my--;
+ y++;
+ }
+ for(ih=gi->height; y < my; y += ih) {
+ if (ih > my - y)
+ ih = my - y;
+ x = gw->g.x;
+ if ((gw->g.flags & GWIN_CONTAINER_BORDER))
+ x++;
+ for(iw=gi->width; x < mx; x += iw) {
+ if (iw > mx - x)
+ iw = mx - x;
+ gdispGImageDraw(gw->g.display, gi, x, y, ih, iw, 0, 0);
+ }
+ }
+
+ #undef gi
+ }
+#endif
+
#endif
diff --git a/src/gwin/gcontainer.h b/src/gwin/gcontainer.h
index 942cf8c0..98707ede 100644
--- a/src/gwin/gcontainer.h
+++ b/src/gwin/gcontainer.h
@@ -105,7 +105,6 @@ extern "C" {
* @{
*/
#define GWIN_CONTAINER_BORDER 0x00000001
- #define GWIN_CONTAINER_TRANSPARENT 0x00000002
/** @} */
/**
@@ -122,6 +121,33 @@ extern "C" {
GHandle gwinGContainerCreate(GDisplay *g, GContainerObject *gw, const GWidgetInit *pInit, uint32_t flags);
#define gwinContainerCreate(gc, pInit, flags) gwinGContainerCreate(GDISP, gc, pInit, flags)
+ /**
+ * @brief The custom draw routines for a simple container
+ * @details These function may be passed to @p gwinSetCustomDraw() to get different frame drawing styles
+ *
+ * @param[in] gw The widget object (in this case a frame)
+ * @param[in] param A parameter passed in from the user
+ *
+ * @note In your own custom drawing function you may optionally call these
+ * standard functions and then draw your extra details on top.
+ *
+ * @note gwinContainerDraw_Std() will fill the client area with the background color.<br/>
+ * gwinContainerDraw_Transparent() will not fill the client area at all.<br/>
+ * gwinContainerDraw_Image() will tile the image throughout the client area.<br/>
+ * All these drawing functions draw the frame itself the same way.
+ *
+ * @note The standard functions below ignore the param parameter except for @p gwinContainerDraw_Image().
+ * @note The image custom draw function @p gwinContainerDraw_Image() uses param to pass in the gdispImage pointer.
+ * The image must be already opened before calling @p gwinSetCustomDraw().
+ *
+ * @api
+ * @{
+ */
+ void gwinContainerDraw_Std(GWidgetObject *gw, void *param);
+ void gwinContainerDraw_Transparent(GWidgetObject *gw, void *param);
+ void gwinContainerDraw_Image(GWidgetObject *gw, void *param);
+ /** @} */
+
#ifdef __cplusplus
}
#endif