aboutsummaryrefslogtreecommitdiffstats
path: root/src/gwin/gwidget.c
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-06-06 14:33:32 +1000
committerinmarket <andrewh@inmarket.com.au>2013-06-06 14:33:32 +1000
commit7baf5c5d448b626d6a062882434b25ca82212d94 (patch)
tree590bea0f81bd4b9e2ebe54c944877ea501e00fa3 /src/gwin/gwidget.c
parenteebecad9f7995dacf3f7c053e3d6b42617ec7294 (diff)
downloaduGFX-7baf5c5d448b626d6a062882434b25ca82212d94.tar.gz
uGFX-7baf5c5d448b626d6a062882434b25ca82212d94.tar.bz2
uGFX-7baf5c5d448b626d6a062882434b25ca82212d94.zip
New simplified gwin using a pseudo class structure.
Diffstat (limited to 'src/gwin/gwidget.c')
-rw-r--r--src/gwin/gwidget.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c
new file mode 100644
index 00000000..464210b7
--- /dev/null
+++ b/src/gwin/gwidget.c
@@ -0,0 +1,254 @@
+/*
+ * This file is subject to the terms of the GFX License, v1.0. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GWIN
+
+#include <string.h>
+
+#include "gwin/class_gwin.h"
+
+/* We use these everywhere in this file */
+#define gw ((GWidgetObject *)gh)
+#define wvmt ((gwidgetVMT *)gh->vmt)
+
+static void gwidgetCallback(void *param, GEvent *pe) {
+ #define gh ((GWindowObject *)param)
+ #define pme ((GEventMouse *)pe)
+ #define pte ((GEventToggle *)pe)
+ #define pde ((GEventDial *)pe)
+
+ // check if widget is disabled
+ if (!(gw->g.flags & GWIN_FLG_ENABLED))
+ return;
+
+ // Process via AllEvents() if it is defined
+ if (wvmt->AllEvents)
+ wvmt->AllEvents(gw, pe);
+
+ // Process various events
+ switch (pe->type) {
+
+ #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
+ case GEVENT_MOUSE:
+ case GEVENT_TOUCH:
+ // Are we captured?
+ if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) {
+ if (pme->meta == GMETA_MOUSE_UP) {
+ gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE;
+ if (wvmt->MouseUp)
+ wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y);
+ return;
+ } else if (wvmt->MouseMove)
+ wvmt->MouseMove(gw, pme->x - gw->g.x, pme->y - gw->g.y);
+
+ // We are not captured - look for mouse downs over the widget
+ } else if (pme->meta == GMETA_MOUSE_DOWN
+ && pme->x >= gw->g.x && pme->x < gw->g.x + gw->g.width
+ && pme->y >= gw->g.y && pme->y < gw->g.y + gw->g.height) {
+ gw->g.flags |= GWIN_FLG_MOUSECAPTURE;
+ if (wvmt->MouseDown)
+ wvmt->MouseDown(gw, pme->x - gw->g.x, pme->y - gw->g.y);
+ }
+ break;
+ #endif
+
+ #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
+ case GEVENT_TOGGLE:
+ if (pte->on) {
+ if (wvmt->ToggleOn)
+ wvmt->ToggleOn(gw, pte->instance);
+ } else {
+ if (wvmt->ToggleOff)
+ wvmt->ToggleOff(gw, pte->instance);
+ }
+ break;
+ #endif
+
+ #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
+ case GEVENT_DIAL:
+ if (wvmt->DialMove)
+ wvmt->DialMove(gw, pde->instance, pde->value);
+ break;
+ #endif
+
+ default:
+ break;
+ }
+ #undef gh
+ #undef pme
+ #undef pte
+ #undef pde
+}
+
+GHandle _gwidgetInit(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwidgetVMT *vmt) {
+ if (!(pgw = (GWidgetObject *)_gwinInit((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt)))
+ return 0;
+
+ pgw->g.flags |= (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED);
+ pgw->txt = "";
+ pgw->fnDraw = vmt->DefaultDraw;
+ pgw->fnParam = 0;
+ geventListenerInit(&pgw->listener);
+ geventRegisterCallback(&pgw->listener, gwidgetCallback, pgw);
+
+ return (GHandle)pgw;
+}
+
+void _gwidgetDestroy(GHandle gh) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return;
+
+ // Deallocate the text (if necessary)
+ if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
+ gh->flags &= ~GWIN_FLG_ALLOCTXT;
+ gfxFree((void *)gw->txt);
+ }
+ // Untangle the listeners (both on us and to us).
+ geventDetachSource(&gw->listener, 0);
+ geventDetachSourceListeners((GSourceHandle)gh);
+ gh->flags &= ~GWIN_FLG_WIDGET;
+}
+
+void gwinSetEnabled(GHandle gh, bool_t enabled) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return;
+
+ if (enabled)
+ gh->flags |= GWIN_FLG_ENABLED;
+ else
+ gh->flags &= ~GWIN_FLG_ENABLED;
+}
+
+void gwinDraw(GHandle gh) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return;
+
+ #if GDISP_NEED_CLIP
+ gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ #endif
+
+ gw->fnDraw(gw, gw->fnParam);
+}
+
+void gwinSetText(GHandle gh, const char *txt, bool_t useAlloc) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return;
+
+ // Dispose of the old string
+ if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
+ gh->flags &= ~GWIN_FLG_ALLOCTXT;
+ if (gw->txt) {
+ gfxFree((void *)gw->txt);
+ gw->txt = "";
+ }
+ }
+
+ // Alloc the new text if required
+ if (txt && !*txt) txt = 0;
+ if (txt && useAlloc) {
+ char *str;
+
+ if ((str = (char *)gfxAlloc(strlen(txt)+1))) {
+ gh->flags |= GWIN_FLG_ALLOCTXT;
+ strcpy(str, txt);
+ }
+ txt = (const char *)str;
+ }
+
+ gw->txt = txt ? txt : "";
+}
+
+const char *gwinGetText(GHandle gh) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return 0;
+
+ return gw->txt;
+}
+
+void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return;
+
+ gw->fnDraw = fn ? fn : wvmt->DefaultDraw;
+ gw->fnParam = param;
+}
+
+bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) {
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return FALSE;
+
+ return geventAttachSource(pl, (GSourceHandle)gh, flags);
+}
+
+#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
+ bool_t gwinAttachMouse(GHandle gh, uint16_t instance) {
+ GSourceHandle gsh;
+ unsigned flags;
+
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return FALSE;
+
+ if (!wvmt->MouseDown && !wvmt->MouseMove && !wvmt->MouseUp)
+ return FALSE;
+
+ if (!(gsh = ginputGetMouse(instance)))
+ return FALSE;
+
+ flags = wvmt->MouseMove ? (GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES) : GLISTEN_MOUSEMETA;
+ return geventAttachSource(&gw->listener, gsh, flags);
+ }
+#endif
+
+#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
+ bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance) {
+ GSourceHandle gsh;
+ unsigned flags;
+
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return FALSE;
+
+ flags = 0;
+ if (wvmt->ToggleOff) flags |= GLISTEN_TOGGLE_OFF;
+ if (wvmt->ToggleOn) flags |= GLISTEN_TOGGLE_ON;
+ if (!flags)
+ return FALSE;
+
+ if (!(gsh = ginputGetToggle(instance)))
+ return FALSE;
+
+ if (wvmt->AssignToggle && !wvmt->AssignToggle(gw, role, instance))
+ return FALSE;
+
+ return geventAttachSource(&gw->listener, gsh, flags);
+ }
+#endif
+
+#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
+ bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance) {
+ GSourceHandle gsh;
+
+ if (!(gh->flags & GWIN_FLG_WIDGET))
+ return FALSE;
+
+ if (!wvmt->DialMove)
+ return FALSE;
+
+ if (!(gsh = ginputGetDial(instance)))
+ return FALSE;
+
+ if (wvmt->AssignDial && !wvmt->AssignDial(gw, role, instance))
+ return FALSE;
+
+ return geventAttachSource(&gw->listener, gsh, 0);
+ }
+#endif
+
+#endif /* GFX_USE_GWIN */
+/** @} */
+