ugfx/src/gwin/checkbox.c

160 lines
4.5 KiB
C

/*
* 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
*/
/**
* @file src/gwin/checkbox.c
* @brief GWIN sub-system button code.
*
* @defgroup Checkbox Checkbox
* @ingroup GWIN
*
* @{
*/
#include "gfx.h"
#if (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) || defined(__DOXYGEN__)
#include "gwin/class_gwin.h"
// Our checked state
#define GCHECKBOX_FLG_CHECKED (GWIN_FIRST_CONTROL_FLAG<<0)
// Prototypes for button VMT functions
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y);
static void ToggleOn(GWidgetObject *gw, uint16_t instance);
// The button VMT table
static const gwidgetVMT checkboxVMT = {
{
"Checkbox", // The classname
_gwidgetDestroy, // The destroy routine
_gwidgetRedraw, // The redraw routine
0, // The after-clear routine
},
gwinCheckboxDraw_CheckOnLeft, // The default drawing routine
MouseDown, // Process mouse down events
0, // Process mouse up events (NOT USED)
0, // Process mouse move events (NOT USED)
0, // Process toggle off events (NOT USED)
ToggleOn, // Process toggle on events
0, // Process dial move events (NOT USED)
0, // Process all events (NOT USED)
0, // AssignToggle (NOT USED)
0, // AssignDial (NOT USED)
};
static const GCheckboxColors defaultColors = {
Black, // border
Grey, // selected
White, // background
Black, // text
};
// Send the checkbox event
static void SendCheckboxEvent(GWidgetObject *gw) {
GSourceListener * psl;
GEvent * pe;
#define pce ((GEventGWinCheckbox *)pe)
// Trigger a GWIN Checkbox Event
psl = 0;
while ((psl = geventGetSourceListener((GSourceHandle)gw, 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 pce
}
// A mouse down has occurred over the checkbox
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);
}
// A toggle on has occurred
static void ToggleOn(GWidgetObject *gw, uint16_t instance) {
(void) instance;
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
_gwidgetRedraw((GHandle)gw);
SendCheckboxEvent(gw);
}
GHandle gwinCreateCheckbox(GCheckboxObject *gb, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gb = (GCheckboxObject *)_gwidgetInit((GWidgetObject *)gb, x, y, width, height, sizeof(GCheckboxObject), &checkboxVMT)))
return 0;
gb->c = defaultColors; // assign the default colors
return (GHandle)gb;
}
bool_t gwinIsCheckboxChecked(GHandle gh) {
if (gh->vmt != (gwinVMT *)&checkboxVMT)
return FALSE;
return (gh->flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE;
}
void gwinCheckboxSetColors(GHandle gh, GCheckboxColors *pColors) {
if (gh->vmt != (gwinVMT *)&checkboxVMT)
return;
((GCheckboxObject *)gh)->c = *pColors;
}
void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param) {
#define gcw ((GCheckboxObject *)gw)
coord_t ld, df;
(void) param;
if (gw->g.vmt != (gwinVMT *)&checkboxVMT)
return;
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, gcw->c.color_bg);
gdispDrawBox(gw->g.x, gw->g.y, ld, ld, gcw->c.color_border);
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, gcw->c.color_checked);
gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->txt, gw->g.font, gcw->c.color_txt, gcw->c.color_bg, justifyLeft);
#undef gcw
}
void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
#define gcw ((GCheckboxObject *)gw)
coord_t ep, ld, df;
(void) param;
if (gw->g.vmt != (gwinVMT *)&checkboxVMT)
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, gcw->c.color_bg);
gdispDrawBox(gw->g.x+ep, gw->g.y, ld, ld, gcw->c.color_border);
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, gcw->c.color_checked);
gdispFillStringBox(gw->g.x, gw->g.y, ep, gw->g.height, gw->txt, gw->g.font, gcw->c.color_txt, gcw->c.color_bg, justifyRight);
#undef gcw
}
#endif /* (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) */
/** @} */