aboutsummaryrefslogtreecommitdiffstats
path: root/src/gwin/checkbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gwin/checkbox.c')
-rw-r--r--src/gwin/checkbox.c264
1 files changed, 137 insertions, 127 deletions
diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c
index faea0ef9..84eb3b9f 100644
--- a/src/gwin/checkbox.c
+++ b/src/gwin/checkbox.c
@@ -7,7 +7,7 @@
/**
* @file src/gwin/checkbox.c
- * @brief GWIN sub-system checkbox code.
+ * @brief GWIN sub-system button code.
*
* @defgroup Checkbox Checkbox
* @ingroup GWIN
@@ -19,168 +19,178 @@
#if (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) || defined(__DOXYGEN__)
-static const GCheckboxColor defaultColors = {
- Grey, // border
- Grey, // selected
- Black // background
-};
-
-/* default style drawing routine */
-static void gwinCheckboxDrawDefaultStyle(GHandle gh, bool_t enabled, bool_t isChecked, void* param) {
- #define gcw ((GCheckboxObject *)gh)
+#include "gwin/class_gwin.h"
- (void) enabled;
- (void) param;
+// Our checked state
+#define GCHECKBOX_FLG_CHECKED (GWIN_FIRST_CONTROL_FLAG<<0)
- gdispDrawBox(gh->x, gh->y, gh->width, gh->height, gcw->colors->border);
+// Send the checkbox event
+static void SendCheckboxEvent(GWidgetObject *gw) {
+ GSourceListener * psl;
+ GEvent * pe;
+ #define pce ((GEventGWinCheckbox *)pe)
- if (isChecked)
- gdispFillArea(gh->x+2, gh->y+2, gh->width-4, gh->height-4, gcw->colors->checked);
- else
- gdispFillArea(gh->x+2, gh->y+2, gh->width-4, gh->height-4, gcw->colors->bg);
+ // Trigger a GWIN Checkbox Event
+ psl = 0;
+ while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
+ if (!(pe = geventGetEventBuffer(psl)))
+ continue;
+ pce->type = GEVENT_GWIN_CHECKBOX;
+ pce->checkbox = &gw->g;
+ pce->isChecked = (gw->g.flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE;
+ geventSendEvent(psl);
+ }
- #undef gcw
+ #undef pce
}
-/* process an event callback */
-static void gwinCheckboxCallback(void *param, GEvent *pe) {
- GSourceListener *psl;
- #define gh ((GHandle)param)
- #define gbw ((GCheckboxObject *)param)
- #define gsh ((GSourceHandle)param)
- #define pme ((GEventMouse *)pe)
- #define pte ((GEventTouch *)pe)
- #define pxe ((GEventToggle *)pe)
- #define pbe ((GEventGWinCheckbox *)pe)
-
- /* check if checkbox is disabled */
- if (!gh->enabled)
- return;
-
- switch (pe->type) {
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- case GEVENT_MOUSE:
- case GEVENT_TOUCH:
-
- // Ignore anything other than the primary mouse button going up or down
- if (!((pme->current_buttons ^ pme->last_buttons) & GINPUT_MOUSE_BTN_LEFT))
- return;
-
- if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)
- && pme->x >= gbw->gwin.x && pme->x < gbw->gwin.x + gbw->gwin.width
- && pme->y >= gbw->gwin.y && pme->y < gbw->gwin.y + gbw->gwin.height) {
+#if GINPUT_NEED_MOUSE
+ static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
+ (void) x; (void) y;
+ gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
+ _gwidgetRedraw((GHandle)gw);
+ SendCheckboxEvent(gw);
+ }
+#endif
- gbw->isChecked = !gbw->isChecked;
+#if GINPUT_NEED_TOGGLE
+ static void ToggleOn(GWidgetObject *gw, uint16_t role) {
+ (void) role;
+ gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
+ _gwidgetRedraw((GHandle)gw);
+ SendCheckboxEvent(gw);
+ }
- gwinCheckboxDraw((GHandle)param);
- break;
- }
- return;
- #endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
+ static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
+ (void) role;
+ ((GCheckboxObject *)gw)->toggle = instance;
+ }
- default:
- return;
+ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
+ (void) role;
+ return ((GCheckboxObject *)gw)->toggle;
}
+#endif
- // Trigger a GWIN checkbox event
- psl = 0;
- while ((psl = geventGetSourceListener(gsh, psl))) {
- if (!(pe = geventGetEventBuffer(psl)))
- continue;
- pbe->type = GEVENT_GWIN_CHECKBOX;
- pbe->checkbox = gh;
- pbe->isChecked = gbw->isChecked;
- geventSendEvent(psl);
- }
-
- #undef gh
- #undef pbe
- #undef pme
- #undef pte
- #undef pxe
- #undef gsh
- #undef gbw
-}
+// The checkbox VMT table
+static const gwidgetVMT checkboxVMT = {
+ {
+ "Checkbox", // The classname
+ sizeof(GCheckboxObject),// The object size
+ _gwidgetDestroy, // The destroy routine
+ _gwidgetRedraw, // The redraw routine
+ 0, // The after-clear routine
+ },
+ gwinCheckboxDraw_CheckOnLeft, // The default drawing routine
+ #if GINPUT_NEED_MOUSE
+ {
+ MouseDown, // Process mouse down events
+ 0, // Process mouse up events (NOT USED)
+ 0, // Process mouse move events (NOT USED)
+ },
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ {
+ 1, // 1 toggle role
+ ToggleAssign, // Assign Toggles
+ ToggleGet, // Get Toggles
+ 0, // Process toggle off events (NOT USED)
+ ToggleOn, // Process toggle on events
+ },
+ #endif
+ #if GINPUT_NEED_DIAL
+ {
+ 0, // No dial roles
+ 0, // Assign Dials (NOT USED)
+ 0, // Get Dials (NOT USED)
+ 0, // Process dial move events (NOT USED)
+ },
+ #endif
+};
-GHandle gwinCheckboxCreate(GCheckboxObject *gb, coord_t x, coord_t y, coord_t width, coord_t height) {
- if (!(gb = (GCheckboxObject *)_gwinInit((GWindowObject *)gb, x, y, width, height, sizeof(GCheckboxObject))))
+GHandle gwinCheckboxCreate(GCheckboxObject *gb, const GWidgetInit *pInit) {
+ if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT)))
return 0;
- gb->gwin.type = GW_CHECKBOX; // create a window of the type checkbox
- gb->fn = gwinCheckboxDrawDefaultStyle; // set the default style drawing routine
- gb->colors = &defaultColors; // asign the default colors
- gb->param = 0; // some safe value here
- gb->isChecked = GCHBX_UNCHECKED; // checkbox is currently unchecked
- gb->gwin.enabled = TRUE; // checkboxes are enabled by default
-
- geventListenerInit(&gb->listener);
- geventRegisterCallback(&gb->listener, gwinCheckboxCallback, gb);
-
- // checkboxes are enabled by default
- gb->gwin.enabled = TRUE;
-
+ #if GINPUT_NEED_TOGGLE
+ gb->toggle = GWIDGET_NO_INSTANCE;
+ #endif
+ gwinSetVisible((GHandle)gb, pInit->g.show);
return (GHandle)gb;
}
-void gwinCheckboxSetCustom(GHandle gh, GCheckboxDrawFunction fn, void *param) {
- #define gcw ((GCheckboxObject *)gh)
-
- if (gh->type != GW_CHECKBOX)
+void gwinCheckboxCheck(GHandle gh, bool_t isChecked) {
+ if (gh->vmt != (gwinVMT *)&checkboxVMT)
return;
- gcw->fn = fn;
- gcw->param = param;
-
- #undef gcw
+ if (isChecked) {
+ if ((gh->flags & GCHECKBOX_FLG_CHECKED)) return;
+ gh->flags |= GCHECKBOX_FLG_CHECKED;
+ } else {
+ if (!(gh->flags & GCHECKBOX_FLG_CHECKED)) return;
+ gh->flags &= ~GCHECKBOX_FLG_CHECKED;
+ }
+ _gwidgetRedraw(gh);
+ SendCheckboxEvent((GWidgetObject *)gh);
}
+bool_t gwinCheckboxIsChecked(GHandle gh) {
+ if (gh->vmt != (gwinVMT *)&checkboxVMT)
+ return FALSE;
-void gwinCheckboxSetEnabled(GHandle gh, bool_t enabled) {
- if (gh->type != GW_CHECKBOX)
- return;
+ return (gh->flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE;
+}
+
+/*----------------------------------------------------------
+ * Custom Draw Routines
+ *----------------------------------------------------------*/
- gh->enabled = enabled;
+static const GColorSet *getDrawColors(GWidgetObject *gw) {
+ if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &gw->pstyle->disabled;
+ if ((gw->g.flags & GCHECKBOX_FLG_CHECKED)) return &gw->pstyle->pressed;
+ return &gw->pstyle->enabled;
}
-void gwinCheckboxDraw(GHandle gh) {
- #define gcw ((GCheckboxObject *)gh)
+void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param) {
+ #define gcw ((GCheckboxObject *)gw)
+ coord_t ld, df;
+ const GColorSet * pcol;
+ (void) param;
- if (gh->type != GW_CHECKBOX)
- return;
+ if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
+ pcol = getDrawColors(gw);
- #if GDISP_NEED_CLIP
- //gdispSetClip(gh->x, gh->y, gh->width, gh->height);
- #endif
+ ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
+ gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
+ gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->edge);
- gcw->fn(gh,
- gcw->gwin.enabled,
- gcw->isChecked,
- gcw->param);
+ df = ld < 4 ? 1 : 2;
+ if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
+ gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
+ gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
#undef gcw
}
-#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- bool_t gwinCheckboxAttachMouse(GHandle gh, uint16_t instance) {
- GSourceHandle gsh;
+void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
+ #define gcw ((GCheckboxObject *)gw)
+ coord_t ep, ld, df;
+ const GColorSet * pcol;
+ (void) param;
- if (gh->type != GW_CHECKBOX || !(gsh = ginputGetMouse(instance)))
- return FALSE;
+ if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
+ pcol = getDrawColors(gw);
- return geventAttachSource(&((GCheckboxObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA);
- }
-#endif
-
-void gwinCheckboxSetColors(GHandle gh, color_t border, color_t checked, color_t bg) {
- #define gcw ((GCheckboxObject *)gh)
-
- if (gh->type != GW_CHECKBOX)
- return;
+ ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
+ ep = gw->g.width-ld-1;
+ gdispFillArea(gw->g.x+ep-1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
+ gdispDrawBox(gw->g.x+ep, gw->g.y, ld, ld, pcol->edge);
- gcw->colors->border = border;
- gcw->colors->checked = checked,
- gcw->colors->bg = bg;
+ df = ld < 4 ? 1 : 2;
+ if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
+ gdispFillArea(gw->g.x+ep+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
+ gdispFillStringBox(gw->g.x, gw->g.y, ep, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyRight);
#undef gcw
}