diff options
Diffstat (limited to 'src/gwin/checkbox.c')
-rw-r--r-- | src/gwin/checkbox.c | 264 |
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 } |