From 7baf5c5d448b626d6a062882434b25ca82212d94 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 6 Jun 2013 14:33:32 +1000 Subject: New simplified gwin using a pseudo class structure. --- src/gwin/button.c | 545 ++++++++++++++++++++++------------------------------ src/gwin/checkbox.c | 225 ++++++++++------------ src/gwin/console.c | 55 +++--- src/gwin/graph.c | 72 +++---- src/gwin/gwidget.c | 254 ++++++++++++++++++++++++ src/gwin/gwin.c | 110 ++++------- src/gwin/gwin.mk | 3 +- src/gwin/slider.c | 402 +++++++++++++++++++------------------- 8 files changed, 884 insertions(+), 782 deletions(-) create mode 100644 src/gwin/gwidget.c (limited to 'src') diff --git a/src/gwin/button.c b/src/gwin/button.c index cf5babc5..1ebc8ee5 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -19,392 +19,313 @@ #if (GFX_USE_GWIN && GWIN_NEED_BUTTON) || defined(__DOXYGEN__) -/* Parameters for various shapes */ +#include "gwin/class_gwin.h" + +// Parameters for various shapes #define RND_CNR_SIZE 5 // Rounded corner size for rounded buttons #define ARROWHEAD_DIVIDER 4 // A quarter of the height for the arrow head #define ARROWBODY_DIVIDER 4 // A quarter of the width for the arrow body -#include - -#include "gwin/internal.h" - -#define GWIN_BUTTON_DEFAULT_SHAPE GBTN_3D +// Our pressed state +#define GBUTTON_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0) + +// Prototypes for button VMT functions +static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); +static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); +static void ToggleOff(GWidgetObject *gw, uint16_t instance); +static void ToggleOn(GWidgetObject *gw, uint16_t instance); + +// The button VMT table +static const gwidgetVMT buttonVMT = { + { + "Button", // The classname + _gwidgetDestroy, // The destroy routine + 0, // The after-clear routine + }, + gwinButtonDraw_3D, // The default drawing routine + MouseDown, // Process mouse down events + MouseUp, // Process mouse up events + 0, // Process mouse move events (NOT USED) + ToggleOff, // Process toggle off events + 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 GButtonDrawStyle GButtonDefaultStyleUp = { +// Default color scheme +static const GButtonColors GButtonDefaultColorsUp = { HTML2COLOR(0x404040), // color_up_edge; HTML2COLOR(0xE0E0E0), // color_up_fill; HTML2COLOR(0x000000), // color_up_txt; }; - -static const GButtonDrawStyle GButtonDefaultStyleDown = { +static const GButtonColors GButtonDefaultColorsDown = { HTML2COLOR(0x404040), // color_dn_edge; HTML2COLOR(0x808080), // color_dn_fill; HTML2COLOR(0x404040), // color_dn_txt; }; +static const GButtonColors GButtonDefaultColorsDisabled = { + HTML2COLOR(0x808080), // color_dis_edge; + HTML2COLOR(0xE0E0E0), // color_dis_fill; + HTML2COLOR(0xC0C0C0), // color_dis_txt; +}; -// Process an event callback -static void gwinButtonCallback(void *param, GEvent *pe) { - GSourceListener *psl; - #define gh ((GHandle)param) - #define gbw ((GButtonObject *)param) - #define gsh ((GSourceHandle)param) - #define pme ((GEventMouse *)pe) - #define pte ((GEventTouch *)pe) - #define pxe ((GEventToggle *)pe) - #define pbe ((GEventGWinButton *)pe) - - // check if button 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 (gbw->state == GBTN_UP) { - // Our button is UP: Test for button down over the button - 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) { - gbw->state = GBTN_DOWN; - gwinButtonDraw((GHandle)param); - } - return; - } - - // Our button is DOWN - - // Skip more mouse downs - if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) - return; - - // This must be a mouse up - set the button as UP - gbw->state = GBTN_UP; - gwinButtonDraw((GHandle)param); - - #if GWIN_BUTTON_LAZY_RELEASE - break; - #else - // If the mouse up was over the button then create the event - if (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) - break; - - return; - #endif - #endif - - #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE - case GEVENT_TOGGLE: - // State has changed - update the button - gbw->state = pxe->on ? GBTN_DOWN : GBTN_UP; - gwinButtonDraw((GHandle)param); - - // Trigger the event on button down (different than for mouse/touch) - if (gbw->state == GBTN_DOWN) - break; - - return; - #endif - - default: - return; - } +// Send the button event +static void SendButtonEvent(GWidgetObject *gw) { + GSourceListener * psl; + GEvent * pe; + #define pbe ((GEventGWinButton *)pe) // Trigger a GWIN Button Event psl = 0; - while ((psl = geventGetSourceListener(gsh, psl))) { + while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { if (!(pe = geventGetEventBuffer(psl))) continue; pbe->type = GEVENT_GWIN_BUTTON; - pbe->button = gh; + pbe->button = (GHandle)gw; geventSendEvent(psl); } #undef pbe - #undef pme - #undef pte - #undef pxe - #undef gsh - #undef gbw - #undef gh } -GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type) { - if (!(gb = (GButtonObject *)_gwinInit((GWindowObject *)gb, x, y, width, height, sizeof(GButtonObject)))) - return 0; - - gb->gwin.type = GW_BUTTON; - gb->fn = 0; - gb->param = 0; - gwinSetFont(&gb->gwin, font); - gwinSetButtonStyle(&gb->gwin, GWIN_BUTTON_DEFAULT_SHAPE, &GButtonDefaultStyleUp, &GButtonDefaultStyleDown); - gb->type = type; - gb->state = GBTN_UP; - gb->txt = ""; - geventListenerInit(&gb->listener); - geventRegisterCallback(&gb->listener, gwinButtonCallback, gb); - - // buttons are enabled by default - gb->gwin.enabled = TRUE; - - return (GHandle)gb; +// A mouse down has occurred over the button +static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { + (void) x; (void) y; + gw->g.flags |= GBUTTON_FLG_PRESSED; + gwinDraw((GHandle)gw); } -void gwinSetButtonStyle(GHandle gh, GButtonShape shape, const GButtonDrawStyle *pUp, const GButtonDrawStyle *pDown) { - #define gbw ((GButtonObject *)gh) - if (gh->type != GW_BUTTON) - return; - - switch(shape) { - case GBTN_SQUARE: gbw->fn = gwinButtonDraw_Square; break; - #if GDISP_NEED_ARC - case GBTN_ROUNDED: gbw->fn = gwinButtonDraw_Rounded; break; - #endif - #if GDISP_NEED_ELLIPSE - case GBTN_ELLIPSE: gbw->fn = gwinButtonDraw_Ellipse; break; - #endif - - #if GDISP_NEED_CONVEX_POLYGON - case GBTN_ARROW_UP: gbw->fn = gwinButtonDraw_ArrowUp; break; - case GBTN_ARROW_DOWN: gbw->fn = gwinButtonDraw_ArrowDown; break; - case GBTN_ARROW_LEFT: gbw->fn = gwinButtonDraw_ArrowLeft; break; - case GBTN_ARROW_RIGHT: gbw->fn = gwinButtonDraw_ArrowRight; break; - #endif - - case GBTN_CUSTOM: if (gbw->fn) break; /* Fall Through */ - case GBTN_3D: /* Fall through */ - default: gbw->fn = gwinButtonDraw_3D; break; - } - if (pUp) { - gbw->up.color_edge = pUp->color_edge; - gbw->up.color_fill = pUp->color_fill; - gbw->up.color_txt = pUp->color_txt; - } - if (pDown) { - gbw->dn.color_edge = pDown->color_edge; - gbw->dn.color_fill = pDown->color_fill; - gbw->dn.color_txt = pDown->color_txt; - } - #undef gbw -} +// A mouse up has occurred (it may or may not be over the button) +static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { + (void) x; (void) y; + gw->g.flags &= ~GBUTTON_FLG_PRESSED; + gwinDraw((GHandle)gw); -void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc) { - #define gbw ((GButtonObject *)gh) - if (gh->type != GW_BUTTON) - return; + #if !GWIN_BUTTON_LAZY_RELEASE + // If the mouse up was not over the button then cancel the event + if (x < 0 || y < 0 || x >= gw->g.width || y >= gw->g.height) + return; + #endif - // Dispose of the old string - if ((gh->flags & GBTN_FLG_ALLOCTXT)) { - gh->flags &= ~GBTN_FLG_ALLOCTXT; - if (gbw->txt) { - gfxFree((void *)gbw->txt); - gbw->txt = ""; - } - } - // Alloc the new text if required - if (txt && useAlloc) { - char *str; - - if ((str = (char *)gfxAlloc(strlen(txt)+1))) { - gh->flags |= GBTN_FLG_ALLOCTXT; - strcpy(str, txt); - } - txt = (const char *)str; - } - - gbw->txt = txt ? txt : ""; - #undef gbw + SendButtonEvent(gw); } -void gwinButtonDraw(GHandle gh) { - #define gbw ((GButtonObject *)gh) - - if (gh->type != GW_BUTTON) - return; +// A toggle off has occurred +static void ToggleOff(GWidgetObject *gw, uint16_t instance) { + (void) instance; + gw->g.flags &= ~GBUTTON_FLG_PRESSED; + gwinDraw((GHandle)gw); +} - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif +// A toggle on has occurred +static void ToggleOn(GWidgetObject *gw, uint16_t instance) { + (void) instance; + gw->g.flags |= GBUTTON_FLG_PRESSED; + gwinDraw((GHandle)gw); + // Trigger the event on button down (different than for mouse/touch) + SendButtonEvent(gw); +} - gbw->fn(gh, - gbw->gwin.enabled, - gbw->state == GBTN_DOWN, - gh->font && gbw->txt ? gbw->txt : "", - gbw->state == GBTN_DOWN ? &gbw->dn : &gbw->up, - gbw->param); +GHandle gwinCreateButton(GButtonObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { + if (!(gw = (GButtonObject *)_gwidgetInit((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT))) + return 0; - #undef gbw + gw->c_up = GButtonDefaultColorsUp; + gw->c_dn = GButtonDefaultColorsDown; + gw->c_dis = GButtonDefaultColorsDisabled; + return (GHandle)gw; } -void gwinSetButtonCustom(GHandle gh, GButtonDrawFunction fn, void *param) { - #define gbw ((GButtonObject *)gh) - - if (gh->type != GW_BUTTON) +void gwinSetButtonColors(GHandle gh, const GButtonColors *pUp, const GButtonColors *pDown, const GButtonColors *pDisabled) { + if (gh->vmt != (gwinVMT *)&buttonVMT) return; - gbw->fn = fn ? fn : gwinButtonDraw_3D; - gbw->param = param; + if (pUp) ((GButtonObject *)gh)->c_up = *pUp; + if (pDown) ((GButtonObject *)gh)->c_dn = *pDown; + if (pDisabled) ((GButtonObject *)gh)->c_dis = *pDisabled; +} + +bool_t gwinIsButtonPressed(GHandle gh) { + if (gh->vmt != (gwinVMT *)&buttonVMT) + return FALSE; - #undef gbw + return (gh->flags & GBUTTON_FLG_PRESSED) ? TRUE : FALSE; } -void gwinButtonSetEnabled(GHandle gh, bool_t enabled) { - if (gh->type != GW_BUTTON) - return; +/*---------------------------------------------------------- + * Custom Draw Routines + *----------------------------------------------------------*/ - gh->enabled = enabled; +static GButtonColors *getDrawColors(GWidgetObject *gw) { + if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &((GButtonObject *)gw)->c_dis; + if ((gw->g.flags & GBUTTON_FLG_PRESSED)) return &((GButtonObject *)gw)->c_dn; + return &((GButtonObject *)gw)->c_up; } -void gwinButtonDraw_3D(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; +void gwinButtonDraw_3D(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; - gdispFillStringBox(gh->x, gh->y, gh->width-1, gh->height-1, txt, gh->font, pstyle->color_txt, pstyle->color_fill, justifyCenter); - gdispDrawLine(gh->x+gh->width-1, gh->y, gh->x+gh->width-1, gh->y+gh->height-1, pstyle->color_edge); - gdispDrawLine(gh->x, gh->y+gh->height-1, gh->x+gh->width-2, gh->y+gh->height-1, pstyle->color_edge); + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); + gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->color_edge); + gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->color_edge); } -void gwinButtonDraw_Square(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; +void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; - gdispFillStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, pstyle->color_fill, justifyCenter); - gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); } #if GDISP_NEED_ARC - void gwinButtonDraw_Rounded(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - - if (gh->width >= 2*RND_CNR_SIZE+10) { - gdispFillRoundedBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, RND_CNR_SIZE-1, pstyle->color_fill); - gdispDrawStringBox(gh->x+1, gh->y+RND_CNR_SIZE, gh->width-2, gh->height-(2*RND_CNR_SIZE), txt, gh->font, pstyle->color_txt, justifyCenter); - gdispDrawRoundedBox(gh->x, gh->y, gh->width, gh->height, RND_CNR_SIZE, pstyle->color_edge); + void gwinButtonDraw_Rounded(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + if (gw->g.width >= 2*RND_CNR_SIZE+10) { + gdispFillRoundedBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->color_fill); + gdispDrawStringBox(gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispDrawRoundedBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->color_edge); } else { - gdispFillStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, pstyle->color_fill, justifyCenter); - gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); + gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); } } #endif #if GDISP_NEED_ELLIPSE - void gwinButtonDraw_Ellipse(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - - gdispFillEllipse(gh->x+1, gh->y+1, gh->width/2-1, gh->height/2-1, pstyle->color_fill); - gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); - gdispDrawEllipse(gh->x, gh->y, gh->width/2, gh->height/2, pstyle->color_edge); + void gwinButtonDraw_Ellipse(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + gdispFillEllipse(gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->color_fill); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispDrawEllipse(gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->color_edge); } #endif #if GDISP_NEED_CONVEX_POLYGON - void gwinButtonDraw_ArrowUp(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - point arw[7]; - - arw[0].x = gh->width/2; arw[0].y = 0; - arw[1].x = gh->width-1; arw[1].y = gh->height/ARROWHEAD_DIVIDER; - arw[2].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->height/ARROWHEAD_DIVIDER; - arw[3].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = gh->height-1; - arw[4].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = gh->height-1; - arw[5].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->height/ARROWHEAD_DIVIDER; - arw[6].x = 0; arw[6].y = gh->height/ARROWHEAD_DIVIDER; - - gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill); - gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge); - gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); + void gwinButtonDraw_ArrowUp(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + point arw[7]; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + arw[0].x = gw->g.width/2; arw[0].y = 0; + arw[1].x = gw->g.width-1; arw[1].y = gw->g.height/ARROWHEAD_DIVIDER; + arw[2].x = (gw->g.width + gw->g.width/ARROWBODY_DIVIDER)/2; arw[2].y = gw->g.height/ARROWHEAD_DIVIDER; + arw[3].x = (gw->g.width + gw->g.width/ARROWBODY_DIVIDER)/2; arw[3].y = gw->g.height-1; + arw[4].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[4].y = gw->g.height-1; + arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height/ARROWHEAD_DIVIDER; + arw[6].x = 0; arw[6].y = gw->g.height/ARROWHEAD_DIVIDER; + + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); } - void gwinButtonDraw_ArrowDown(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - point arw[7]; - - arw[0].x = gh->width/2; arw[0].y = gh->height-1; - arw[1].x = gh->width-1; arw[1].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER; - arw[2].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[2].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER; - arw[3].x = (gh->width + gh->width/ARROWBODY_DIVIDER)/2; arw[3].y = 0; - arw[4].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[4].y = 0; - arw[5].x = (gh->width - gh->width/ARROWBODY_DIVIDER)/2; arw[5].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER; - arw[6].x = 0; arw[6].y = gh->height-1-gh->height/ARROWHEAD_DIVIDER; - - gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill); - gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge); - gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); + void gwinButtonDraw_ArrowDown(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + point arw[7]; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + arw[0].x = gw->g.width/2; arw[0].y = gw->g.height-1; + arw[1].x = gw->g.width-1; arw[1].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; + arw[2].x = (gw->g.width + gw->g.width/ARROWBODY_DIVIDER)/2; arw[2].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; + arw[3].x = (gw->g.width + gw->g.width/ARROWBODY_DIVIDER)/2; arw[3].y = 0; + arw[4].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[4].y = 0; + arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; + arw[6].x = 0; arw[6].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; + + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); } - void gwinButtonDraw_ArrowLeft(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - point arw[7]; - - arw[0].x = 0; arw[0].y = gh->height/2; - arw[1].x = gh->width/ARROWHEAD_DIVIDER; arw[1].y = 0; - arw[2].x = gh->width/ARROWHEAD_DIVIDER; arw[2].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2; - arw[3].x = gh->width-1; arw[3].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2; - arw[4].x = gh->width-1; arw[4].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2; - arw[5].x = gh->width/ARROWHEAD_DIVIDER; arw[5].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2; - arw[6].x = gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->height-1; - - gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill); - gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge); - gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); + void gwinButtonDraw_ArrowLeft(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + point arw[7]; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + arw[0].x = 0; arw[0].y = gw->g.height/2; + arw[1].x = gw->g.width/ARROWHEAD_DIVIDER; arw[1].y = 0; + arw[2].x = gw->g.width/ARROWHEAD_DIVIDER; arw[2].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2; + arw[3].x = gw->g.width-1; arw[3].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2; + arw[4].x = gw->g.width-1; arw[4].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; + arw[5].x = gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; + arw[6].x = gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1; + + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); } - void gwinButtonDraw_ArrowRight(GHandle gh, bool_t enabled, bool_t isdown, const char *txt, const GButtonDrawStyle *pstyle, void *param) { - (void) enabled; - (void) isdown; - (void) param; - point arw[7]; - - arw[0].x = gh->width-1; arw[0].y = gh->height/2; - arw[1].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[1].y = 0; - arw[2].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[2].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2; - arw[3].x = 0; arw[3].y = (gh->height - gh->height/ARROWBODY_DIVIDER)/2; - arw[4].x = 0; arw[4].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2; - arw[5].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[5].y = (gh->height + gh->height/ARROWBODY_DIVIDER)/2; - arw[6].x = gh->width-1-gh->width/ARROWHEAD_DIVIDER; arw[6].y = gh->height-1; - - gdispFillConvexPoly(gh->x, gh->y, arw, 7, pstyle->color_fill); - gdispDrawPoly(gh->x, gh->y, arw, 7, pstyle->color_edge); - gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, pstyle->color_txt, justifyCenter); + void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param) { + (void) param; + GButtonColors * pcol; + point arw[7]; + + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); + + arw[0].x = gw->g.width-1; arw[0].y = gw->g.height/2; + arw[1].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[1].y = 0; + arw[2].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[2].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2; + arw[3].x = 0; arw[3].y = (gw->g.height - gw->g.height/ARROWBODY_DIVIDER)/2; + arw[4].x = 0; arw[4].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; + arw[5].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; + arw[6].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1; + + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); } #endif -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - bool_t gwinAttachButtonMouse(GHandle gh, uint16_t instance) { - GSourceHandle gsh; +#if GDISP_NEED_IMAGE || defined(__DOXYGEN__) + void gwinButtonDraw_Image(GWidgetObject *gw, void *param) { + GButtonColors * pcol; + coord_t sy; - if (gh->type != GW_BUTTON || !(gsh = ginputGetMouse(instance))) - return FALSE; + if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; - return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA); - } -#endif - -#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE - bool_t gwinAttachButtonToggle(GHandle gh, uint16_t instance) { - GSourceHandle gsh; - - if (gh->type != GW_BUTTON || !(gsh = ginputGetToggle(instance))) - return FALSE; + if (!(gw->g.flags & GWIN_FLG_ENABLED)) { + pcol = &((GButtonObject *)gw)->c_dis; + sy = 2 * gw->g.height; + } else if ((gw->g.flags & GBUTTON_FLG_PRESSED)) { + pcol = &((GButtonObject *)gw)->c_dn; + sy = gw->g.height; + } else { + pcol = &((GButtonObject *)gw)->c_up; + sy = 0; + } - return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_TOGGLE_OFF|GLISTEN_TOGGLE_ON); + gdispImageDraw((gdispImage *)param, gw->g.x, gw->g.y, gw->g.width, gw->g.height, 0, sy); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); } #endif diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 547a30b5..d35f271c 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,137 @@ #if (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) || defined(__DOXYGEN__) -static const GCheckboxColor defaultColors = { - Grey, // border - Grey, // selected - Black // background +#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 + 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) }; -/* default style drawing routine */ -static void gwinCheckboxDrawDefaultStyle(GHandle gh, bool_t enabled, bool_t isChecked, void* param) { - #define gcw ((GCheckboxObject *)gh) - - (void) enabled; - (void) param; - - gdispDrawBox(gh->x, gh->y, gh->width, gh->height, gcw->colors->border); - - 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); - - #undef gcw -} - -/* 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) { - - gbw->isChecked = !gbw->isChecked; - - gwinCheckboxDraw((GHandle)param); - break; - } - return; - #endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */ +static const GCheckboxColors defaultColors = { + Black, // border + Grey, // selected + White, // background + Black, // text +}; - default: - return; - } +// Send the checkbox event +static void SendCheckboxEvent(GWidgetObject *gw) { + GSourceListener * psl; + GEvent * pe; + #define pce ((GEventGWinCheckbox *)pe) - // Trigger a GWIN checkbox event + // Trigger a GWIN Checkbox Event psl = 0; - while ((psl = geventGetSourceListener(gsh, psl))) { + while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { if (!(pe = geventGetEventBuffer(psl))) continue; - pbe->type = GEVENT_GWIN_CHECKBOX; - pbe->checkbox = gh; - pbe->isChecked = gbw->isChecked; + pce->type = GEVENT_GWIN_CHECKBOX; + pce->checkbox = &gw->g; + pce->isChecked = (gw->g.flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE; geventSendEvent(psl); - } - - #undef gh - #undef pbe - #undef pme - #undef pte - #undef pxe - #undef gsh - #undef gbw -} + } -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)))) - return 0; + #undef pce +} - 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 +// 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; + gwinDraw((GHandle)gw); + SendCheckboxEvent(gw); +} - geventListenerInit(&gb->listener); - geventRegisterCallback(&gb->listener, gwinCheckboxCallback, gb); +// A toggle on has occurred +static void ToggleOn(GWidgetObject *gw, uint16_t instance) { + (void) instance; + gw->g.flags ^= GCHECKBOX_FLG_CHECKED; + gwinDraw((GHandle)gw); + SendCheckboxEvent(gw); +} - // checkboxes are enabled by default - gb->gwin.enabled = TRUE; +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; } -void gwinCheckboxSetCustom(GHandle gh, GCheckboxDrawFunction fn, void *param) { - #define gcw ((GCheckboxObject *)gh) - - if (gh->type != GW_CHECKBOX) - return; - - gcw->fn = fn; - gcw->param = param; +bool_t gwinIsCheckboxChecked(GHandle gh) { + if (gh->vmt != (gwinVMT *)&checkboxVMT) + return FALSE; - #undef gcw + return (gh->flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE; } - -void gwinCheckboxSetEnabled(GHandle gh, bool_t enabled) { - if (gh->type != GW_CHECKBOX) +void gwinCheckboxSetColors(GHandle gh, GCheckboxColors *pColors) { + if (gh->vmt != (gwinVMT *)&checkboxVMT) return; - gh->enabled = enabled; + ((GCheckboxObject *)gh)->c = *pColors; } -void gwinCheckboxDraw(GHandle gh) { - #define gcw ((GCheckboxObject *)gh) +void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param) { + #define gcw ((GCheckboxObject *)gw) + coord_t ld, df; + (void) param; - if (gh->type != GW_CHECKBOX) + if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return; - #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, gcw->c.color_bg); + gdispDrawBox(gw->g.x, gw->g.y, ld, ld, gcw->c.color_border); - 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, 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 } -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - bool_t gwinCheckboxAttachMouse(GHandle gh, uint16_t instance) { - GSourceHandle gsh; - - if (gh->type != GW_CHECKBOX || !(gsh = ginputGetMouse(instance))) - return FALSE; - - 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) +void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) { + #define gcw ((GCheckboxObject *)gw) + coord_t ep, ld, df; + (void) param; - if (gh->type != GW_CHECKBOX) + if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return; - gcw->colors->border = border; - gcw->colors->checked = checked, - gcw->colors->bg = bg; + 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 } diff --git a/src/gwin/console.c b/src/gwin/console.c index 5c068c93..d9bda362 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -8,20 +8,15 @@ /** * @file src/gwin/console.c * @brief GWIN sub-system console code. - * - * @defgroup Console Console - * @ingroup GWIN - * - * @{ */ #include "gfx.h" -#if (GFX_USE_GWIN && GWIN_NEED_CONSOLE) || defined(__DOXYGEN__) +#if GFX_USE_GWIN && GWIN_NEED_CONSOLE #include -#include "gwin/internal.h" +#include "gwin/class_gwin.h" #define GWIN_CONSOLE_USE_CLEAR_LINES TRUE #define GWIN_CONSOLE_USE_FILLED_CHARS FALSE @@ -58,11 +53,20 @@ }; #endif -GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font) { - if (!(gc = (GConsoleObject *)_gwinInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject)))) +static void AfterClear(GWindowObject *gh) { + ((GConsoleObject *)gh)->cx = 0; + ((GConsoleObject *)gh)->cy = 0; +} + +static const gwinVMT consoleVMT = { + "Console", // The classname + 0, // The destroy routine + AfterClear, // The after-clear routine +}; + +GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) { + if (!(gc = (GConsoleObject *)_gwinInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT))) return 0; - gc->gwin.type = GW_CONSOLE; - gwinSetFont(&gc->gwin, font); #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM gc->stream.vmt = &GWindowConsoleVMT; #endif @@ -73,17 +77,21 @@ GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t widt #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM BaseSequentialStream *gwinGetConsoleStream(GHandle gh) { - if (gh->type != GW_CONSOLE) + if (gh->vmt != &consoleVMT) return 0; return (BaseSequentialStream *)&(((GConsoleObject *)(gh))->stream); } #endif void gwinPutChar(GHandle gh, char c) { - uint8_t width; #define gcw ((GConsoleObject *)gh) + uint8_t width, fy, fp; + + if (gh->vmt != &consoleVMT || !gh->font) + return; - if (gh->type != GW_CONSOLE || !gh->font) return; + fy = gdispGetFontMetric(gh->font, fontHeight); + fp = gdispGetFontMetric(gh->font, fontCharPadding); #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); @@ -91,24 +99,24 @@ void gwinPutChar(GHandle gh, char c) { if (c == '\n') { gcw->cx = 0; - gcw->cy += gcw->fy; + gcw->cy += fy; // We use lazy scrolling here and only scroll when the next char arrives } else if (c == '\r') { // gcw->cx = 0; } else { - width = gdispGetCharWidth(c, gh->font) + gcw->fp; + width = gdispGetCharWidth(c, gh->font) + fp; if (gcw->cx + width >= gh->width) { gcw->cx = 0; - gcw->cy += gcw->fy; + gcw->cy += fy; } - if (gcw->cy + gcw->fy > gh->height) { + if (gcw->cy + fy > gh->height) { #if GDISP_NEED_SCROLL /* scroll the console */ - gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, gcw->fy, gh->bgcolor); + gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor); /* reset the cursor to the start of the last line */ gcw->cx = 0; - gcw->cy = (((coord_t)(gh->height/gcw->fy))-1)*gcw->fy; + gcw->cy = (((coord_t)(gh->height/fy))-1)*fy; #else /* clear the console */ gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor); @@ -121,7 +129,7 @@ void gwinPutChar(GHandle gh, char c) { #if GWIN_CONSOLE_USE_CLEAR_LINES /* clear to the end of the line */ if (gcw->cx == 0) - gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, gcw->fy, gh->bgcolor); + gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor); #endif #if GWIN_CONSOLE_USE_FILLED_CHARS gdispFillChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor); @@ -200,7 +208,8 @@ void gwinPrintf(GHandle gh, const char *fmt, ...) { char tmpbuf[MAX_FILLER + 1]; #endif - if (gh->type != GW_CONSOLE || !gh->font) return; + if (gh->vmt != &consoleVMT || !gh->font) + return; va_start(ap, fmt); while (TRUE) { @@ -343,5 +352,5 @@ void gwinPrintf(GHandle gh, const char *fmt, ...) { } #endif /* GFX_USE_GWIN && GWIN_NEED_CONSOLE */ -/** @} */ + diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 287deba9..0ae9822b 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -8,18 +8,13 @@ /** * @file src/gwin/graph.c * @brief GWIN sub-system button code. - * - * @defgroup Graph Graph - * @ingroup GWIN - * - * @{ */ #include "gfx.h" -#if (GFX_USE_GWIN && GWIN_NEED_GRAPH) || defined(__DOXYGEN__) +#if GFX_USE_GWIN && GWIN_NEED_GRAPH -#include "gwin/internal.h" +#include "gwin/class_gwin.h" #define GGRAPH_FLG_CONNECTPOINTS (GWIN_FIRST_CONTROL_FLAG<<0) #define GGRAPH_ARROW_SIZE 5 @@ -34,13 +29,19 @@ static const GGraphStyle GGraphDefaultStyle = { GWIN_GRAPH_STYLE_XAXIS_ARROWS|GWIN_GRAPH_STYLE_YAXIS_ARROWS // flags }; +static const gwinVMT graphVMT = { + "Graph", // The classname + 0, // The destroy routine + 0, // The after-clear routine +}; + static void pointto(GGraphObject *gg, coord_t x, coord_t y, const GGraphPointStyle *style) { if (style->type == GGRAPH_POINT_NONE) return; // Convert to device space. Note the y-axis is inverted. - x += gg->gwin.x + gg->xorigin; - y = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y; + x += gg->g.x + gg->xorigin; + y = gg->g.y + gg->g.height - 1 - gg->yorigin - y; if (style->size <= 1) { gdispDrawPixel(x, y, style->color); @@ -73,10 +74,10 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t return; // Convert to device space. Note the y-axis is inverted. - x0 += gg->gwin.x + gg->xorigin; - y0 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y0; - x1 += gg->gwin.x + gg->xorigin; - y1 = gg->gwin.y + gg->gwin.height - 1 - gg->yorigin - y1; + x0 += gg->g.x + gg->xorigin; + y0 = gg->g.y + gg->g.height - 1 - gg->yorigin - y0; + x1 += gg->g.x + gg->xorigin; + y1 = gg->g.y + gg->g.height - 1 - gg->yorigin - y1; if (style->size <= 0) { // Use the driver to draw a solid line @@ -163,41 +164,26 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gg = (GGraphObject *)_gwinInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject)))) + if (!(gg = (GGraphObject *)_gwinInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT))) return 0; - gg->gwin.type = GW_GRAPH; gg->xorigin = gg->yorigin = 0; gg->lastx = gg->lasty = 0; - gwinGraphSetStyle(&gg->gwin, &GGraphDefaultStyle); + gwinGraphSetStyle((GHandle)gg, &GGraphDefaultStyle); return (GHandle)gg; } void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle) { #define gg ((GGraphObject *)gh) - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; - gg->style.point.type = pstyle->point.type; - gg->style.point.size = pstyle->point.size; - gg->style.point.color = pstyle->point.color; - gg->style.line.type = pstyle->line.type; - gg->style.line.size = pstyle->line.size; - gg->style.line.color = pstyle->line.color; - gg->style.xaxis.type = pstyle->xaxis.type; - gg->style.xaxis.size = pstyle->xaxis.size; - gg->style.xaxis.color = pstyle->xaxis.color; - gg->style.yaxis.type = pstyle->yaxis.type; - gg->style.yaxis.size = pstyle->yaxis.size; - gg->style.yaxis.color = pstyle->yaxis.color; - gg->style.xgrid.type = pstyle->xgrid.type; - gg->style.xgrid.size = pstyle->xgrid.size; - gg->style.xgrid.color = pstyle->xgrid.color; - gg->style.xgrid.spacing = pstyle->xgrid.spacing; - gg->style.ygrid.type = pstyle->ygrid.type; - gg->style.ygrid.size = pstyle->ygrid.size; - gg->style.ygrid.color = pstyle->ygrid.color; - gg->style.ygrid.spacing = pstyle->ygrid.spacing; + gg->style.point = pstyle->point; + gg->style.line = pstyle->line; + gg->style.xaxis = pstyle->xaxis; + gg->style.yaxis = pstyle->yaxis; + gg->style.xgrid = pstyle->xgrid; + gg->style.ygrid = pstyle->ygrid; gg->style.flags = pstyle->flags; #undef gg @@ -206,7 +192,7 @@ void gwinGraphSetStyle(GHandle gh, const GGraphStyle *pstyle) { void gwinGraphSetOrigin(GHandle gh, coord_t x, coord_t y) { #define gg ((GGraphObject *)gh) - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; gg->xorigin = x; @@ -219,7 +205,7 @@ void gwinGraphDrawAxis(GHandle gh) { #define gg ((GGraphObject *)gh) coord_t i, xmin, ymin, xmax, ymax; - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; xmin = -gg->xorigin; @@ -277,7 +263,7 @@ void gwinGraphDrawAxis(GHandle gh) { } void gwinGraphStartSet(GHandle gh) { - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; gh->flags &= ~GGRAPH_FLG_CONNECTPOINTS; @@ -286,7 +272,7 @@ void gwinGraphStartSet(GHandle gh) { void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) { #define gg ((GGraphObject *)gh) - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) { @@ -314,7 +300,7 @@ void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count) { unsigned i; const point *p; - if (gh->type != GW_GRAPH) + if (gh->vmt != &graphVMT) return; // Draw the connecting lines @@ -344,5 +330,3 @@ void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count) { } #endif /* GFX_USE_GWIN && GWIN_NEED_GRAPH */ -/** @} */ - 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 + +#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 */ +/** @} */ + diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index c01c8a90..fcbaa397 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -9,11 +9,19 @@ #if GFX_USE_GWIN -#include "gwin/internal.h" +#include "gwin/class_gwin.h" + +static const gwinVMT basegwinVMT = { + "GWIN", // The classname + 0, // The destroy routine + 0, // The after-clear routine +}; + +static font_t defaultFont; // Internal routine for use by GWIN components only // Initialise a window creating it dynamicly if required. -GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size) { +GHandle _gwinInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt) { coord_t w, h; // Check the window size against the screen size @@ -26,60 +34,34 @@ GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_ if (y+height > h) height = h - y; // Allocate the structure if necessary - if (!gw) { - if (!(gw = (GWindowObject *)gfxAlloc(size))) + if (!pgw) { + if (!(pgw = (GWindowObject *)gfxAlloc(size))) return 0; - gw->flags = GWIN_FLG_DYNAMIC; + pgw->flags = GWIN_FLG_DYNAMIC; } else - gw->flags = 0; + pgw->flags = 0; - // Initialise all basic fields (except the type) - gw->x = x; - gw->y = y; - gw->width = width; - gw->height = height; - gw->color = White; - gw->bgcolor = Black; + // Initialise all basic fields + pgw->vmt = vmt; + pgw->x = x; + pgw->y = y; + pgw->width = width; + pgw->height = height; + pgw->color = White; + pgw->bgcolor = Black; #if GDISP_NEED_TEXT - gw->font = 0; + pgw->font = defaultFont; #endif - return (GHandle)gw; -} - -GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gw = (GWindowObject *)_gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject)))) - return 0; - gw->type = GW_WINDOW; - return (GHandle)gw; + return (GHandle)pgw; } -void gwinSetEnabled(GHandle gh, bool_t enabled) { - (void)gh; - (void)enabled; +GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) { + return _gwinInit(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT); } -void gwinDestroyWindow(GHandle gh) { - // Clean up any type specific dynamic memory allocations - switch(gh->type) { -#if GWIN_NEED_BUTTON - case GW_BUTTON: - if ((gh->flags & GBTN_FLG_ALLOCTXT)) { - gh->flags &= ~GBTN_FLG_ALLOCTXT; // To be sure, to be sure - gfxFree((void *)((GButtonObject *)gh)->txt); - } - geventDetachSource(&((GButtonObject *)gh)->listener, 0); - geventDetachSourceListeners((GSourceHandle)gh); - break; -#endif -#if GWIN_NEED_SLIDER - case GW_SLIDER: - geventDetachSource(&((GSliderObject *)gh)->listener, 0); - geventDetachSourceListeners((GSourceHandle)gh); - break; -#endif - default: - break; - } +void gwinDestroy(GHandle gh) { + if (gh->vmt->Destroy) + gh->vmt->Destroy(gh); // Clean up the structure if (gh->flags & GWIN_FLG_DYNAMIC) { @@ -88,30 +70,17 @@ void gwinDestroyWindow(GHandle gh) { } } -void gwinDraw(GHandle gh) { - switch(gh->type) { - #if GWIN_NEED_BUTTON - case GW_BUTTON: - gwinButtonDraw(gh); - break; - #endif - #if GWIN_NEED_SLIDER - case GW_SLIDER: - gwinSliderDraw(gh); - break; - #endif - } +const char *gwinGetClassName(GHandle gh) { + return gh->vmt->classname; } #if GDISP_NEED_TEXT + void gwinSetDefaultFont(font_t font) { + defaultFont = font; + } + void gwinSetFont(GHandle gh, font_t font) { gh->font = font; - #if GWIN_NEED_CONSOLE - if (font && gh->type == GW_CONSOLE) { - ((GConsoleObject *)gh)->fy = gdispGetFontMetric(font, fontHeight); - ((GConsoleObject *)gh)->fp = gdispGetFontMetric(font, fontCharPadding); - } - #endif } #endif @@ -120,13 +89,8 @@ void gwinClear(GHandle gh) { gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor); - - #if GWIN_NEED_CONSOLE - if (gh->type == GW_CONSOLE) { - ((GConsoleObject *)gh)->cx = 0; - ((GConsoleObject *)gh)->cy = 0; - } - #endif + if (gh->vmt->AfterClear) + gh->vmt->AfterClear(gh); } void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index be6301c6..90a8e9b4 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -1,7 +1,8 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ + $(GFXLIB)/src/gwin/gwidget.c \ $(GFXLIB)/src/gwin/console.c \ + $(GFXLIB)/src/gwin/graph.c \ $(GFXLIB)/src/gwin/button.c \ $(GFXLIB)/src/gwin/slider.c \ - $(GFXLIB)/src/gwin/graph.c \ $(GFXLIB)/src/gwin/checkbox.c \ diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 1f252d77..f18c665b 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -19,140 +19,168 @@ #if (GFX_USE_GWIN && GWIN_NEED_SLIDER) || defined(__DOXYGEN__) -#include "gwin/internal.h" +#include "gwin/class_gwin.h" #ifndef GWIN_SLIDER_DEAD_BAND #define GWIN_SLIDER_DEAD_BAND 5 #endif -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - static void trackSliderDraw(GHandle gh, coord_t x, coord_t y); -#endif +// Prototypes for slider VMT functions +static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); +static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y); +static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value); + +// The button VMT table +static const gwidgetVMT sliderVMT = { + { + "Slider", // The classname + _gwidgetDestroy, // The destroy routine + 0, // The after-clear routine + }, + gwinSliderDraw_Std, // The default drawing routine + MouseMove, // Process mouse down events (AS MOUSEMOVE) + MouseUp, // Process mouse up events + MouseMove, // Process mouse move events + 0, // Process toggle off events (NOT USED) + 0, // Process toggle on events (NOT USED) + DialMove, // Process dial move events + 0, // Process all events (NOT USED) + 0, // AssignToggle (NOT USED) + 0, // AssignDial (NOT USED) +}; -static const GSliderDrawStyle GSliderDefaultStyle = { - HTML2COLOR(0x404040), // color_edge; - HTML2COLOR(0x000000), // color_thumb; - HTML2COLOR(0x00E000), // color_active; - HTML2COLOR(0xE0E0E0), // color_inactive; +static const GSliderColors GSliderDefaultColors = { + HTML2COLOR(0x404040), // color_edge + HTML2COLOR(0x000000), // color_thumb + HTML2COLOR(0x00E000), // color_active + HTML2COLOR(0xE0E0E0), // color_inactive + HTML2COLOR(0xFFFFFF), // color_txt }; -// Process an event callback -static void gwinSliderCallback(void *param, GEvent *pe) { - GSourceListener *psl; - #define gh ((GHandle)param) - #define gsw ((GSliderObject *)param) - #define gsh ((GSourceHandle)param) - #define pme ((GEventMouse *)pe) - #define pde ((GEventDial *)pe) - #define pse ((GEventGWinSlider *)pe) - - switch (pe->type) { - #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - case GEVENT_MOUSE: - case GEVENT_TOUCH: - // If not tracking we only only interested in a mouse down over the slider - if (!gsw->tracking) { - if ((pme->meta & GMETA_MOUSE_DOWN) - && pme->x >= gh->x && pme->x < gh->x + gh->width - && pme->y >= gh->y && pme->y < gh->y + gh->height) { - gsw->tracking = TRUE; - trackSliderDraw(gh, pme->x-gh->x, pme->y-gh->y); - } - return; - } +// Send the slider event +static void SendSliderEvent(GWidgetObject *gw) { + GSourceListener * psl; + GEvent * pe; + #define pse ((GEventGWinSlider *)pe) - // We are tracking the mouse - - // Test for button up - if ((pme->meta & GMETA_MOUSE_UP)) { - gsw->tracking = FALSE; - - #if !GWIN_BUTTON_LAZY_RELEASE - // Are we over the slider? - if (pme->x < gh->x || pme->x >= gh->x + gh->width - || pme->y < gh->y || pme->y >= gh->y + gh->height) { - // No - restore the slider - gwinSliderDraw(gh); - return; - } - #endif - - // Set the new position - if (gh->width < gh->height) - gwinSetSliderPosition(gh, - (uint16_t)((uint32_t)(gh->height-1-pme->y+gh->y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min)); - else - gwinSetSliderPosition(gh, - (uint16_t)((uint32_t)(pme->x-gh->x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min)); - - // Update the display - gwinSliderDraw(gh); - - // Generate the event - break; - } + // Trigger a GWIN Button Event + psl = 0; + while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { + if (!(pe = geventGetEventBuffer(psl))) + continue; + pse->type = GEVENT_GWIN_SLIDER; + pse->slider = (GHandle)gw; + pse->position = ((GSliderObject *)gw)->pos; + geventSendEvent(psl); + } - // If mouse down - track movement - if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) - trackSliderDraw(gh, pme->x-gh->x, pme->y-gh->y); + #undef pbe +} +// Reset the display position back to the value predicted by the saved slider position +static void ResetDisplayPos(GSliderObject *gsw) { + if (gsw->w.g.width < gsw->w.g.height) + gsw->dpos = gsw->w.g.height-1-((gsw->w.g.height-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min); + else + gsw->dpos = ((gsw->w.g.width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min); +} + +// A mouse up event +static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gw) + #define gh ((GHandle)gw) + + #if GWIN_BUTTON_LAZY_RELEASE + // Clip to the slider + if (x < 0) x = 0; + else if (x >= gh->width) x = gh->width-1; + if (y < 0) y = 0; + else if (y >= gh->height) x = gh->height-1; + #else + // Are we over the slider? + if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) { + // No - restore the slider + ResetDisplayPos(gsw); + gwinDraw(gh); return; + } #endif - #if GFX_USE_GINPUT && GINPUT_NEED_DIAL - case GEVENT_DIAL: - // Set the new position - gwinSetSliderPosition(gh, (uint16_t)((uint32_t)pde->value*(gsw->max-gsw->min)/ginputGetDialRange(pde->instance) + gsw->min)); - // Update the display - gwinSliderDraw(gh); + // Set the new position + if (gh->width < gh->height) + gsw->pos = (uint16_t)((uint32_t)(gh->height-1-y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + else + gsw->pos = (uint16_t)((uint32_t)(x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); - // Generate the event - break; - #endif + ResetDisplayPos(gsw); + gwinDraw(gh); - default: - return; - } + // Generate the event + SendSliderEvent(gw); + #undef gh + #undef gsw +} - // Trigger a GWIN Slider Event - psl = 0; - while ((psl = geventGetSourceListener(gsh, psl))) { - if (!(pe = geventGetEventBuffer(psl))) - continue; - pse->type = GEVENT_GWIN_SLIDER; - pse->slider = gh; - pse->position = gsw->pos; - geventSendEvent(psl); +// A mouse move (or mouse down) event +static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gw) + + // Determine the temporary display position (with range checking) + if (gw->g.width < gw->g.height) { + if (y < 0) + gsw->dpos = 0; + else if (y >= gw->g.height) + gsw->dpos = gw->g.height-1; + else + gsw->dpos = y; + } else { + if (x < 0) + gsw->dpos = 0; + else if (x >= gw->g.width) + gsw->dpos = gw->g.width-1; + else + gsw->dpos = x; } - #undef pse - #undef pme - #undef pxe - #undef gsh + // Update the display + gwinDraw(&gw->g); #undef gsw - #undef gh +} + +// A dial move event +static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value) { +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + #define gsw ((GSliderObject *)gw) + + // Set the new position + gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/ginputGetDialRange(instance) + gsw->min); + + ResetDisplayPos(gsw); + gwinDraw(&gw->g); + + // Generate the event + SendSliderEvent(gw); + #undef gsw +#else + (void)gw; (void)instance; (void)value; +#endif } GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gs = (GSliderObject *)_gwinInit((GWindowObject *)gs, x, y, width, height, sizeof(GSliderObject)))) + if (!(gs = (GSliderObject *)_gwidgetInit((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT))) return 0; - gs->gwin.type = GW_SLIDER; - gs->fn = gwinSliderDraw_Std; - gs->param = 0; - gwinSetSliderStyle(&gs->gwin, &GSliderDefaultStyle); + gs->c = GSliderDefaultColors; gs->min = 0; gs->max = 100; gs->pos = 0; - gs->tracking = FALSE; - geventListenerInit(&gs->listener); - geventRegisterCallback(&gs->listener, gwinSliderCallback, gs); + ResetDisplayPos(gs); return (GHandle)gs; } void gwinSetSliderRange(GHandle gh, int min, int max) { #define gsw ((GSliderObject *)gh) - if (gh->type != GW_SLIDER) + if (gh->vmt != (gwinVMT *)&sliderVMT) return; if (min == max) // prevent divide by 0 errors. @@ -160,13 +188,14 @@ void gwinSetSliderRange(GHandle gh, int min, int max) { gsw->min = min; gsw->max = max; gsw->pos = min; + ResetDisplayPos(gsw); #undef gsw } void gwinSetSliderPosition(GHandle gh, int pos) { #define gsw ((GSliderObject *)gh) - if (gh->type != GW_SLIDER) + if (gh->vmt != (gwinVMT *)&sliderVMT) return; if (gsw->min <= gsw->max) { @@ -178,125 +207,96 @@ void gwinSetSliderPosition(GHandle gh, int pos) { else if (pos < gsw->max) gsw->pos = gsw->max; else gsw->pos = pos; } + ResetDisplayPos(gsw); #undef gsw } -void gwinSetSliderStyle(GHandle gh, const GSliderDrawStyle *pStyle) { - #define gsw ((GSliderObject *)gh) - - if (gh->type != GW_SLIDER) - return; - - gsw->style.color_edge = pStyle->color_edge; - gsw->style.color_thumb = pStyle->color_thumb; - gsw->style.color_active = pStyle->color_active; - gsw->style.color_inactive = pStyle->color_inactive; - #undef gsw -} - -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - static void trackSliderDraw(GHandle gh, coord_t x, coord_t y) { - #define gsw ((GSliderObject *)gh) - - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif - - if (gh->height <= gh->width) - gsw->fn(gh, FALSE, x, &gsw->style, gsw->param); - else - gsw->fn(gh, TRUE, y, &gsw->style, gsw->param); - - #undef gbw - } -#endif - -void gwinSliderDraw(GHandle gh) { - #define gsw ((GSliderObject *)gh) - - if (gh->type != GW_SLIDER) +void gwinSetSliderColors(GHandle gh, const GSliderColors *pColors) { + if (gh->vmt != (gwinVMT *)&sliderVMT) return; - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif - - if (gh->height <= gh->width) - gsw->fn(gh, FALSE, ((gh->width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min), &gsw->style, gsw->param); - else - gsw->fn(gh, TRUE, gh->height-1-((gh->height-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min), &gsw->style, gsw->param); - - #undef gbw + ((GSliderObject *)gh)->c = *pColors; } -void gwinSetSliderCustom(GHandle gh, GSliderDrawFunction fn, void *param) { - #define gsw ((GSliderObject *)gh) +void gwinSliderDraw_Std(GWidgetObject *gw, void *param) { + #define gsw ((GSliderObject *)gw) + (void) param; - if (gh->type != GW_SLIDER) + if (gw->g.vmt != (gwinVMT *)&sliderVMT) return; - gsw->fn = fn ? fn : gwinSliderDraw_Std; - gsw->param = param; + if (gw->g.width < gw->g.height) { // Vertical slider + if (gsw->dpos != gw->g.height-1) + gdispFillArea(gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, gsw->c.color_active); + if (gsw->dpos != 0) + gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gsw->c.color_inactive); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, gsw->c.color_thumb); + if (gsw->dpos >= 2) + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos-2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos-2, gsw->c.color_thumb); + if (gsw->dpos <= gw->g.height-2) + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos+2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos+2, gsw->c.color_thumb); + + // Horizontal slider + } else { + if (gsw->dpos != gw->g.width-1) + gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gsw->c.color_inactive); + if (gsw->dpos != 0) + gdispFillArea(gw->g.x, gw->g.y, gsw->dpos, gw->g.height, gsw->c.color_active); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); + gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + if (gsw->dpos >= 2) + gdispDrawLine(gw->g.x+gsw->dpos-2, gw->g.y, gw->g.x+gsw->dpos-2, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + if (gsw->dpos <= gw->g.width-2) + gdispDrawLine(gw->g.x+gsw->dpos+2, gw->g.y, gw->g.x+gsw->dpos+2, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + } + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, gsw->c.color_txt, justifyCenter); #undef gsw } -void gwinSliderSetEnabled(GHandle gh, bool_t enabled) { - if (gh->type != GW_SLIDER) - return; +void gwinSliderDraw_Image(GWidgetObject *gw, void *param) { + #define gsw ((GSliderObject *)gw) + #define gi ((gdispImage *)param) + coord_t z, v; - gh->enabled = enabled; -} + if (gw->g.vmt != (gwinVMT *)&sliderVMT) + return; -void gwinSliderDraw_Std(GHandle gh, bool_t isVertical, coord_t thumbpos, const GSliderDrawStyle *pstyle, void *param) { - (void) param; + if (gw->g.width < gw->g.height) { // Vertical slider + if (gsw->dpos != 0) // The unfilled area + gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gsw->c.color_inactive); + if (gsw->dpos != gw->g.height-1) { // The filled area + for(z=gw->g.height, v=gi->height; z > gsw->dpos;) { + z -= v; + if (z < gsw->dpos) { + v -= gsw->dpos - z; + z = gsw->dpos; + } + gdispImageDraw(gi, gw->g.x, gw->g.y+z, gw->g.width, v, 0, gi->height-v); + } + } + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, gsw->c.color_thumb); - if (isVertical) { - if (thumbpos != gh->height-1) - gdispFillArea(gh->x, gh->y+thumbpos, gh->width, gh->height - thumbpos, pstyle->color_active); - if (thumbpos != 0) - gdispFillArea(gh->x, gh->y, gh->width, thumbpos, pstyle->color_inactive); - gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); - gdispDrawLine(gh->x, gh->y+thumbpos, gh->x+gh->width-1, gh->y+thumbpos, pstyle->color_thumb); - if (thumbpos >= 2) - gdispDrawLine(gh->x, gh->y+thumbpos-2, gh->x+gh->width-1, gh->y+thumbpos-2, pstyle->color_thumb); - if (thumbpos <= gh->height-2) - gdispDrawLine(gh->x, gh->y+thumbpos+2, gh->x+gh->width-1, gh->y+thumbpos+2, pstyle->color_thumb); + // Horizontal slider } else { - if (thumbpos != gh->width-1) - gdispFillArea(gh->x+thumbpos, gh->y, gh->width-thumbpos, gh->height, pstyle->color_inactive); - if (thumbpos != 0) - gdispFillArea(gh->x, gh->y, thumbpos, gh->height, pstyle->color_active); - gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); - gdispDrawLine(gh->x+thumbpos, gh->y, gh->x+thumbpos, gh->y+gh->height-1, pstyle->color_thumb); - if (thumbpos >= 2) - gdispDrawLine(gh->x+thumbpos-2, gh->y, gh->x+thumbpos-2, gh->y+gh->height-1, pstyle->color_thumb); - if (thumbpos <= gh->width-2) - gdispDrawLine(gh->x+thumbpos+2, gh->y, gh->x+thumbpos+2, gh->y+gh->height-1, pstyle->color_thumb); - } -} - -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - bool_t gwinAttachSliderMouse(GHandle gh, uint16_t instance) { - GSourceHandle gsh; - - if (gh->type != GW_SLIDER || !(gsh = ginputGetMouse(instance))) - return FALSE; - - return geventAttachSource(&((GSliderObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES); + if (gsw->dpos != gw->g.width-1) // The unfilled area + gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gsw->c.color_inactive); + if (gsw->dpos != 0) { // The filled area + for(z=0, v=gi->width; z < gsw->dpos; z += v) { + if (z+v > gsw->dpos) + v -= z+v - gsw->dpos; + gdispImageDraw(gi, gw->g.x+z, gw->g.y, v, gw->g.height, 0, 0); + } + } + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); + gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, gsw->c.color_thumb); } -#endif - -#if GFX_USE_GINPUT && GINPUT_NEED_DIAL - bool_t gwinAttachSliderDial(GHandle gh, uint16_t instance) { - GSourceHandle gsh; + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, gsw->c.color_txt, justifyCenter); - if (gh->type != GW_SLIDER || !(gsh = ginputGetDial(instance))) - return FALSE; - - return geventAttachSource(&((GSliderObject *)gh)->listener, gsh, 0); - } -#endif + #undef gsw +} #endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */ /** @} */ -- cgit v1.2.3 From 663caba66214acdb6170903f6a203740ea1de8b9 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 6 Jun 2013 16:48:30 +1000 Subject: GWIN fixes --- src/gwin/gwidget.c | 4 ++-- src/gwin/gwin.c | 14 ++++++++++++-- src/gwin/slider.c | 19 +++++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 464210b7..3f23140c 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -39,7 +39,7 @@ static void gwidgetCallback(void *param, GEvent *pe) { case GEVENT_TOUCH: // Are we captured? if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) { - if (pme->meta == GMETA_MOUSE_UP) { + if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) { gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE; if (wvmt->MouseUp) wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y); @@ -48,7 +48,7 @@ static void gwidgetCallback(void *param, GEvent *pe) { 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 + } else if ((~pme->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT) && 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; diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index fcbaa397..163e821d 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -18,6 +18,8 @@ static const gwinVMT basegwinVMT = { }; static font_t defaultFont; +static color_t defaultFgColor = White; +static color_t defaultBgColor = Black; // Internal routine for use by GWIN components only // Initialise a window creating it dynamicly if required. @@ -47,8 +49,8 @@ GHandle _gwinInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord pgw->y = y; pgw->width = width; pgw->height = height; - pgw->color = White; - pgw->bgcolor = Black; + pgw->color = defaultFgColor; + pgw->bgcolor = defaultBgColor; #if GDISP_NEED_TEXT pgw->font = defaultFont; #endif @@ -74,6 +76,14 @@ const char *gwinGetClassName(GHandle gh) { return gh->vmt->classname; } +void gwinSetDefaultColor(color_t clr) { + defaultFgColor = clr; +} + +void gwinSetDefaultBgColor(color_t bgclr) { + defaultBgColor = bgclr; +} + #if GDISP_NEED_TEXT void gwinSetDefaultFont(font_t font) { defaultFont = font; diff --git a/src/gwin/slider.c b/src/gwin/slider.c index f18c665b..a0289d3d 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -107,10 +107,21 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { #endif // Set the new position - if (gh->width < gh->height) - gsw->pos = (uint16_t)((uint32_t)(gh->height-1-y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); - else - gsw->pos = (uint16_t)((uint32_t)(x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + if (gh->width < gh->height) { + if (y > gh->height-GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->min; + else if (y < GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->max; + else + gsw->pos = (uint16_t)((int32_t)(gh->height-1-y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + } else { + if (x > gh->width-GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->max; + else if (x < GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->min; + else + gsw->pos = (uint16_t)((int32_t)(x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + } ResetDisplayPos(gsw); gwinDraw(gh); -- cgit v1.2.3 From 777ec6af7c1b594f7b7a9cbaaf7ead90d8fb7e8f Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 8 Jun 2013 02:27:59 +1000 Subject: Add a simple GWIN window manager, Change the way GWIN visibility works --- src/gfx.c | 2 +- src/gqueue/gqueue.c | 29 ++++-- src/gwin/button.c | 9 +- src/gwin/checkbox.c | 5 +- src/gwin/console.c | 3 +- src/gwin/graph.c | 3 +- src/gwin/gwidget.c | 46 +++++---- src/gwin/gwin.c | 290 +++++++++++++++++++++++++++++++++++++++++++++------- src/gwin/gwin.mk | 1 + src/gwin/gwm.c | 144 ++++++++++++++++++++++++++ src/gwin/slider.c | 7 +- 11 files changed, 461 insertions(+), 78 deletions(-) create mode 100644 src/gwin/gwm.c (limited to 'src') diff --git a/src/gfx.c b/src/gfx.c index 2b307426..3856eea3 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -32,7 +32,7 @@ void DEPRECATED("Use gfxInit() instead") gdispInit() { gfxInit(); } /* These init functions are defined by each module but not published */ extern void _gosInit(void); -#if GFX_USE_GDISP && (GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC) +#if GFX_USE_GDISP extern void _gdispInit(void); #endif #if GFX_USE_TDISP diff --git a/src/gqueue/gqueue.c b/src/gqueue/gqueue.c index d515a425..11d10c0a 100644 --- a/src/gqueue/gqueue.c +++ b/src/gqueue/gqueue.c @@ -21,6 +21,9 @@ * @file src/gqueue/gqueue.c * @brief GQUEUE source file. */ + +#include "gfx.h" + #if GFX_USE_GQUEUE #if GQUEUE_NEED_ASYNC @@ -34,7 +37,7 @@ gfxSystemLock(); if ((pi = pqueue->head)) pqueue->head = pi->next; - gfxSytemUnlock(); + gfxSystemUnlock(); return pi; } void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { @@ -58,13 +61,15 @@ gfxSystemUnlock(); } void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxQueueASyncItem *pi; + if (!pitem) return; gfxSystemLock(); if (pqueue->head) { if (pqueue->head == pitem) { pqueue->head = pitem->next; } else { - for(gfxQueueASyncItem *pi = pqueue->head; pi->next; pi = pi->next) { + for(pi = pqueue->head; pi->next; pi = pi->next) { if (pi->next == pitem) { pi->next = pitem->next; if (pqueue->tail == pitem) @@ -80,8 +85,10 @@ return pqueue->head == NULL; } bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxQueueASyncItem *pi; + gfxSystemLock(); - for(gfxQueueASyncItem *pi = pqueue->head; pi; pi = pi->next) { + for(pi = pqueue->head; pi; pi = pi->next) { if (pi == pitem) { gfxSystemUnlock(); return TRUE; @@ -132,13 +139,15 @@ gfxSemSignal(&pqueue->sem); } void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxQueueGSyncItem *pi; + if (!pitem) return; gfxSystemLock(); if (pqueue->head) { if (pqueue->head == pitem) { pqueue->head = pitem->next; } else { - for(gfxQueueGSyncItem *pi = pqueue->head; pi->next; pi = pi->next) { + for(pi = pqueue->head; pi->next; pi = pi->next) { if (pi->next == pitem) { pi->next = pitem->next; if (pqueue->tail == pitem) @@ -154,8 +163,10 @@ return pqueue->head == NULL; } bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxQueueGSyncItem *pi; + gfxSystemLock(); - for(gfxQueueGSyncItem *pi = pqueue->head; pi; pi = pi->next) { + for(pi = pqueue->head; pi; pi = pi->next) { if (pi == pitem) { gfxSystemUnlock(); return TRUE; @@ -214,6 +225,8 @@ return gfxSemWait(&pitem->sem, ms); } void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) { + gfxQueueFSyncItem *pi; + if (!pitem) return; gfxSystemLock(); if (pqueue->head) { @@ -225,7 +238,7 @@ gfxSemDestroy(&pitem->sem); return; } - for(gfxQueueFSyncItem *pi = pqueue->head; pi->next; pi = pi->next) { + for(pi = pqueue->head; pi->next; pi = pi->next) { if (pi->next == pitem) { pi->next = pitem->next; if (pqueue->tail == pitem) @@ -240,8 +253,10 @@ return pqueue->head == NULL; } bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) { + gfxQueueASyncItem *pi; + gfxSystemLock(); - for(gfxQueueFSyncItem *pi = pqueue->head; pi; pi = pi->next) { + for(pi = pqueue->head; pi; pi = pi->next) { if (pi == pitem) { gfxSystemUnlock(); return TRUE; diff --git a/src/gwin/button.c b/src/gwin/button.c index 1ebc8ee5..83b81b03 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -40,6 +40,7 @@ static const gwidgetVMT buttonVMT = { { "Button", // The classname _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, gwinButtonDraw_3D, // The default drawing routine @@ -94,14 +95,14 @@ static void SendButtonEvent(GWidgetObject *gw) { static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { (void) x; (void) y; gw->g.flags |= GBUTTON_FLG_PRESSED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); } // A mouse up has occurred (it may or may not be over the button) static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { (void) x; (void) y; gw->g.flags &= ~GBUTTON_FLG_PRESSED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); #if !GWIN_BUTTON_LAZY_RELEASE // If the mouse up was not over the button then cancel the event @@ -116,14 +117,14 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { static void ToggleOff(GWidgetObject *gw, uint16_t instance) { (void) instance; gw->g.flags &= ~GBUTTON_FLG_PRESSED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); } // A toggle on has occurred static void ToggleOn(GWidgetObject *gw, uint16_t instance) { (void) instance; gw->g.flags |= GBUTTON_FLG_PRESSED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); // Trigger the event on button down (different than for mouse/touch) SendButtonEvent(gw); } diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index d35f271c..893dab9c 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -33,6 +33,7 @@ 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 @@ -78,7 +79,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) { static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { (void) x; (void) y; gw->g.flags ^= GCHECKBOX_FLG_CHECKED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); SendCheckboxEvent(gw); } @@ -86,7 +87,7 @@ static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { static void ToggleOn(GWidgetObject *gw, uint16_t instance) { (void) instance; gw->g.flags ^= GCHECKBOX_FLG_CHECKED; - gwinDraw((GHandle)gw); + _gwidgetRedraw((GHandle)gw); SendCheckboxEvent(gw); } diff --git a/src/gwin/console.c b/src/gwin/console.c index d9bda362..c4b2798d 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -61,11 +61,12 @@ static void AfterClear(GWindowObject *gh) { static const gwinVMT consoleVMT = { "Console", // The classname 0, // The destroy routine + 0, // The redraw routine AfterClear, // The after-clear routine }; GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gc = (GConsoleObject *)_gwinInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT))) + if (!(gc = (GConsoleObject *)_gwindowInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE))) return 0; #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM gc->stream.vmt = &GWindowConsoleVMT; diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 0ae9822b..393297e7 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -32,6 +32,7 @@ static const GGraphStyle GGraphDefaultStyle = { static const gwinVMT graphVMT = { "Graph", // The classname 0, // The destroy routine + 0, // The redraw routine 0, // The after-clear routine }; @@ -164,7 +165,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gg = (GGraphObject *)_gwinInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT))) + if (!(gg = (GGraphObject *)_gwindowInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE))) return 0; gg->xorigin = gg->yorigin = 0; gg->lastx = gg->lasty = 0; diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 3f23140c..773a715d 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -7,7 +7,7 @@ #include "gfx.h" -#if GFX_USE_GWIN +#if GFX_USE_GWIN && GWIN_NEED_WIDGET #include @@ -24,7 +24,7 @@ static void gwidgetCallback(void *param, GEvent *pe) { #define pde ((GEventDial *)pe) // check if widget is disabled - if (!(gw->g.flags & GWIN_FLG_ENABLED)) + if ((gw->g.flags & (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) return; // Process via AllEvents() if it is defined @@ -87,10 +87,9 @@ static void gwidgetCallback(void *param, GEvent *pe) { } 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))) + if (!(pgw = (GWidgetObject *)_gwindowInit((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) return 0; - pgw->g.flags |= (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED); pgw->txt = ""; pgw->fnDraw = vmt->DefaultDraw; pgw->fnParam = 0; @@ -101,9 +100,6 @@ GHandle _gwidgetInit(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, co } 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; @@ -112,21 +108,10 @@ void _gwidgetDestroy(GHandle gh) { // 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)) +void _gwidgetRedraw(GHandle gh) { + if (!(gh->flags & GWIN_FLG_VISIBLE)) return; #if GDISP_NEED_CLIP @@ -136,6 +121,23 @@ void gwinDraw(GHandle gh) { gw->fnDraw(gw, gw->fnParam); } +void gwinSetEnabled(GHandle gh, bool_t enabled) { + if (!(gh->flags & GWIN_FLG_WIDGET)) + return; + + if (enabled) { + if (!(gh->flags & GWIN_FLG_ENABLED)) { + gh->flags |= GWIN_FLG_ENABLED; + _gwidgetRedraw(gh); + } + } else { + if ((gh->flags & GWIN_FLG_ENABLED)) { + gh->flags &= ~GWIN_FLG_ENABLED; + _gwidgetRedraw(gh); + } + } +} + void gwinSetText(GHandle gh, const char *txt, bool_t useAlloc) { if (!(gh->flags & GWIN_FLG_WIDGET)) return; @@ -162,6 +164,7 @@ void gwinSetText(GHandle gh, const char *txt, bool_t useAlloc) { } gw->txt = txt ? txt : ""; + _gwidgetRedraw(gh); } const char *gwinGetText(GHandle gh) { @@ -177,6 +180,7 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) { gw->fnDraw = fn ? fn : wvmt->DefaultDraw; gw->fnParam = param; + _gwidgetRedraw(gh); } bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) { @@ -249,6 +253,6 @@ bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) { } #endif -#endif /* GFX_USE_GWIN */ +#endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */ /** @} */ diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 163e821d..3e790d38 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -11,90 +11,247 @@ #include "gwin/class_gwin.h" +// Needed if there is no window manager +#define MIN_WIN_WIDTH 1 +#define MIN_WIN_HEIGHT 1 + +/*----------------------------------------------- + * Data + *-----------------------------------------------*/ + static const gwinVMT basegwinVMT = { "GWIN", // The classname 0, // The destroy routine + 0, // The redraw routine 0, // The after-clear routine }; -static font_t defaultFont; static color_t defaultFgColor = White; static color_t defaultBgColor = Black; +#if GDISP_NEED_TEXT + static font_t defaultFont; +#endif +#if GWIN_NEED_WINDOWMANAGER + gfxQueueASync _GWINList; + extern GWindowManager GNullWindowManager; + static GWindowManager * cwm; +#endif + +/*----------------------------------------------- + * Helper Routines + *-----------------------------------------------*/ + +#if !GWIN_NEED_WINDOWMANAGER + static void _gwm_vis(GHandle gh) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } else + gwinClear(gh); + } + static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { + if (x < 0) { w += x; x = 0; } + if (y < 0) { h += y; y = 0; } + if (x > gdispGetWidth()-MIN_WIN_WIDTH) x = gdispGetWidth()-MIN_WIN_WIDTH; + if (y > gdispGetHeight()-MIN_WIN_HEIGHT) y = gdispGetHeight()-MIN_WIN_HEIGHT; + if (w < MIN_WIN_WIDTH) { w = MIN_WIN_WIDTH; } + if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; } + if (x+w > gdispGetWidth()) w = gdispGetWidth() - x; + if (y+h > gdispGetHeight()) h = gdispGetHeight() - y; + gh->x = x; gh->y = y; + gh->width = w; gh->height = h; + } +#endif + +/*----------------------------------------------- + * Class Routines + *-----------------------------------------------*/ + +void _gwinInit(void) { + #if GWIN_NEED_WINDOWMANAGER + gfxQueueASyncInit(&_GWINList); + cwm = &GNullWindowManager; + cwm->vmt->Init(); + #endif +} // Internal routine for use by GWIN components only -// Initialise a window creating it dynamicly if required. -GHandle _gwinInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt) { - coord_t w, h; - - // Check the window size against the screen size - w = gdispGetWidth(); - h = gdispGetHeight(); - if (x < 0) { width += x; x = 0; } - if (y < 0) { height += y; y = 0; } - if (x >= w || y >= h) return 0; - if (x+width > w) width = w - x; - if (y+height > h) height = h - y; - +// Initialise a window creating it dynamically if required. +GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary if (!pgw) { if (!(pgw = (GWindowObject *)gfxAlloc(size))) return 0; - pgw->flags = GWIN_FLG_DYNAMIC; + pgw->flags = flags|GWIN_FLG_DYNAMIC; } else - pgw->flags = 0; + pgw->flags = flags; // Initialise all basic fields pgw->vmt = vmt; - pgw->x = x; - pgw->y = y; - pgw->width = width; - pgw->height = height; pgw->color = defaultFgColor; pgw->bgcolor = defaultBgColor; #if GDISP_NEED_TEXT pgw->font = defaultFont; #endif + + #if GWIN_NEED_WINDOWMANAGER + if (!cwm->vmt->Add(pgw, x, y, width, height)) { + if ((pgw->flags & GWIN_FLG_DYNAMIC)) + gfxFree(pgw); + return 0; + } + #else + _gwm_redim(pgw, x, y, width, height); + if ((pgw->flags & GWIN_FLG_VISIBLE)) + _gwm_vis(pgw); + #endif + return (GHandle)pgw; } +/*----------------------------------------------- + * Routines that affect all windows + *-----------------------------------------------*/ + +#if GWIN_NEED_WINDOWMANAGER + void gwinSetWindowManager(struct GWindowManager *gwm) { + if (!gwm) + gwm = &GNullWindowManager; + if (cwm != gwm) { + cwm->vmt->DeInit(); + cwm = gwm; + cwm->vmt->Init(); + } + } +#endif + +void gwinSetDefaultColor(color_t clr) { + defaultFgColor = clr; +} + +void gwinSetDefaultBgColor(color_t bgclr) { + defaultBgColor = bgclr; +} + +#if GDISP_NEED_TEXT + void gwinSetDefaultFont(font_t font) { + defaultFont = font; + } +#endif + +/*----------------------------------------------- + * The GWindow Routines + *-----------------------------------------------*/ + GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) { - return _gwinInit(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT); + return _gwindowInit(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE); } void gwinDestroy(GHandle gh) { + // Remove from the window manager + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Delete(gh); + #endif + + // Class destroy routine if (gh->vmt->Destroy) gh->vmt->Destroy(gh); // Clean up the structure - if (gh->flags & GWIN_FLG_DYNAMIC) { - gh->flags = 0; // To be sure, to be sure + if (gh->flags & GWIN_FLG_DYNAMIC) gfxFree((void *)gh); - } + + gh->flags = 0; // To be sure, to be sure } const char *gwinGetClassName(GHandle gh) { return gh->vmt->classname; } -void gwinSetDefaultColor(color_t clr) { - defaultFgColor = clr; +void gwinSetVisible(GHandle gh, bool_t visible) { + if (visible) { + if (!(gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags |= GWIN_FLG_VISIBLE; + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Visible(gh); + #else + _gwm_vis(gh); + #endif + } + } else { + if ((gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags &= ~GWIN_FLG_VISIBLE; + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Visible(gh); + #endif + } + } } -void gwinSetDefaultBgColor(color_t bgclr) { - defaultBgColor = bgclr; +bool_t gwinGetVisible(GHandle gh) { + return (gh->flags & GWIN_FLG_VISIBLE) ? TRUE : FALSE; } -#if GDISP_NEED_TEXT - void gwinSetDefaultFont(font_t font) { - defaultFont = font; - } +void gwinMove(GHandle gh, coord_t x, coord_t y) { + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Redim(gh, x, y, gh->width, gh->height); + #else + _gwm_redim(gh, x, y, gh->width, gh->height); + #endif +} + +void gwinResize(GHandle gh, coord_t width, coord_t height) { + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Redim(gh, gh->x, gh->y, width, height); + #else + _gwm_redim(gh, gh->x, gh->y, width, height); + #endif +} +void gwinSetMinMax(GHandle gh, GWindowMinMax minmax) { + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->MinMax(gh, minmax); + #else + (void) gh; + (void) minmax; + #endif +} + +void gwinRaise(GHandle gh) { + #if GWIN_NEED_WINDOWMANAGER + cwm->vmt->Raise(gh); + #else + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } + #endif +} + +GWindowMinMax gwinGetMinMax(GHandle gh) { + if (gh->flags & GWIN_FLG_MINIMIZED) + return GWIN_MINIMIZE; + if (gh->flags & GWIN_FLG_MAXIMIZED) + return GWIN_MAXIMIZE; + return GWIN_NORMAL; +} + +#if GDISP_NEED_TEXT void gwinSetFont(GHandle gh, font_t font) { gh->font = font; } #endif void gwinClear(GHandle gh) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -104,6 +261,9 @@ void gwinClear(GHandle gh) { } void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -111,6 +271,9 @@ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) { } void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -118,6 +281,9 @@ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) { } void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -125,6 +291,9 @@ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { } void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -132,6 +301,9 @@ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) { } void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -140,6 +312,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_CIRCLE void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -147,6 +322,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -156,6 +334,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_ELLIPSE void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -163,6 +344,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -172,6 +356,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_ARC void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -179,6 +366,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -188,6 +378,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_PIXELREAD color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -197,7 +390,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_TEXT void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -205,7 +400,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -213,7 +410,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -221,7 +420,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -229,7 +430,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -237,7 +440,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) { - if (!gh->font) return; + if (!((gh->flags & GWIN_FLG_VISIBLE)) || !gh->font) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -247,6 +452,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_CONVEX_POLYGON void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -254,6 +462,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -263,6 +474,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #if GDISP_NEED_IMAGE gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return GDISP_IMAGE_ERR_OK; + #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index 90a8e9b4..fb8fdfd1 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -1,5 +1,6 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/gwidget.c \ + $(GFXLIB)/src/gwin/gwm.c \ $(GFXLIB)/src/gwin/console.c \ $(GFXLIB)/src/gwin/graph.c \ $(GFXLIB)/src/gwin/button.c \ diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c new file mode 100644 index 00000000..bc561345 --- /dev/null +++ b/src/gwin/gwm.c @@ -0,0 +1,144 @@ +/* + * 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" + +// Used by the NULL window manager +#define MIN_WIN_WIDTH 3 +#define MIN_WIN_HEIGHT 3 + +/*----------------------------------------------- + * The default window manager (GNullWindowManager) + *-----------------------------------------------*/ + +#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER + +#include "gwin/class_gwin.h" + +/*----------------------------------------------- + * Data + *-----------------------------------------------*/ + +static void WM_Init(void); +static void WM_DeInit(void); +static bool_t WM_Add(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); +static void WM_Delete(GHandle gh); +static void WM_Visible(GHandle gh); +static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); +static void WM_Raise(GHandle gh); +static void WM_MinMax(GHandle gh, GWindowMinMax minmax); + +static const gwmVMT GNullWindowManagerVMT = { + WM_Init, + WM_DeInit, + WM_Add, + WM_Delete, + WM_Visible, + WM_Redim, + WM_Raise, + WM_MinMax, +}; + +const GWindowManager GNullWindowManager = { + &GNullWindowManagerVMT, +}; + +/*----------------------------------------------- + * Window Manager Routines + *-----------------------------------------------*/ + +static void WM_Init(void) { + // We don't need to do anything here. + // A full window manager would move the windows around, add borders etc + + // clear the screen + // cycle through the windows already defined displaying them + // or cut all the window areas out of the screen and clear the remainder +} + +static void WM_DeInit(void) { + // We don't need to do anything here. + // A full window manager would remove any borders etc +} + +static bool_t WM_Add(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { + // Put it on the queue + gfxQueueASyncPut(&_GWINList, &gh->wmq); + + // Make sure the size is valid + WM_Redim(gh, x, y, w, h); + + // Display it if it is visible + WM_Visible(gh); + return TRUE; +} + +static void WM_Delete(GHandle gh) { + // A real window manager would make the window invisible + // (and then clear the area underneath) + + // Just remove it from the queue + gfxQueueASyncRemove(&_GWINList, &gh->wmq); +} + +static void WM_Visible(GHandle gh) { + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } else + gwinClear(gh); + // A real window manager would also redraw the borders + } + + // else + // A real window manager would make the window invisible + // (and then clear the area underneath) + +} + +static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { + // This is the simplest way of doing it - just clip the the screen + // If it won't fit on the screen move it around until it does. + if (x < 0) { w += x; x = 0; } + if (y < 0) { h += y; y = 0; } + if (x > gdispGetWidth()-MIN_WIN_WIDTH) x = gdispGetWidth()-MIN_WIN_WIDTH; + if (y > gdispGetHeight()-MIN_WIN_HEIGHT) y = gdispGetHeight()-MIN_WIN_HEIGHT; + if (w < MIN_WIN_WIDTH) { w = MIN_WIN_WIDTH; } + if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; } + if (x+w > gdispGetWidth()) w = gdispGetWidth() - x; + if (y+h > gdispGetHeight()) h = gdispGetHeight() - y; + gh->x = x; gh->y = y; + gh->width = w; gh->height = h; +} + +static void WM_MinMax(GHandle gh, GWindowMinMax minmax) { + (void)gh; (void) minmax; + // We don't support minimising, maximising or restoring +} + +static void WM_Raise(GHandle gh) { + // Take it off the list and then put it back on top + // The order of the list then reflects the z-order. + gfxQueueASyncRemove(&_GWINList, &gh->wmq); + gfxQueueASyncPut(&_GWINList, &gh->wmq); + + // Redraw the window + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } +} + +#endif /* GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER */ +/** @} */ diff --git a/src/gwin/slider.c b/src/gwin/slider.c index a0289d3d..1a1855a9 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -35,6 +35,7 @@ static const gwidgetVMT sliderVMT = { { "Slider", // The classname _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, gwinSliderDraw_Std, // The default drawing routine @@ -101,7 +102,7 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) { // No - restore the slider ResetDisplayPos(gsw); - gwinDraw(gh); + _gwidgetRedraw(gh); return; } #endif @@ -124,7 +125,7 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { } ResetDisplayPos(gsw); - gwinDraw(gh); + _gwidgetRedraw(gh); // Generate the event SendSliderEvent(gw); @@ -154,7 +155,7 @@ static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) { } // Update the display - gwinDraw(&gw->g); + _gwidgetRedraw(&gw->g); #undef gsw } -- cgit v1.2.3 From 2cb35d6815a0a12035f4792c266b688c77085620 Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 10 Jun 2013 17:18:01 +1000 Subject: Clean up GWIN Event assignment. Optimise event efficiency. --- src/ginput/dial.c | 2 + src/gqueue/gqueue.c | 8 ++ src/gwin/button.c | 58 ++++++++---- src/gwin/checkbox.c | 50 ++++++++--- src/gwin/console.c | 2 +- src/gwin/graph.c | 2 +- src/gwin/gwidget.c | 254 ++++++++++++++++++++++++++++++++++++++-------------- src/gwin/gwin.c | 9 +- src/gwin/slider.c | 91 +++++++++++++++---- 9 files changed, 355 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/ginput/dial.c b/src/ginput/dial.c index 24836910..2e52c224 100644 --- a/src/ginput/dial.c +++ b/src/ginput/dial.c @@ -57,6 +57,7 @@ static void DialCallback(uint16_t instance, uint16_t rawvalue) { pe->type = GEVENT_DIAL; pe->instance = instance; pe->value = pds->lastvalue; + pe->maxvalue = pds->max; geventSendEvent(psl); } } @@ -144,6 +145,7 @@ bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial) { pdial->type = GEVENT_DIAL; pdial->instance = instance; pdial->value = DialStatus[instance].lastvalue; + pdial->maxvalue = DialStatus[instance].max; return TRUE; } diff --git a/src/gqueue/gqueue.c b/src/gqueue/gqueue.c index 11d10c0a..002378b3 100644 --- a/src/gqueue/gqueue.c +++ b/src/gqueue/gqueue.c @@ -37,6 +37,7 @@ gfxSystemLock(); if ((pi = pqueue->head)) pqueue->head = pi->next; + pi->next = 0; gfxSystemUnlock(); return pi; } @@ -68,12 +69,14 @@ if (pqueue->head) { if (pqueue->head == pitem) { pqueue->head = pitem->next; + pitem->next = 0; } else { for(pi = pqueue->head; pi->next; pi = pi->next) { if (pi->next == pitem) { pi->next = pitem->next; if (pqueue->tail == pitem) pqueue->tail = pi; + pitem->next = 0; break; } } @@ -111,6 +114,7 @@ gfxSystemLock(); pi = pqueue->head; pqueue->head = pi->next; + pi->next = 0; gfxSytemUnlock(); return pi; } @@ -146,12 +150,14 @@ if (pqueue->head) { if (pqueue->head == pitem) { pqueue->head = pitem->next; + pitem->next = 0; } else { for(pi = pqueue->head; pi->next; pi = pi->next) { if (pi->next == pitem) { pi->next = pitem->next; if (pqueue->tail == pitem) pqueue->tail = pi; + pitem->next = 0; break; } } @@ -189,6 +195,7 @@ gfxSystemLock(); pi = pqueue->head; pqueue->head = pi->next; + pi->next = 0; gfxSytemUnlock(); gfxSemSignalI(&pi->sem); @@ -233,6 +240,7 @@ if (pqueue->head == pitem) { pqueue->head = pitem->next; found: + pitem->next = 0; gfxSystemUnlock(); gfxSemSignal(&pitem->sem); gfxSemDestroy(&pitem->sem); diff --git a/src/gwin/button.c b/src/gwin/button.c index 83b81b03..285a406c 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -32,8 +32,10 @@ // Prototypes for button VMT functions static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); -static void ToggleOff(GWidgetObject *gw, uint16_t instance); -static void ToggleOn(GWidgetObject *gw, uint16_t instance); +static void ToggleOff(GWidgetObject *gw, uint16_t role); +static void ToggleOn(GWidgetObject *gw, uint16_t role); +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); // The button VMT table static const gwidgetVMT buttonVMT = { @@ -43,16 +45,25 @@ static const gwidgetVMT buttonVMT = { _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, - gwinButtonDraw_3D, // The default drawing routine - MouseDown, // Process mouse down events - MouseUp, // Process mouse up events - 0, // Process mouse move events (NOT USED) - ToggleOff, // Process toggle off events - 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) + gwinButtonDraw_3D, // The default drawing routine + { + MouseDown, // Process mouse down events + MouseUp, // Process mouse up events + 0, // Process mouse move events (NOT USED) + }, + { + 1, // 1 toggle role + ToggleAssign, // Assign Toggles + ToggleGet, // Get Toggles + ToggleOff, // Process toggle off events + ToggleOn, // Process toggle on events + }, + { + 0, // No dial roles + 0, // Assign Dials (NOT USED) + 0, // Get Dials (NOT USED) + 0, // Process dial move events (NOT USED) + } }; // Default color scheme @@ -80,7 +91,7 @@ static void SendButtonEvent(GWidgetObject *gw) { // Trigger a GWIN Button Event psl = 0; - while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { + while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) { if (!(pe = geventGetEventBuffer(psl))) continue; pbe->type = GEVENT_GWIN_BUTTON; @@ -114,25 +125,36 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { } // A toggle off has occurred -static void ToggleOff(GWidgetObject *gw, uint16_t instance) { - (void) instance; +static void ToggleOff(GWidgetObject *gw, uint16_t role) { + (void) role; gw->g.flags &= ~GBUTTON_FLG_PRESSED; _gwidgetRedraw((GHandle)gw); } // A toggle on has occurred -static void ToggleOn(GWidgetObject *gw, uint16_t instance) { - (void) instance; +static void ToggleOn(GWidgetObject *gw, uint16_t role) { + (void) role; gw->g.flags |= GBUTTON_FLG_PRESSED; _gwidgetRedraw((GHandle)gw); // Trigger the event on button down (different than for mouse/touch) SendButtonEvent(gw); } +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GButtonObject *)gw)->toggle = instance; +} + +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GButtonObject *)gw)->toggle; +} + GHandle gwinCreateButton(GButtonObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gw = (GButtonObject *)_gwidgetInit((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT))) + if (!(gw = (GButtonObject *)_gwidgetCreate((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT))) return 0; + gw->toggle = GWIDGET_NO_INSTANCE; gw->c_up = GButtonDefaultColorsUp; gw->c_dn = GButtonDefaultColorsDown; gw->c_dis = GButtonDefaultColorsDisabled; diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 893dab9c..53e99e42 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -26,7 +26,9 @@ // Prototypes for button VMT functions static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); -static void ToggleOn(GWidgetObject *gw, uint16_t instance); +static void ToggleOn(GWidgetObject *gw, uint16_t role); +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); // The button VMT table static const gwidgetVMT checkboxVMT = { @@ -37,15 +39,24 @@ static const gwidgetVMT checkboxVMT = { 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) + { + MouseDown, // Process mouse down events + 0, // Process mouse up events (NOT USED) + 0, // Process mouse move events (NOT USED) + }, + { + 1, // 1 toggle role + ToggleAssign, // Assign Toggles + ToggleGet, // Get Toggles + 0, // Process toggle off events (NOT USED) + ToggleOn, // Process toggle on events + }, + { + 0, // No dial roles + 0, // Assign Dials (NOT USED) + 0, // Get Dials (NOT USED) + 0, // Process dial move events (NOT USED) + } }; static const GCheckboxColors defaultColors = { @@ -63,7 +74,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) { // Trigger a GWIN Checkbox Event psl = 0; - while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { + while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) { if (!(pe = geventGetEventBuffer(psl))) continue; pce->type = GEVENT_GWIN_CHECKBOX; @@ -84,17 +95,28 @@ static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { } // A toggle on has occurred -static void ToggleOn(GWidgetObject *gw, uint16_t instance) { - (void) instance; +static void ToggleOn(GWidgetObject *gw, uint16_t role) { + (void) role; gw->g.flags ^= GCHECKBOX_FLG_CHECKED; _gwidgetRedraw((GHandle)gw); SendCheckboxEvent(gw); } +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GCheckboxObject *)gw)->toggle = instance; +} + +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GCheckboxObject *)gw)->toggle; +} + 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))) + if (!(gb = (GCheckboxObject *)_gwidgetCreate((GWidgetObject *)gb, x, y, width, height, sizeof(GCheckboxObject), &checkboxVMT))) return 0; + gb->toggle = (uint16_t) -1; gb->c = defaultColors; // assign the default colors return (GHandle)gb; } diff --git a/src/gwin/console.c b/src/gwin/console.c index c4b2798d..6941295a 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -66,7 +66,7 @@ static const gwinVMT consoleVMT = { }; GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gc = (GConsoleObject *)_gwindowInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE))) + if (!(gc = (GConsoleObject *)_gwindowCreate((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE))) return 0; #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM gc->stream.vmt = &GWindowConsoleVMT; diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 393297e7..264c0c2c 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -165,7 +165,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gg = (GGraphObject *)_gwindowInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE))) + if (!(gg = (GGraphObject *)_gwindowCreate((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE))) return 0; gg->xorigin = gg->yorigin = 0; gg->lastx = gg->lasty = 0; diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 773a715d..ee7986d1 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -13,23 +13,25 @@ #include "gwin/class_gwin.h" +/* Our listener for events for widgets */ +static GListener gl; + /* 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) +/* Process an event */ +static void gwidgetEvent(void *param, GEvent *pe) { + #define gh QItem2GWindow(qi) #define pme ((GEventMouse *)pe) #define pte ((GEventToggle *)pe) #define pde ((GEventDial *)pe) - // check if widget is disabled - if ((gw->g.flags & (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) - return; - - // Process via AllEvents() if it is defined - if (wvmt->AllEvents) - wvmt->AllEvents(gw, pe); + const gfxQueueASyncItem * qi; + #if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL) + uint16_t role; + #endif + (void) param; // Process various events switch (pe->type) { @@ -37,76 +39,179 @@ static void gwidgetCallback(void *param, GEvent *pe) { #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->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) { - 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->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT) - && 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); + // Cycle through all windows + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + + // check if it a widget that is enabled and visible + if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) + continue; + + // Are we captured? + if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) { + if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) { + gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE; + if (wvmt->MouseUp) + wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y); + } 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->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT) + && 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); + // Cycle through all windows + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + + // check if it a widget that is enabled and visible + if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) + continue; + + for(role = 0; role < wvmt->toggleroles; role++) { + if (wvmt->ToggleGet(gw, role) == pte->instance) { + if (pte->on) { + if (wvmt->ToggleOn) + wvmt->ToggleOn(gw, role); + } else { + if (wvmt->ToggleOff) + wvmt->ToggleOff(gw, role); + } + } + } } break; #endif #if GFX_USE_GINPUT && GINPUT_NEED_DIAL case GEVENT_DIAL: - if (wvmt->DialMove) - wvmt->DialMove(gw, pde->instance, pde->value); + // Cycle through all windows + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + + // check if it a widget that is enabled and visible + if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) + continue; + + for(role = 0; role < wvmt->dialroles; role++) { + if (wvmt->DialGet(gw, role) == pte->instance) { + if (wvmt->DialMove) + wvmt->DialMove(gw, role, pde->value, pde->maxvalue); + } + } + } 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 *)_gwindowInit((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) +#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE + static GHandle FindToggleUser(uint16_t instance) { + #define gh QItem2GWindow(qi) + const gfxQueueASyncItem * qi; + uint16_t role; + + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget + continue; + + for(role = 0; role < wvmt->toggleroles; role++) { + if (wvmt->ToggleGet(gw, role) == instance) + return gh; + } + } + return 0; + #undef gh + } +#endif + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + static GHandle FindDialUser(uint16_t instance) { + #define gh QItem2GWindow(qi) + const gfxQueueASyncItem * qi; + uint16_t role; + + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget + continue; + + for(role = 0; role < wvmt->dialroles; role++) { + if (wvmt->DialGet(gw, role) == instance) + return gh; + } + } + return 0; + #undef gh + } +#endif + +void _gwidgetInit(void) { + geventListenerInit(&gl); + geventRegisterCallback(&gl, gwidgetEvent, 0); +} + +GHandle _gwidgetCreate(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwidgetVMT *vmt) { + if (!(pgw = (GWidgetObject *)_gwindowCreate((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) return 0; 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 GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL) + uint16_t role, instance; + #endif + // 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); + + #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE + // Detach any toggles from this object + for(role = 0; role < wvmt->toggleroles; role++) { + instance = wvmt->ToggleGet(gw, role); + if (instance != GWIDGET_NO_INSTANCE) { + wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE); + if (!FindToggleUser(instance)) + geventDetachSource(&gl, ginputGetToggle(instance)); + } + } + #endif + + #if GFX_USE_GINPUT && GINPUT_NEED_DIAL + // Detach any dials from this object + for(role = 0; role < wvmt->dialroles; role++) { + instance = wvmt->DialGet(gw, role); + if (instance != GWIDGET_NO_INSTANCE) { + wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE); + if (!FindDialUser(instance)) + geventDetachSource(&gl, ginputGetDial(instance)); + } + } + #endif + + // Remove any listeners on this object. geventDetachSourceListeners((GSourceHandle)gh); } @@ -183,76 +288,89 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) { _gwidgetRedraw(gh); } -bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) { - if (!(gh->flags & GWIN_FLG_WIDGET)) - return FALSE; - - return geventAttachSource(pl, (GSourceHandle)gh, flags); +bool_t gwinAttachListener(GListener *pl) { + return geventAttachSource(pl, GWIDGET_SOURCE, 0); } #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE - bool_t gwinAttachMouse(GHandle gh, uint16_t instance) { + bool_t gwinAttachMouse(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); + return geventAttachSource(&gl, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES); } #endif #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance) { GSourceHandle gsh; - unsigned flags; + uint16_t oi; + // Is this a widget 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) + // Is the role valid + if (role >= wvmt->toggleroles) return FALSE; + // Is this a valid device if (!(gsh = ginputGetToggle(instance))) return FALSE; - if (wvmt->AssignToggle && !wvmt->AssignToggle(gw, role, instance)) - return FALSE; + // Is this already done? + oi = wvmt->ToggleGet(gw, role); + if (instance == oi) + return TRUE; - return geventAttachSource(&gw->listener, gsh, flags); + // Remove the old instance + if (oi != GWIDGET_NO_INSTANCE) { + wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE); + if (!FindToggleUser(oi)) + geventDetachSource(&gl, ginputGetToggle(oi)); + } + + // Assign the new + wvmt->ToggleAssign(gw, role, instance); + return geventAttachSource(&gl, gsh, GLISTEN_TOGGLE_ON|GLISTEN_TOGGLE_OFF); } #endif #if GFX_USE_GINPUT && GINPUT_NEED_DIAL bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance) { GSourceHandle gsh; + uint16_t oi; if (!(gh->flags & GWIN_FLG_WIDGET)) return FALSE; - if (!wvmt->DialMove) + // Is the role valid + if (role >= wvmt->dialroles) return FALSE; + // Is this a valid device if (!(gsh = ginputGetDial(instance))) return FALSE; - if (wvmt->AssignDial && !wvmt->AssignDial(gw, role, instance)) - return FALSE; + // Is this already done? + oi = wvmt->DialGet(gw, role); + if (instance == oi) + return TRUE; - return geventAttachSource(&gw->listener, gsh, 0); + // Remove the old instance + if (oi != GWIDGET_NO_INSTANCE) { + wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE); + if (!FindDialUser(oi)) + geventDetachSource(&gl, ginputGetDial(oi)); + } + + // Assign the new + wvmt->DialAssign(gw, role, instance); + return geventAttachSource(&gl, gsh, 0); } #endif #endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */ /** @} */ - diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 3e790d38..98e61c52 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -70,6 +70,11 @@ static color_t defaultBgColor = Black; *-----------------------------------------------*/ void _gwinInit(void) { + #if GWIN_NEED_WIDGET + extern void _gwidgetInit(void); + + _gwidgetInit(); + #endif #if GWIN_NEED_WINDOWMANAGER gfxQueueASyncInit(&_GWINList); cwm = &GNullWindowManager; @@ -79,7 +84,7 @@ void _gwinInit(void) { // Internal routine for use by GWIN components only // Initialise a window creating it dynamically if required. -GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) { +GHandle _gwindowCreate(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary if (!pgw) { if (!(pgw = (GWindowObject *)gfxAlloc(size))) @@ -146,7 +151,7 @@ void gwinSetDefaultBgColor(color_t bgclr) { *-----------------------------------------------*/ GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) { - return _gwindowInit(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE); + return _gwindowCreate(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE); } void gwinDestroy(GHandle gh) { diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 1a1855a9..343973a2 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -25,10 +25,19 @@ #define GWIN_SLIDER_DEAD_BAND 5 #endif +#ifndef GWIN_SLIDER_TOGGLE_INC + #define GWIN_SLIDER_TOGGLE_INC 20 // How many toggles to go from minimum to maximum +#endif + // Prototypes for slider VMT functions static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y); -static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value); +static void ToggleOn(GWidgetObject *gw, uint16_t role); +static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max); +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); +static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); +static uint16_t DialGet(GWidgetObject *gw, uint16_t role); // The button VMT table static const gwidgetVMT sliderVMT = { @@ -38,16 +47,25 @@ static const gwidgetVMT sliderVMT = { _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, - gwinSliderDraw_Std, // The default drawing routine - MouseMove, // Process mouse down events (AS MOUSEMOVE) - MouseUp, // Process mouse up events - MouseMove, // Process mouse move events - 0, // Process toggle off events (NOT USED) - 0, // Process toggle on events (NOT USED) - DialMove, // Process dial move events - 0, // Process all events (NOT USED) - 0, // AssignToggle (NOT USED) - 0, // AssignDial (NOT USED) + gwinSliderDraw_Std, // The default drawing routine + { + 0, // Process mouse down events (NOT USED) + MouseUp, // Process mouse up events + MouseMove, // Process mouse move events + }, + { + 2, // 1 toggle role + ToggleAssign, // Assign Toggles + ToggleGet, // Get Toggles + 0, // Process toggle off events (NOT USED) + ToggleOn, // Process toggle on events + }, + { + 1, // 1 dial roles + DialAssign, // Assign Dials + DialGet, // Get Dials + DialMove, // Process dial move events + } }; static const GSliderColors GSliderDefaultColors = { @@ -66,7 +84,7 @@ static void SendSliderEvent(GWidgetObject *gw) { // Trigger a GWIN Button Event psl = 0; - while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { + while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) { if (!(pe = geventGetEventBuffer(psl))) continue; pse->type = GEVENT_GWIN_SLIDER; @@ -75,7 +93,7 @@ static void SendSliderEvent(GWidgetObject *gw) { geventSendEvent(psl); } - #undef pbe + #undef pse } // Reset the display position back to the value predicted by the saved slider position @@ -159,13 +177,28 @@ static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) { #undef gsw } +// A toggle on has occurred +static void ToggleOn(GWidgetObject *gw, uint16_t role) { + #define gsw ((GSliderObject *)gw) + + if (role) { + gwinSetSliderPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + SendSliderEvent(gw); + } else { + gwinSetSliderPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + SendSliderEvent(gw); + } + #undef gsw +} + // A dial move event -static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value) { +static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max) { #if GFX_USE_GINPUT && GINPUT_NEED_DIAL #define gsw ((GSliderObject *)gw) + (void) role; // Set the new position - gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/ginputGetDialRange(instance) + gsw->min); + gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min); ResetDisplayPos(gsw); gwinDraw(&gw->g); @@ -174,13 +207,37 @@ static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value) { SendSliderEvent(gw); #undef gsw #else - (void)gw; (void)instance; (void)value; + (void)gw; (void)role; (void)value; (void)max; #endif } +static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + if (role) + ((GSliderObject *)gw)->t_up = instance; + else + ((GSliderObject *)gw)->t_dn = instance; +} + +static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + return role ? ((GSliderObject *)gw)->t_up : ((GSliderObject *)gw)->t_dn; +} + +static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GSliderObject *)gw)->dial = instance; +} + +static uint16_t DialGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GSliderObject *)gw)->dial; +} + GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gs = (GSliderObject *)_gwidgetInit((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT))) + if (!(gs = (GSliderObject *)_gwidgetCreate((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT))) return 0; + gs->t_dn = (uint16_t) -1; + gs->t_up = (uint16_t) -1; + gs->dial = (uint16_t) -1; gs->c = GSliderDefaultColors; gs->min = 0; gs->max = 100; -- cgit v1.2.3 From 49b3e8f55ae135ce6475d1185db68e665430fe5e Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 15 Jun 2013 21:09:02 +1000 Subject: License header updates --- src/gadc/gadc.c | 2 +- src/gaudin/gaudin.c | 2 +- src/gaudout/gaudout.c | 2 +- src/gdisp/fonts.c | 2 +- src/gdisp/gdisp.c | 2 +- src/gdisp/image.c | 2 +- src/gdisp/image_bmp.c | 2 +- src/gdisp/image_gif.c | 2 +- src/gdisp/image_jpg.c | 2 +- src/gdisp/image_native.c | 2 +- src/gdisp/image_png.c | 2 +- src/gevent/gevent.c | 2 +- src/gfx.c | 23 +++++------------------ src/ginput/dial.c | 2 +- src/ginput/ginput.c | 2 +- src/ginput/keyboard.c | 2 +- src/ginput/mouse.c | 2 +- src/ginput/toggle.c | 2 +- src/gmisc/arrayops.c | 2 +- src/gmisc/trig.c | 23 +++++------------------ src/gos/chibios.c | 23 +++++------------------ src/gos/posix.c | 23 +++++------------------ src/gos/win32.c | 23 +++++------------------ src/gqueue/gqueue.c | 22 +++++----------------- src/gtimer/gtimer.c | 2 +- src/gwin/button.c | 2 +- src/gwin/checkbox.c | 2 +- src/gwin/console.c | 2 +- src/gwin/graph.c | 2 +- src/gwin/gwidget.c | 2 +- src/gwin/gwin.c | 2 +- src/gwin/gwm.c | 2 +- src/gwin/slider.c | 2 +- src/tdisp/tdisp.c | 2 +- 34 files changed, 58 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/gadc/gadc.c b/src/gadc/gadc.c index 36f4db6d..f3d99c85 100644 --- a/src/gadc/gadc.c +++ b/src/gadc/gadc.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gaudin/gaudin.c b/src/gaudin/gaudin.c index 2e87c628..270cd26e 100644 --- a/src/gaudin/gaudin.c +++ b/src/gaudin/gaudin.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gaudout/gaudout.c b/src/gaudout/gaudout.c index b418b158..4f8ac759 100644 --- a/src/gaudout/gaudout.c +++ b/src/gaudout/gaudout.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/fonts.c b/src/gdisp/fonts.c index 175828c6..6c73216c 100644 --- a/src/gdisp/fonts.c +++ b/src/gdisp/fonts.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index 9ba85d82..1b16ac53 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image.c b/src/gdisp/image.c index 50b641b6..fec05147 100644 --- a/src/gdisp/image.c +++ b/src/gdisp/image.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c index 51d1ce91..e54ad5e4 100644 --- a/src/gdisp/image_bmp.c +++ b/src/gdisp/image_bmp.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c index e8f4f422..3de47d03 100644 --- a/src/gdisp/image_gif.c +++ b/src/gdisp/image_gif.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image_jpg.c b/src/gdisp/image_jpg.c index 3a51ea5f..9ffd4b31 100644 --- a/src/gdisp/image_jpg.c +++ b/src/gdisp/image_jpg.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c index 8cc15817..694518c6 100644 --- a/src/gdisp/image_native.c +++ b/src/gdisp/image_native.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gdisp/image_png.c b/src/gdisp/image_png.c index 76e8f652..183b0734 100644 --- a/src/gdisp/image_png.c +++ b/src/gdisp/image_png.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gevent/gevent.c b/src/gevent/gevent.c index d83fa4d8..d73a574f 100644 --- a/src/gevent/gevent.c +++ b/src/gevent/gevent.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gfx.c b/src/gfx.c index 3856eea3..1791ef89 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1,22 +1,9 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * This file is subject to the terms of the GFX License. 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/gfx.c diff --git a/src/ginput/dial.c b/src/ginput/dial.c index 2e52c224..d978aa65 100644 --- a/src/ginput/dial.c +++ b/src/ginput/dial.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/ginput/ginput.c b/src/ginput/ginput.c index 96fa1449..4f2e72b0 100644 --- a/src/ginput/ginput.c +++ b/src/ginput/ginput.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/ginput/keyboard.c b/src/ginput/keyboard.c index 99aa90e8..a0f1f2cb 100644 --- a/src/ginput/keyboard.c +++ b/src/ginput/keyboard.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/ginput/mouse.c b/src/ginput/mouse.c index 334fdb6c..11b358f9 100644 --- a/src/ginput/mouse.c +++ b/src/ginput/mouse.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/ginput/toggle.c b/src/ginput/toggle.c index 2784a6ef..fdbfb8ce 100644 --- a/src/ginput/toggle.c +++ b/src/ginput/toggle.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gmisc/arrayops.c b/src/gmisc/arrayops.c index 460387f6..d433437e 100644 --- a/src/gmisc/arrayops.c +++ b/src/gmisc/arrayops.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gmisc/trig.c b/src/gmisc/trig.c index 2cd90a53..e49a4c22 100644 --- a/src/gmisc/trig.c +++ b/src/gmisc/trig.c @@ -1,22 +1,9 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * This file is subject to the terms of the GFX License. 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/gmisc/trig.c diff --git a/src/gos/chibios.c b/src/gos/chibios.c index 40e176ce..6ce06d94 100644 --- a/src/gos/chibios.c +++ b/src/gos/chibios.c @@ -1,22 +1,9 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * This file is subject to the terms of the GFX License. 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/gos/chibios.c diff --git a/src/gos/posix.c b/src/gos/posix.c index 9f6fe430..19a02560 100644 --- a/src/gos/posix.c +++ b/src/gos/posix.c @@ -1,22 +1,9 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * This file is subject to the terms of the GFX License. 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/gos/chibios.c diff --git a/src/gos/win32.c b/src/gos/win32.c index a1c5abcd..02ba1b67 100644 --- a/src/gos/win32.c +++ b/src/gos/win32.c @@ -1,22 +1,9 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * This file is subject to the terms of the GFX License. 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/gos/chibios.c diff --git a/src/gqueue/gqueue.c b/src/gqueue/gqueue.c index 002378b3..beb42a2e 100644 --- a/src/gqueue/gqueue.c +++ b/src/gqueue/gqueue.c @@ -1,22 +1,10 @@ /* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://chibios-gfx.com/license.html + */ - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ /** * @file src/gqueue/gqueue.c * @brief GQUEUE source file. diff --git a/src/gtimer/gtimer.c b/src/gtimer/gtimer.c index 1de1ce45..3eedc952 100644 --- a/src/gtimer/gtimer.c +++ b/src/gtimer/gtimer.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/button.c b/src/gwin/button.c index 285a406c..fc432cb4 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 53e99e42..0282df42 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/console.c b/src/gwin/console.c index 6941295a..38e2ea8b 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 264c0c2c..708b90cb 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index ee7986d1..9d634c58 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 98e61c52..b918d297 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index bc561345..5a533c40 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 343973a2..f2052524 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html diff --git a/src/tdisp/tdisp.c b/src/tdisp/tdisp.c index 17451deb..56122f8c 100644 --- a/src/tdisp/tdisp.c +++ b/src/tdisp/tdisp.c @@ -1,5 +1,5 @@ /* - * This file is subject to the terms of the GFX License, v1.0. If a copy of + * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://chibios-gfx.com/license.html -- cgit v1.2.3 From 8ed9e763c0f97f2946990a911bb940f8c80ff761 Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 24 Jun 2013 22:58:37 +1000 Subject: GWIN reduce Initialisation parameters and fix visibility issues --- src/gwin/button.c | 6 ++++-- src/gwin/checkbox.c | 6 ++++-- src/gwin/console.c | 6 ++++-- src/gwin/graph.c | 6 ++++-- src/gwin/gwidget.c | 8 ++++---- src/gwin/gwin.c | 54 +++++++++++++++++++++++++++-------------------------- src/gwin/gwm.c | 6 +++--- src/gwin/slider.c | 6 ++++-- 8 files changed, 55 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/gwin/button.c b/src/gwin/button.c index fc432cb4..4f823aa6 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -41,6 +41,7 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); static const gwidgetVMT buttonVMT = { { "Button", // The classname + sizeof(GButtonObject), // The object size _gwidgetDestroy, // The destroy routine _gwidgetRedraw, // The redraw routine 0, // The after-clear routine @@ -150,14 +151,15 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { return ((GButtonObject *)gw)->toggle; } -GHandle gwinCreateButton(GButtonObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gw = (GButtonObject *)_gwidgetCreate((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT))) +GHandle gwinCreateButton(GButtonObject *gw, GWidgetInit *pInit) { + if (!(gw = (GButtonObject *)_gwidgetCreate(&gw->w, pInit, &buttonVMT))) return 0; gw->toggle = GWIDGET_NO_INSTANCE; gw->c_up = GButtonDefaultColorsUp; gw->c_dn = GButtonDefaultColorsDown; gw->c_dis = GButtonDefaultColorsDisabled; + gwinSetVisible((GHandle)gw, pInit->g.show); return (GHandle)gw; } diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 0282df42..b4628ae0 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -34,6 +34,7 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); 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 @@ -112,12 +113,13 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { return ((GCheckboxObject *)gw)->toggle; } -GHandle gwinCreateCheckbox(GCheckboxObject *gb, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gb = (GCheckboxObject *)_gwidgetCreate((GWidgetObject *)gb, x, y, width, height, sizeof(GCheckboxObject), &checkboxVMT))) +GHandle gwinCreateCheckbox(GCheckboxObject *gb, GWidgetInit *pInit) { + if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT))) return 0; gb->toggle = (uint16_t) -1; gb->c = defaultColors; // assign the default colors + gwinSetVisible((GHandle)gb, pInit->g.show); return (GHandle)gb; } diff --git a/src/gwin/console.c b/src/gwin/console.c index 38e2ea8b..39e534b4 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -60,19 +60,21 @@ static void AfterClear(GWindowObject *gh) { static const gwinVMT consoleVMT = { "Console", // The classname + sizeof(GConsoleObject), // The object size 0, // The destroy routine 0, // The redraw routine AfterClear, // The after-clear routine }; -GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gc = (GConsoleObject *)_gwindowCreate((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE))) +GHandle gwinCreateConsole(GConsoleObject *gc, GWindowInit *pInit) { + if (!(gc = (GConsoleObject *)_gwindowCreate(&gc->g, pInit, &consoleVMT, 0))) return 0; #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM gc->stream.vmt = &GWindowConsoleVMT; #endif gc->cx = 0; gc->cy = 0; + gwinSetVisible((GHandle)gc, pInit->show); return (GHandle)gc; } diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 708b90cb..81ce1b5f 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -31,6 +31,7 @@ static const GGraphStyle GGraphDefaultStyle = { static const gwinVMT graphVMT = { "Graph", // The classname + sizeof(GGraphObject), // The object size 0, // The destroy routine 0, // The redraw routine 0, // The after-clear routine @@ -164,12 +165,13 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } } -GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gg = (GGraphObject *)_gwindowCreate((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE))) +GHandle gwinCreateGraph(GGraphObject *gg, GWindowInit *pInit) { + if (!(gg = (GGraphObject *)_gwindowCreate(&gg->g, pInit, &graphVMT, 0))) return 0; gg->xorigin = gg->yorigin = 0; gg->lastx = gg->lasty = 0; gwinGraphSetStyle((GHandle)gg, &GGraphDefaultStyle); + gwinSetVisible((GHandle)gg, pInit->show); return (GHandle)gg; } diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 9d634c58..2825bf4c 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -165,15 +165,15 @@ void _gwidgetInit(void) { geventRegisterCallback(&gl, gwidgetEvent, 0); } -GHandle _gwidgetCreate(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwidgetVMT *vmt) { - if (!(pgw = (GWidgetObject *)_gwindowCreate((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) +GHandle _gwidgetCreate(GWidgetObject *pgw, GWidgetInit *pInit, const gwidgetVMT *vmt) { + if (!(pgw = (GWidgetObject *)_gwindowCreate(&pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) return 0; - pgw->txt = ""; + pgw->txt = pInit->text ? pInit->text : ""; pgw->fnDraw = vmt->DefaultDraw; pgw->fnParam = 0; - return (GHandle)pgw; + return &pgw->g; } void _gwidgetDestroy(GHandle gh) { diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index b918d297..110d35cc 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -21,6 +21,7 @@ static const gwinVMT basegwinVMT = { "GWIN", // The classname + sizeof(GWindowObject), // The object size 0, // The destroy routine 0, // The redraw routine 0, // The after-clear routine @@ -51,17 +52,17 @@ static color_t defaultBgColor = Black; } else gwinClear(gh); } - static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { - if (x < 0) { w += x; x = 0; } - if (y < 0) { h += y; y = 0; } - if (x > gdispGetWidth()-MIN_WIN_WIDTH) x = gdispGetWidth()-MIN_WIN_WIDTH; - if (y > gdispGetHeight()-MIN_WIN_HEIGHT) y = gdispGetHeight()-MIN_WIN_HEIGHT; - if (w < MIN_WIN_WIDTH) { w = MIN_WIN_WIDTH; } - if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; } - if (x+w > gdispGetWidth()) w = gdispGetWidth() - x; - if (y+h > gdispGetHeight()) h = gdispGetHeight() - y; - gh->x = x; gh->y = y; - gh->width = w; gh->height = h; + static void _gwm_redim(GHandle gh, GWindowInit *pInit) { + gh->x = pInit->x; gh->y = pInit->y; + gh->width = pInit->width; gh->height = pInit->height; + if (gh->x < 0) { gh->width += gh->x; gh->x = 0; } + if (gh->y < 0) { gh->height += gh->y; gh->y = 0; } + if (gh->x > gdispGetWidth()-MIN_WIN_WIDTH) gh->x = gdispGetWidth()-MIN_WIN_WIDTH; + if (gh->y > gdispGetHeight()-MIN_WIN_HEIGHT) gh->y = gdispGetHeight()-MIN_WIN_HEIGHT; + if (gh->width < MIN_WIN_WIDTH) { gh->width = MIN_WIN_WIDTH; } + if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; } + if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x; + if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y; } #endif @@ -84,10 +85,10 @@ void _gwinInit(void) { // Internal routine for use by GWIN components only // Initialise a window creating it dynamically if required. -GHandle _gwindowCreate(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) { +GHandle _gwindowCreate(GWindowObject *pgw, GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary if (!pgw) { - if (!(pgw = (GWindowObject *)gfxAlloc(size))) + if (!(pgw = (GWindowObject *)gfxAlloc(vmt->size))) return 0; pgw->flags = flags|GWIN_FLG_DYNAMIC; } else @@ -101,17 +102,15 @@ GHandle _gwindowCreate(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, pgw->font = defaultFont; #endif - #if GWIN_NEED_WINDOWMANAGER - if (!cwm->vmt->Add(pgw, x, y, width, height)) { - if ((pgw->flags & GWIN_FLG_DYNAMIC)) - gfxFree(pgw); - return 0; - } - #else - _gwm_redim(pgw, x, y, width, height); - if ((pgw->flags & GWIN_FLG_VISIBLE)) - _gwm_vis(pgw); - #endif +#if GWIN_NEED_WINDOWMANAGER + if (!cwm->vmt->Add(pgw, pInit)) { + if ((pgw->flags & GWIN_FLG_DYNAMIC)) + gfxFree(pgw); + return 0; + } +#else + _gwm_redim(pgw, pInit->x, pInit->y, pInit->width, pInit->height); +#endif return (GHandle)pgw; } @@ -150,8 +149,11 @@ void gwinSetDefaultBgColor(color_t bgclr) { * The GWindow Routines *-----------------------------------------------*/ -GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) { - return _gwindowCreate(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE); +GHandle gwinCreateWindow(GWindowObject *pgw, GWindowInit *pInit) { + if (!(pgw = _gwindowCreate(pgw, pInit, &basegwinVMT, 0))) + return 0; + gwinSetVisible(pgw, pInit->show); + return pgw; } void gwinDestroy(GHandle gh) { diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index 5a533c40..c3405d83 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -25,7 +25,7 @@ static void WM_Init(void); static void WM_DeInit(void); -static bool_t WM_Add(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); +static bool_t WM_Add(GHandle gh, GWindowInit *pInit); static void WM_Delete(GHandle gh); static void WM_Visible(GHandle gh); static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); @@ -65,12 +65,12 @@ static void WM_DeInit(void) { // A full window manager would remove any borders etc } -static bool_t WM_Add(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { +static bool_t WM_Add(GHandle gh, GWindowInit *pInit) { // Put it on the queue gfxQueueASyncPut(&_GWINList, &gh->wmq); // Make sure the size is valid - WM_Redim(gh, x, y, w, h); + WM_Redim(gh, pInit->x, pInit->y, pInit->width, pInit->height); // Display it if it is visible WM_Visible(gh); diff --git a/src/gwin/slider.c b/src/gwin/slider.c index f2052524..08dd6ca7 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -43,6 +43,7 @@ static uint16_t DialGet(GWidgetObject *gw, uint16_t role); static const gwidgetVMT sliderVMT = { { "Slider", // The classname + sizeof(GSliderObject), // The object size _gwidgetDestroy, // The destroy routine _gwidgetRedraw, // The redraw routine 0, // The after-clear routine @@ -232,8 +233,8 @@ static uint16_t DialGet(GWidgetObject *gw, uint16_t role) { return ((GSliderObject *)gw)->dial; } -GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) { - if (!(gs = (GSliderObject *)_gwidgetCreate((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT))) +GHandle gwinCreateSlider(GSliderObject *gs, GWidgetInit *pInit) { + if (!(gs = (GSliderObject *)_gwidgetCreate(&gs->w, pInit, &sliderVMT))) return 0; gs->t_dn = (uint16_t) -1; gs->t_up = (uint16_t) -1; @@ -243,6 +244,7 @@ GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, gs->max = 100; gs->pos = 0; ResetDisplayPos(gs); + gwinSetVisible((GHandle)gs, pInit->g.show); return (GHandle)gs; } -- cgit v1.2.3 From 57d3632e36fe2ab55589207a84c29544b15bd2c3 Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 1 Jul 2013 17:34:13 +1000 Subject: GWIN Init structures are const (read-only to GWIN) --- src/gwin/button.c | 2 +- src/gwin/checkbox.c | 2 +- src/gwin/console.c | 2 +- src/gwin/graph.c | 2 +- src/gwin/gwidget.c | 2 +- src/gwin/gwin.c | 6 +++--- src/gwin/slider.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gwin/button.c b/src/gwin/button.c index 4f823aa6..303d1078 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -151,7 +151,7 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { return ((GButtonObject *)gw)->toggle; } -GHandle gwinCreateButton(GButtonObject *gw, GWidgetInit *pInit) { +GHandle gwinCreateButton(GButtonObject *gw, const GWidgetInit *pInit) { if (!(gw = (GButtonObject *)_gwidgetCreate(&gw->w, pInit, &buttonVMT))) return 0; diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index b4628ae0..62f4c55b 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -113,7 +113,7 @@ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { return ((GCheckboxObject *)gw)->toggle; } -GHandle gwinCreateCheckbox(GCheckboxObject *gb, GWidgetInit *pInit) { +GHandle gwinCreateCheckbox(GCheckboxObject *gb, const GWidgetInit *pInit) { if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT))) return 0; diff --git a/src/gwin/console.c b/src/gwin/console.c index 39e534b4..105cc79d 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -66,7 +66,7 @@ static const gwinVMT consoleVMT = { AfterClear, // The after-clear routine }; -GHandle gwinCreateConsole(GConsoleObject *gc, GWindowInit *pInit) { +GHandle gwinCreateConsole(GConsoleObject *gc, const GWindowInit *pInit) { if (!(gc = (GConsoleObject *)_gwindowCreate(&gc->g, pInit, &consoleVMT, 0))) return 0; #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 81ce1b5f..049f52e0 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -165,7 +165,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } } -GHandle gwinCreateGraph(GGraphObject *gg, GWindowInit *pInit) { +GHandle gwinCreateGraph(GGraphObject *gg, const GWindowInit *pInit) { if (!(gg = (GGraphObject *)_gwindowCreate(&gg->g, pInit, &graphVMT, 0))) return 0; gg->xorigin = gg->yorigin = 0; diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 2825bf4c..a2b82f1d 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -165,7 +165,7 @@ void _gwidgetInit(void) { geventRegisterCallback(&gl, gwidgetEvent, 0); } -GHandle _gwidgetCreate(GWidgetObject *pgw, GWidgetInit *pInit, const gwidgetVMT *vmt) { +GHandle _gwidgetCreate(GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt) { if (!(pgw = (GWidgetObject *)_gwindowCreate(&pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) return 0; diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 110d35cc..c1122b3f 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -52,7 +52,7 @@ static color_t defaultBgColor = Black; } else gwinClear(gh); } - static void _gwm_redim(GHandle gh, GWindowInit *pInit) { + static void _gwm_redim(GHandle gh, const GWindowInit *pInit) { gh->x = pInit->x; gh->y = pInit->y; gh->width = pInit->width; gh->height = pInit->height; if (gh->x < 0) { gh->width += gh->x; gh->x = 0; } @@ -85,7 +85,7 @@ void _gwinInit(void) { // Internal routine for use by GWIN components only // Initialise a window creating it dynamically if required. -GHandle _gwindowCreate(GWindowObject *pgw, GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) { +GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary if (!pgw) { if (!(pgw = (GWindowObject *)gfxAlloc(vmt->size))) @@ -149,7 +149,7 @@ void gwinSetDefaultBgColor(color_t bgclr) { * The GWindow Routines *-----------------------------------------------*/ -GHandle gwinCreateWindow(GWindowObject *pgw, GWindowInit *pInit) { +GHandle gwinCreateWindow(GWindowObject *pgw, const GWindowInit *pInit) { if (!(pgw = _gwindowCreate(pgw, pInit, &basegwinVMT, 0))) return 0; gwinSetVisible(pgw, pInit->show); diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 08dd6ca7..2dfa3a7c 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -233,7 +233,7 @@ static uint16_t DialGet(GWidgetObject *gw, uint16_t role) { return ((GSliderObject *)gw)->dial; } -GHandle gwinCreateSlider(GSliderObject *gs, GWidgetInit *pInit) { +GHandle gwinCreateSlider(GSliderObject *gs, const GWidgetInit *pInit) { if (!(gs = (GSliderObject *)_gwidgetCreate(&gs->w, pInit, &sliderVMT))) return 0; gs->t_dn = (uint16_t) -1; -- cgit v1.2.3 From de27a6c2db6f5fb97b3a5d07395a629c879abfbc Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Mon, 1 Jul 2013 10:10:45 +0200 Subject: image widget implementation work in progress --- src/gwin/gwin.mk | 1 + src/gwin/image.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/gwin/image.c (limited to 'src') diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index fb8fdfd1..9c114b3b 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -6,4 +6,5 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/button.c \ $(GFXLIB)/src/gwin/slider.c \ $(GFXLIB)/src/gwin/checkbox.c \ + $(GFXLIB)/src/gwin/image.c \ diff --git a/src/gwin/image.c b/src/gwin/image.c new file mode 100644 index 00000000..35a0471d --- /dev/null +++ b/src/gwin/image.c @@ -0,0 +1,63 @@ +/* + * This file is subject to the terms of the GFX License. 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/image.c + * @brief GWIN sub-system image code. + */ + +#include "gfx.h" + +#if GFX_USE_GWIN && GWIN_NEED_IMAGE + +#include "gwin/class_gwin.h" + +static void _destroy(GWindowObject *gh) { + (void)gh; + + return; +} + +static void _redraw(GWindowObject *gh) { + (void)gh; + + return; +} + +static void _afterClear(GWindowObject *gh) { + ((GImageWidget *)gh)->cx = 0; + ((GImageWidget *)gh)->cy = 0; + + return; +} + +static const gwinVMT imageVMT = { + "Image", // The class name + sizeof(GImageWidget), // The object size + _destroy, // The destroy routine + _redraw, // The redraw routine + _afterClear, // The after-clear routine +}; + +GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit) { + if (!(widget = (GImageWidget *)_gwindowCreate(&widget->g, pInit, &imageVMT, 0))) + return 0; + + widget->cx = 0; + widget->cy = 0; + gwinSetVisible((GHandle)widget, pInit->show); + + return (GHandle)widget; +} + +void gwinImageDisplay(GImageWidget *widget, gdispImage *image) { + +} + +#endif // GFX_USE_GWIN && GWIN_NEED_IMAGE +/** @} */ + -- cgit v1.2.3 From 6e59a6cf6ca75bf3ca72649f3f57e03e3e321c36 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Mon, 1 Jul 2013 17:40:31 +0200 Subject: image widget first release --- src/gwin/gwin.c | 12 ------------ src/gwin/image.c | 58 +++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index c1122b3f..75f1b2d3 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -479,18 +479,6 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } #endif -#if GDISP_NEED_IMAGE - gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { - if (!((gh->flags & GWIN_FLG_VISIBLE))) - return GDISP_IMAGE_ERR_OK; - - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif - return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy); - } -#endif - #endif /* GFX_USE_GWIN */ /** @} */ diff --git a/src/gwin/image.c b/src/gwin/image.c index 35a0471d..64a27840 100644 --- a/src/gwin/image.c +++ b/src/gwin/image.c @@ -16,21 +16,17 @@ #include "gwin/class_gwin.h" -static void _destroy(GWindowObject *gh) { - (void)gh; +#define widget(gh) ((GImageWidget*)gh) - return; -} - -static void _redraw(GWindowObject *gh) { - (void)gh; +static void _destroy(GWindowObject *gh) { + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); return; } static void _afterClear(GWindowObject *gh) { - ((GImageWidget *)gh)->cx = 0; - ((GImageWidget *)gh)->cy = 0; + (void)gh; return; } @@ -39,7 +35,7 @@ static const gwinVMT imageVMT = { "Image", // The class name sizeof(GImageWidget), // The object size _destroy, // The destroy routine - _redraw, // The redraw routine + 0, _afterClear, // The after-clear routine }; @@ -47,17 +43,53 @@ GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit) { if (!(widget = (GImageWidget *)_gwindowCreate(&widget->g, pInit, &imageVMT, 0))) return 0; - widget->cx = 0; - widget->cy = 0; + widget->image = gfxAlloc(sizeof(gdispImage)); + if (widget->image == NULL) + return 0; + + widget->g.x = pInit->x; + widget->g.y = pInit->y; + widget->g.width = pInit->width; + widget->g.height = pInit->height; + widget->bgColor = Black; gwinSetVisible((GHandle)widget, pInit->show); return (GHandle)widget; } -void gwinImageDisplay(GImageWidget *widget, gdispImage *image) { +bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { + bool_t err; + err = gdispImageSetMemoryReader(widget(gh)->image, memory); + gdispImageOpen(widget(gh)->image); + + return err; } +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__) +bool_t gwinImageOpenFile(GHandle gh, const char* filename) { + return gdispImageSetFileReader(widget(gh)->image, filename); +} +#endif + +#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) +bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { + return gdispImageSetBaseFileStreamReader(widget(gh)->image, streamPtr); +} +#endif + +gdispImageError gwinImageCache(GHandle gh) { + return gdispImageCache(widget(gh)->image); +} + +void gwinImageSetBgColor(GHandle gh, color_t bgColor) { + widget(gh)->bgColor = bgColor; +} + +void gwinImageDraw(GHandle gh) { + gdispImageDraw(widget(gh)->image, widget(gh)->g.x, widget(gh)->g.y, widget(gh)->g.width, widget(gh)->g.height, 0, 0); +} + #endif // GFX_USE_GWIN && GWIN_NEED_IMAGE /** @} */ -- cgit v1.2.3 From f188613d30977ac44f89e4eab9c5f9784169f576 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Mon, 1 Jul 2013 17:58:05 +0200 Subject: fixed image drawing boundries --- src/gwin/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gwin/image.c b/src/gwin/image.c index 64a27840..bba92238 100644 --- a/src/gwin/image.c +++ b/src/gwin/image.c @@ -87,7 +87,7 @@ void gwinImageSetBgColor(GHandle gh, color_t bgColor) { } void gwinImageDraw(GHandle gh) { - gdispImageDraw(widget(gh)->image, widget(gh)->g.x, widget(gh)->g.y, widget(gh)->g.width, widget(gh)->g.height, 0, 0); + gdispImageDraw(widget(gh)->image, widget(gh)->g.x, widget(gh)->g.y, widget(gh)->image->width, widget(gh)->image->height, 0, 0); } #endif // GFX_USE_GWIN && GWIN_NEED_IMAGE -- cgit v1.2.3 From 931c46526521c5fd36856b1fc1990136d5f7f255 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Mon, 1 Jul 2013 19:53:58 +0200 Subject: GLabel work in progress --- src/gwin/gwin.mk | 3 ++- src/gwin/label.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/gwin/label.c (limited to 'src') diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index 9c114b3b..9a81728e 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -7,4 +7,5 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/slider.c \ $(GFXLIB)/src/gwin/checkbox.c \ $(GFXLIB)/src/gwin/image.c \ - + $(GFXLIB)/src/gwin/label.c \ + diff --git a/src/gwin/label.c b/src/gwin/label.c new file mode 100644 index 00000000..e31a3de6 --- /dev/null +++ b/src/gwin/label.c @@ -0,0 +1,67 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://chibios-gfx.com/license.html + */ + +/** + * @file include/gwin/label.h + * @brief GWIN label widget header file. + * + * @defgroup Label Label + * @ingroup GWIN + * + * @{ + */ + +#include "gfx.h" + +#if GFX_USE_GWIN && GWIN_NEED_LABEL + +#include "gwin/class_gwin.h" + +#define widget(gh) ((GLabelWidget*)gh) + +static void _destroy(GWindowObject *gh) { + (void)gh; + + return; +} + +static void _redraw(GWindowObject *gh) { + (void)gh; + + return; +} + +static void _afterClear(GWindowObject *gh) { + (void)gh; + + return; +} + +GHandle gwinLabelCreate(GLabelWidget *widget, GWindowInit *pInit) { + +} + +void gwinLabelSetColor(GHandle gh, color_t color) { + widget(gh)->g.color = color; +} + +void gwinLabelSetBgColor(GHandle gh, color_t bgColor) { + widget(gh)->g.bgcolor = bgColor; +} + +void gwinLabelSetText(GHandle gh, char* text) { + widget(gh)->text = text; + + gwinLabelDraw(gh); +} + +void gwinLabelDraw(GHandle gh) { + +} + +#endif // GFX_USE_GWIN && GFX_NEED_LABEL + -- cgit v1.2.3 From ad57ab7967d0e0ee3cfce8746b0c4969cfe970fd Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Tue, 2 Jul 2013 08:29:38 +0200 Subject: wip --- src/gwin/label.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gwin/label.c b/src/gwin/label.c index e31a3de6..8c892217 100644 --- a/src/gwin/label.c +++ b/src/gwin/label.c @@ -41,8 +41,25 @@ static void _afterClear(GWindowObject *gh) { return; } +static const gwinVMT labelVMT = { + "Label", // The class name + sizeof(GLabelWidget), // The object size + _destroy, // The destroy routine + 0, // The redraw routine + _afterClear // The after-clear routine +}; + GHandle gwinLabelCreate(GLabelWidget *widget, GWindowInit *pInit) { + if (!(widget = (GLabelWidget *)_gwindowCreate(&widget->g, pInit, &labelVMT, 0))) + return 0; + + widget->g.x = pInit->x; + widget->g.y = pInit->y; + widget->g.width = pInit->width; + widget->g.height = pInit->height; + gwinSetVisible((GHandle)widget, pInit->show); + return (GHandle)widget; } void gwinLabelSetColor(GHandle gh, color_t color) { @@ -53,14 +70,24 @@ void gwinLabelSetBgColor(GHandle gh, color_t bgColor) { widget(gh)->g.bgcolor = bgColor; } -void gwinLabelSetText(GHandle gh, char* text) { +void gwinLabelSetFont(GHandle gh, font_t font) { + widget(gh)->g.font = font; +} + +void gwinLabelSetText(GHandle gh, const char* text) { widget(gh)->text = text; gwinLabelDraw(gh); } void gwinLabelDraw(GHandle gh) { - + gdispFillString( widget(gh)->g.x, + widget(gh)->g.y, + widget(gh)->text, + widget(gh)->g.font, + widget(gh)->g.color, + widget(gh)->g.bgcolor + ); } #endif // GFX_USE_GWIN && GFX_NEED_LABEL -- cgit v1.2.3 From 3f80e1f89dbeec06dd97a914d6851ad4596b1743 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Tue, 2 Jul 2013 19:26:48 +0200 Subject: label work in progress - not working anymore --- src/gwin/gwin.c | 4 ++ src/gwin/label.c | 120 +++++++++++++++++++++++++++++-------------------------- 2 files changed, 67 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 75f1b2d3..f080ac64 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -143,6 +143,10 @@ void gwinSetDefaultBgColor(color_t bgclr) { void gwinSetDefaultFont(font_t font) { defaultFont = font; } + + font_t gwinGetDefaultFont(void) { + return defaultFont; + } #endif /*----------------------------------------------- diff --git a/src/gwin/label.c b/src/gwin/label.c index 8c892217..7f8ab814 100644 --- a/src/gwin/label.c +++ b/src/gwin/label.c @@ -21,74 +21,80 @@ #include "gwin/class_gwin.h" -#define widget(gh) ((GLabelWidget*)gh) - -static void _destroy(GWindowObject *gh) { - (void)gh; - - return; -} - -static void _redraw(GWindowObject *gh) { - (void)gh; - - return; -} +#define widget(gh) ((GLabelWidget*)gh) +#define GLABEL_FLG_WAUTO (GWIN_FIRST_CONTROL_FLAG<<0) +#define GLABEL_FLG_HAUTO (GWIN_FIRST_CONTROL_FLAG<<1) + +static void gwinLabelDefaultDraw(GHandle gh) { + // if( check if auto flag is set ) + // if( call current size != font size ) + // gwinResize(); + + gdispFillString( widget(gh)->w.g.x, + widget(gh)->w.g.y, + widget(gh)->w.txt, + widget(gh)->w.g.font, + widget(gh)->w.g.color, + widget(gh)->w.g.bgcolor + ); -static void _afterClear(GWindowObject *gh) { - (void)gh; + gdispFillArea( widget(gh)->w.g.x, widget(gh)->w.g.y, widget(gh)->w.g.width, widget(gh)->w.g.height, Green); - return; + printf("Text: %s\r\n", widget(gh)->w.txt); } -static const gwinVMT labelVMT = { - "Label", // The class name - sizeof(GLabelWidget), // The object size - _destroy, // The destroy routine - 0, // The redraw routine - _afterClear // The after-clear routine +static const gwidgetVMT labelVMT = { + { + "Label", // The class name + sizeof(GLabelWidget), // The object size + _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine + 0, // The after-clear routine + }, + gwinLabelDefaultDraw, // default drawing routine + { + 0, // Process mose down events (NOT USED) + 0, // Process mouse up events (NOT USED) + 0, // Process mouse move events (NOT USED) + }, + { + 0, // No toggle role + 0, // Assign Toggles (NOT USED) + 0, // Get Toggles (NOT USED) + 0, // Process toggle off event (NOT USED) + 0, // Process toggle on event (NOT USED) + }, + { + 0, // No dial roles + 0, // Assign Dials (NOT USED) + 0, // Get Dials (NOT USED) + 0, // Procees dial move events (NOT USED) + } }; -GHandle gwinLabelCreate(GLabelWidget *widget, GWindowInit *pInit) { - if (!(widget = (GLabelWidget *)_gwindowCreate(&widget->g, pInit, &labelVMT, 0))) +GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) { + uint16_t flags = 0; + + // auto assign width + if (pInit->g.width <= 0) { + flags |= GLABEL_FLG_WAUTO; + pInit->g.width = gdispGetStringWidth(pInit->text, gwinGetDefaultFont()); + } + + // auto assign height + if (pInit->g.height <= 0) { + flags |= GLABEL_FLG_HAUTO; + pInit->g.height = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight); + } + + if (!(widget = (GLabelWidget *)_gwidgetCreate(&widget->w, pInit, &labelVMT))) return 0; - widget->g.x = pInit->x; - widget->g.y = pInit->y; - widget->g.width = pInit->width; - widget->g.height = pInit->height; - gwinSetVisible((GHandle)widget, pInit->show); + gwinLabelDefaultDraw((GHandle)widget); + widget->w.g.flags |= flags; return (GHandle)widget; } -void gwinLabelSetColor(GHandle gh, color_t color) { - widget(gh)->g.color = color; -} - -void gwinLabelSetBgColor(GHandle gh, color_t bgColor) { - widget(gh)->g.bgcolor = bgColor; -} - -void gwinLabelSetFont(GHandle gh, font_t font) { - widget(gh)->g.font = font; -} - -void gwinLabelSetText(GHandle gh, const char* text) { - widget(gh)->text = text; - - gwinLabelDraw(gh); -} - -void gwinLabelDraw(GHandle gh) { - gdispFillString( widget(gh)->g.x, - widget(gh)->g.y, - widget(gh)->text, - widget(gh)->g.font, - widget(gh)->g.color, - widget(gh)->g.bgcolor - ); -} - #endif // GFX_USE_GWIN && GFX_NEED_LABEL -- cgit v1.2.3 From 09a359813f0abe8f99c32dadfa1ac2c68356ddfd Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 4 Jul 2013 00:20:32 +1000 Subject: Label, Image and Window Manager changes --- src/gwin/gimage.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gwin/gwin.c | 18 ++++++ src/gwin/gwin.mk | 2 +- src/gwin/gwm.c | 44 ++++++++++---- src/gwin/image.c | 95 ------------------------------ src/gwin/label.c | 44 ++++++++------ 6 files changed, 251 insertions(+), 125 deletions(-) create mode 100644 src/gwin/gimage.c delete mode 100644 src/gwin/image.c (limited to 'src') diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c new file mode 100644 index 00000000..464bc595 --- /dev/null +++ b/src/gwin/gimage.c @@ -0,0 +1,173 @@ +/* + * This file is subject to the terms of the GFX License. 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/image.c + * @brief GWIN sub-system image code. + */ + +#include "gfx.h" + +#if GFX_USE_GWIN && GWIN_NEED_IMAGE + +#include "gwin/class_gwin.h" + +#define widget(gh) ((GImageWidget*)gh) + +static void _destroy(GWindowObject *gh) { + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); +} + +static void _redraw(GHandle gh) { + coord_t x, y, w, h, dx, dy; + + // The default display area + x = gh->x; + y = gh->y; + w = gh->width; + h = gh->height; + + // If the image isn't open just clear the area + if (!gdispImageIsOpen(&widget(gh)->image)) { + gdispFillArea(x, y, w, h, gh->bgcolor); + return; + } + + // Center horizontally if the area is larger than the image + if (widget(gh)->image.width < w) { + w = widget(gh)->image.width; + dx = (gh->width-w)/2; + x += dx; + if (dx) + gdispFillArea(gh->x, y, dx, h, gh->bgcolor); + gdispFillArea(x+w, y, gh->width-dx-w, h, gh->bgcolor); + dx = 0; + } + + // Center image horizontally if the area is smaller than the image + else if (widget(gh)->image.width > w) { + dx = (widget(gh)->image.width - w)/2; + } + + // Center vertically if the area is larger than the image + if (widget(gh)->image.height < h) { + h = widget(gh)->image.height; + dy = (gh->height-h)/2; + y += dy; + if (dy) + gdispFillArea(x, gh->y, w, dy, gh->bgcolor); + gdispFillArea(x, y+h, w, gh->height-dy-h, gh->bgcolor); + dy = 0; + } + + // Center image vertically if the area is smaller than the image + else if (widget(gh)->image.height > h) { + dy = (widget(gh)->image.height - h)/2; + } + + // Reset the background color in case it has changed + gdispImageSetBgColor(&widget(gh)->image, gh->bgcolor); + + // Display the image + gdispImageDraw(&widget(gh)->image, x, y, w, h, dx, dy); +} + + +static const gwinVMT imageVMT = { + "Image", // The class name + sizeof(GImageWidget), // The object size + _destroy, // The destroy routine + _redraw, // The redraw routine + 0, // The after-clear routine +}; + +GHandle gwinImageCreate(GImageWidget *gobj, GWindowInit *pInit) { + if (!(gobj = (GImageWidget *)_gwindowCreate(&gobj->g, pInit, &imageVMT, 0))) + return 0; + + // Ensure the gdispImageIsOpen() gives valid results + gobj->image.type = 0; + + gwinSetVisible((GHandle)gobj, pInit->show); + + return (GHandle)gobj; +} + +bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); + + if (!gdispImageSetMemoryReader(&widget(gh)->image, memory)) + return FALSE; + + if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) + return FALSE; + + if ((gh->flags & GWIN_FLG_VISIBLE)) { + // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw + // but we put it in for safety anyway + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + _redraw(gh); + } + return TRUE; +} + +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__) +bool_t gwinImageOpenFile(GHandle gh, const char* filename) { + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); + + if (!gdispImageSetFileReader(&widget(gh)->image, filename)) + return FALSE; + + if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) + return FALSE; + + if ((gh->flags & GWIN_FLG_VISIBLE)) { + // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw + // but we put it in for safety anyway + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + _redraw(gh); + } + return TRUE; +} +#endif + +#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) +bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); + + if (!gdispImageSetBaseFileStreamReader(&widget(gh)->image, streamPtr)) + return FALSE; + + if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) + return FALSE; + + if ((gh->flags & GWIN_FLG_VISIBLE)) { + // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw + // but we put it in for safety anyway + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + _redraw(gh); + } + return TRUE; +} +#endif + +gdispImageError gwinImageCache(GHandle gh) { + return gdispImageCache(&widget(gh)->image); +} + +#endif // GFX_USE_GWIN && GWIN_NEED_IMAGE +/** @} */ diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index f080ac64..de1673cb 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -63,6 +63,16 @@ static color_t defaultBgColor = Black; if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; } if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x; if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y; + + // Redraw the window + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } } #endif @@ -135,10 +145,18 @@ void gwinSetDefaultColor(color_t clr) { defaultFgColor = clr; } +color_t gwinGetDefaultColor(void) { + return defaultFgColor; +} + void gwinSetDefaultBgColor(color_t bgclr) { defaultBgColor = bgclr; } +color_t gwinGetDefaultBgColor(void) { + return defaultBgColor; +} + #if GDISP_NEED_TEXT void gwinSetDefaultFont(font_t font) { defaultFont = font; diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index 9a81728e..b9e6a9ee 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -6,6 +6,6 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/button.c \ $(GFXLIB)/src/gwin/slider.c \ $(GFXLIB)/src/gwin/checkbox.c \ - $(GFXLIB)/src/gwin/image.c \ + $(GFXLIB)/src/gwin/gimage.c \ $(GFXLIB)/src/gwin/label.c \ diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index c3405d83..75b08be6 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -25,7 +25,7 @@ static void WM_Init(void); static void WM_DeInit(void); -static bool_t WM_Add(GHandle gh, GWindowInit *pInit); +static bool_t WM_Add(GHandle gh, const GWindowInit *pInit); static void WM_Delete(GHandle gh); static void WM_Visible(GHandle gh); static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h); @@ -65,23 +65,25 @@ static void WM_DeInit(void) { // A full window manager would remove any borders etc } -static bool_t WM_Add(GHandle gh, GWindowInit *pInit) { +static bool_t WM_Add(GHandle gh, const GWindowInit *pInit) { + // Note the window will not be marked as visible yet + // Put it on the queue gfxQueueASyncPut(&_GWINList, &gh->wmq); // Make sure the size is valid WM_Redim(gh, pInit->x, pInit->y, pInit->width, pInit->height); - - // Display it if it is visible - WM_Visible(gh); return TRUE; } static void WM_Delete(GHandle gh) { - // A real window manager would make the window invisible - // (and then clear the area underneath) + // Make the window invisible and clear the area underneath + if ((gh->flags & GWIN_FLG_VISIBLE)) { + gh->flags &= ~GWIN_FLG_VISIBLE; + gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor()); + } - // Just remove it from the queue + // Remove it from the queue gfxQueueASyncRemove(&_GWINList, &gh->wmq); } @@ -97,10 +99,8 @@ static void WM_Visible(GHandle gh) { // A real window manager would also redraw the borders } - // else - // A real window manager would make the window invisible - // (and then clear the area underneath) - + else + gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor()); } static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { @@ -114,8 +114,28 @@ static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) { if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; } if (x+w > gdispGetWidth()) w = gdispGetWidth() - x; if (y+h > gdispGetHeight()) h = gdispGetHeight() - y; + + // If there has been no resize just exit + if (gh->x == x && gh->y == y && gh->width == w && gh->height == h) + return; + + // Clear the old area + if ((gh->flags & GWIN_FLG_VISIBLE)) + gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor()); + + // Set the new size gh->x = x; gh->y = y; gh->width = w; gh->height = h; + + // Redraw the window (if possible) + if ((gh->flags & GWIN_FLG_VISIBLE)) { + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } } static void WM_MinMax(GHandle gh, GWindowMinMax minmax) { diff --git a/src/gwin/image.c b/src/gwin/image.c deleted file mode 100644 index bba92238..00000000 --- a/src/gwin/image.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. 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/image.c - * @brief GWIN sub-system image code. - */ - -#include "gfx.h" - -#if GFX_USE_GWIN && GWIN_NEED_IMAGE - -#include "gwin/class_gwin.h" - -#define widget(gh) ((GImageWidget*)gh) - -static void _destroy(GWindowObject *gh) { - if (gdispImageIsOpen(&widget(gh)->image)) - gdispImageClose(&widget(gh)->image); - - return; -} - -static void _afterClear(GWindowObject *gh) { - (void)gh; - - return; -} - -static const gwinVMT imageVMT = { - "Image", // The class name - sizeof(GImageWidget), // The object size - _destroy, // The destroy routine - 0, - _afterClear, // The after-clear routine -}; - -GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit) { - if (!(widget = (GImageWidget *)_gwindowCreate(&widget->g, pInit, &imageVMT, 0))) - return 0; - - widget->image = gfxAlloc(sizeof(gdispImage)); - if (widget->image == NULL) - return 0; - - widget->g.x = pInit->x; - widget->g.y = pInit->y; - widget->g.width = pInit->width; - widget->g.height = pInit->height; - widget->bgColor = Black; - gwinSetVisible((GHandle)widget, pInit->show); - - return (GHandle)widget; -} - -bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { - bool_t err; - - err = gdispImageSetMemoryReader(widget(gh)->image, memory); - gdispImageOpen(widget(gh)->image); - - return err; -} - -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__) -bool_t gwinImageOpenFile(GHandle gh, const char* filename) { - return gdispImageSetFileReader(widget(gh)->image, filename); -} -#endif - -#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) -bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { - return gdispImageSetBaseFileStreamReader(widget(gh)->image, streamPtr); -} -#endif - -gdispImageError gwinImageCache(GHandle gh) { - return gdispImageCache(widget(gh)->image); -} - -void gwinImageSetBgColor(GHandle gh, color_t bgColor) { - widget(gh)->bgColor = bgColor; -} - -void gwinImageDraw(GHandle gh) { - gdispImageDraw(widget(gh)->image, widget(gh)->g.x, widget(gh)->g.y, widget(gh)->image->width, widget(gh)->image->height, 0, 0); -} - -#endif // GFX_USE_GWIN && GWIN_NEED_IMAGE -/** @} */ - diff --git a/src/gwin/label.c b/src/gwin/label.c index 7f8ab814..e757892d 100644 --- a/src/gwin/label.c +++ b/src/gwin/label.c @@ -21,26 +21,36 @@ #include "gwin/class_gwin.h" -#define widget(gh) ((GLabelWidget*)gh) #define GLABEL_FLG_WAUTO (GWIN_FIRST_CONTROL_FLAG<<0) #define GLABEL_FLG_HAUTO (GWIN_FIRST_CONTROL_FLAG<<1) -static void gwinLabelDefaultDraw(GHandle gh) { - // if( check if auto flag is set ) - // if( call current size != font size ) - // gwinResize(); +// Simple: single line with no wrapping +static coord_t getwidth(const char *txt, font_t font, coord_t maxwidth) { + (void) maxwidth; + return gdispGetStringWidth(txt, font)+2; // Allow one pixel of padding on each side +} + +// Simple: single line with no wrapping +static coord_t getheight(const char *txt, font_t font, coord_t maxwidth) { + (void) txt; + (void) maxwidth; + + return gdispGetFontMetric(font, fontHeight); +} + +static void gwinLabelDefaultDraw(GWidgetObject *gw, void *param) { + (void) param; + coord_t w, h; - gdispFillString( widget(gh)->w.g.x, - widget(gh)->w.g.y, - widget(gh)->w.txt, - widget(gh)->w.g.font, - widget(gh)->w.g.color, - widget(gh)->w.g.bgcolor - ); + w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.width; + h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.height; - gdispFillArea( widget(gh)->w.g.x, widget(gh)->w.g.y, widget(gh)->w.g.width, widget(gh)->w.g.height, Green); + if (gw->g.width != w || gw->g.height != h) { + gwinResize(&gw->g, w, h); + return; + } - printf("Text: %s\r\n", widget(gh)->w.txt); + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->txt, gw->g.font, gw->g.color, gw->g.bgcolor, justifyLeft); } static const gwidgetVMT labelVMT = { @@ -78,21 +88,21 @@ GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) { // auto assign width if (pInit->g.width <= 0) { flags |= GLABEL_FLG_WAUTO; - pInit->g.width = gdispGetStringWidth(pInit->text, gwinGetDefaultFont()); + pInit->g.width = getwidth(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x); } // auto assign height if (pInit->g.height <= 0) { flags |= GLABEL_FLG_HAUTO; - pInit->g.height = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight); + pInit->g.height = getheight(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x); } if (!(widget = (GLabelWidget *)_gwidgetCreate(&widget->w, pInit, &labelVMT))) return 0; - gwinLabelDefaultDraw((GHandle)widget); widget->w.g.flags |= flags; + gwinSetVisible(&widget->w.g, pInit->g.show); return (GHandle)widget; } -- cgit v1.2.3 From a7198b53ff82a02a86a55823a8be895ec5eca1e4 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 4 Jul 2013 00:54:25 +1000 Subject: Restore gwin base class image function --- src/gwin/gwin.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index de1673cb..e3d81d9c 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -501,6 +501,18 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } #endif +#if GDISP_NEED_IMAGE + gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + if (!((gh->flags & GWIN_FLG_VISIBLE))) + return GDISP_IMAGE_ERR_OK; + + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy); + } +#endif + #endif /* GFX_USE_GWIN */ /** @} */ -- cgit v1.2.3 From f9eed6036d7f28ef1ab8f8d3feec6a05e0572405 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 4 Jul 2013 00:59:12 +1000 Subject: Make the enabled state available to all GWIN's - not just widgets. --- src/gwin/gwidget.c | 17 ----------------- src/gwin/gwin.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index a2b82f1d..6440f171 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -226,23 +226,6 @@ void _gwidgetRedraw(GHandle gh) { gw->fnDraw(gw, gw->fnParam); } -void gwinSetEnabled(GHandle gh, bool_t enabled) { - if (!(gh->flags & GWIN_FLG_WIDGET)) - return; - - if (enabled) { - if (!(gh->flags & GWIN_FLG_ENABLED)) { - gh->flags |= GWIN_FLG_ENABLED; - _gwidgetRedraw(gh); - } - } else { - if ((gh->flags & GWIN_FLG_ENABLED)) { - gh->flags &= ~GWIN_FLG_ENABLED; - _gwidgetRedraw(gh); - } - } -} - void gwinSetText(GHandle gh, const char *txt, bool_t useAlloc) { if (!(gh->flags & GWIN_FLG_WIDGET)) return; diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index e3d81d9c..9e345523 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -223,6 +223,34 @@ bool_t gwinGetVisible(GHandle gh) { return (gh->flags & GWIN_FLG_VISIBLE) ? TRUE : FALSE; } +void gwinSetEnabled(GHandle gh, bool_t enabled) { + if (enabled) { + if (!(gh->flags & GWIN_FLG_ENABLED)) { + gh->flags |= GWIN_FLG_ENABLED; + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } + } else { + if ((gh->flags & GWIN_FLG_ENABLED)) { + gh->flags &= ~GWIN_FLG_ENABLED; + if (gh->vmt->Redraw) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + gh->vmt->Redraw(gh); + } + } + } +} + +bool_t gwinGetEnabled(GHandle gh) { + return (gh->flags & GWIN_FLG_ENABLED) ? TRUE : FALSE; +} + void gwinMove(GHandle gh, coord_t x, coord_t y) { #if GWIN_NEED_WINDOWMANAGER cwm->vmt->Redim(gh, x, y, gh->width, gh->height); -- cgit v1.2.3 From c059f96d24c814fc34d470aa01577f294f9d73a6 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 4 Jul 2013 01:08:47 +1000 Subject: Rename gwin base image function to avoid confusion with the image gwin object. --- src/gwin/gwin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 9e345523..92b6cc03 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -530,7 +530,7 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #endif #if GDISP_NEED_IMAGE - gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { if (!((gh->flags & GWIN_FLG_VISIBLE))) return GDISP_IMAGE_ERR_OK; -- cgit v1.2.3 From 99c13615c829f5d64fe10f644aa493be0cd01c15 Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 4 Jul 2013 17:00:34 +1000 Subject: Image decoders not setting image type correctly. --- src/gdisp/image_bmp.c | 1 + src/gdisp/image_gif.c | 1 + src/gdisp/image_native.c | 1 + 3 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c index e54ad5e4..4f50de81 100644 --- a/src/gdisp/image_bmp.c +++ b/src/gdisp/image_bmp.c @@ -407,6 +407,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { } #endif + img->type = GDISP_IMAGE_TYPE_BMP; return GDISP_IMAGE_ERR_OK; baddatacleanup: diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c index 3de47d03..ed342b4e 100644 --- a/src/gdisp/image_gif.c +++ b/src/gdisp/image_gif.c @@ -609,6 +609,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { // Read the first frame descriptor switch(initFrame(img)) { case GDISP_IMAGE_ERR_OK: // Everything OK + img->type = GDISP_IMAGE_TYPE_GIF; return GDISP_IMAGE_ERR_OK; case GDISP_IMAGE_ERR_UNSUPPORTED: // Unsupported gdispImageClose_GIF(img); // Clean up the private data area diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c index 694518c6..6bbed3fc 100644 --- a/src/gdisp/image_native.c +++ b/src/gdisp/image_native.c @@ -56,6 +56,7 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { return GDISP_IMAGE_ERR_NOMEMORY; img->priv->frame0cache = 0; + img->type = GDISP_IMAGE_TYPE_NATIVE; return GDISP_IMAGE_ERR_OK; } -- cgit v1.2.3 From f3f9b7dc015b5afc82fba6682e780dcc72f9241d Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 6 Jul 2013 01:42:10 +1000 Subject: Fix window manager bug Window are was not being cleared properly when something was made invisible --- src/gwin/gwm.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index 75b08be6..88d61a21 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -88,18 +88,16 @@ static void WM_Delete(GHandle gh) { } static void WM_Visible(GHandle gh) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif if ((gh->flags & GWIN_FLG_VISIBLE)) { - if (gh->vmt->Redraw) { - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif + if (gh->vmt->Redraw) gh->vmt->Redraw(gh); - } else - gwinClear(gh); - // A real window manager would also redraw the borders - } - - else + else + gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor); + // A real window manager would also redraw the borders here + } else gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor()); } -- cgit v1.2.3 From ab44f32859ac61072a561869787089e13adaf509 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 6 Jul 2013 01:45:24 +1000 Subject: Remove widget structure members when they are not needed for input tracking Also doco update for Enabled Flag --- src/gwin/button.c | 164 ++++++++++++++-------------- src/gwin/checkbox.c | 122 +++++++++++---------- src/gwin/label.c | 42 ++++---- src/gwin/slider.c | 306 ++++++++++++++++++++++++++-------------------------- 4 files changed, 325 insertions(+), 309 deletions(-) (limited to 'src') diff --git a/src/gwin/button.c b/src/gwin/button.c index 303d1078..73f56c2e 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -17,7 +17,7 @@ #include "gfx.h" -#if (GFX_USE_GWIN && GWIN_NEED_BUTTON) || defined(__DOXYGEN__) +#if GFX_USE_GWIN && GWIN_NEED_BUTTON #include "gwin/class_gwin.h" @@ -29,44 +29,6 @@ // Our pressed state #define GBUTTON_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0) -// Prototypes for button VMT functions -static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); -static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); -static void ToggleOff(GWidgetObject *gw, uint16_t role); -static void ToggleOn(GWidgetObject *gw, uint16_t role); -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); - -// The button VMT table -static const gwidgetVMT buttonVMT = { - { - "Button", // The classname - sizeof(GButtonObject), // The object size - _gwidgetDestroy, // The destroy routine - _gwidgetRedraw, // The redraw routine - 0, // The after-clear routine - }, - gwinButtonDraw_3D, // The default drawing routine - { - MouseDown, // Process mouse down events - MouseUp, // Process mouse up events - 0, // Process mouse move events (NOT USED) - }, - { - 1, // 1 toggle role - ToggleAssign, // Assign Toggles - ToggleGet, // Get Toggles - ToggleOff, // Process toggle off events - ToggleOn, // Process toggle on events - }, - { - 0, // No dial roles - 0, // Assign Dials (NOT USED) - 0, // Get Dials (NOT USED) - 0, // Process dial move events (NOT USED) - } -}; - // Default color scheme static const GButtonColors GButtonDefaultColorsUp = { HTML2COLOR(0x404040), // color_up_edge; @@ -103,59 +65,101 @@ static void SendButtonEvent(GWidgetObject *gw) { #undef pbe } -// A mouse down has occurred over the button -static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { - (void) x; (void) y; - gw->g.flags |= GBUTTON_FLG_PRESSED; - _gwidgetRedraw((GHandle)gw); -} +#if GINPUT_NEED_MOUSE + // A mouse down has occurred over the button + static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { + (void) x; (void) y; + gw->g.flags |= GBUTTON_FLG_PRESSED; + _gwidgetRedraw((GHandle)gw); + } -// A mouse up has occurred (it may or may not be over the button) -static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { - (void) x; (void) y; - gw->g.flags &= ~GBUTTON_FLG_PRESSED; - _gwidgetRedraw((GHandle)gw); + // A mouse up has occurred (it may or may not be over the button) + static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { + (void) x; (void) y; + gw->g.flags &= ~GBUTTON_FLG_PRESSED; + _gwidgetRedraw((GHandle)gw); - #if !GWIN_BUTTON_LAZY_RELEASE - // If the mouse up was not over the button then cancel the event - if (x < 0 || y < 0 || x >= gw->g.width || y >= gw->g.height) - return; - #endif + #if !GWIN_BUTTON_LAZY_RELEASE + // If the mouse up was not over the button then cancel the event + if (x < 0 || y < 0 || x >= gw->g.width || y >= gw->g.height) + return; + #endif - SendButtonEvent(gw); -} + SendButtonEvent(gw); + } +#endif -// A toggle off has occurred -static void ToggleOff(GWidgetObject *gw, uint16_t role) { - (void) role; - gw->g.flags &= ~GBUTTON_FLG_PRESSED; - _gwidgetRedraw((GHandle)gw); -} +#if GINPUT_NEED_TOGGLE + // A toggle off has occurred + static void ToggleOff(GWidgetObject *gw, uint16_t role) { + (void) role; + gw->g.flags &= ~GBUTTON_FLG_PRESSED; + _gwidgetRedraw((GHandle)gw); + } -// A toggle on has occurred -static void ToggleOn(GWidgetObject *gw, uint16_t role) { - (void) role; - gw->g.flags |= GBUTTON_FLG_PRESSED; - _gwidgetRedraw((GHandle)gw); - // Trigger the event on button down (different than for mouse/touch) - SendButtonEvent(gw); -} + // A toggle on has occurred + static void ToggleOn(GWidgetObject *gw, uint16_t role) { + (void) role; + gw->g.flags |= GBUTTON_FLG_PRESSED; + _gwidgetRedraw((GHandle)gw); + // Trigger the event on button down (different than for mouse/touch) + SendButtonEvent(gw); + } -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { - (void) role; - ((GButtonObject *)gw)->toggle = instance; -} + static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GButtonObject *)gw)->toggle = instance; + } -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { - (void) role; - return ((GButtonObject *)gw)->toggle; -} + static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GButtonObject *)gw)->toggle; + } +#endif + +// The button VMT table +static const gwidgetVMT buttonVMT = { + { + "Button", // The classname + sizeof(GButtonObject), // The object size + _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine + 0, // The after-clear routine + }, + gwinButtonDraw_3D, // The default drawing routine + #if GINPUT_NEED_MOUSE + { + MouseDown, // Process mouse down events + MouseUp, // Process mouse up events + 0, // Process mouse move events (NOT USED) + }, + #endif + #if GINPUT_NEED_TOGGLE + { + 1, // 1 toggle role + ToggleAssign, // Assign Toggles + ToggleGet, // Get Toggles + ToggleOff, // Process toggle off events + 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 gwinCreateButton(GButtonObject *gw, const GWidgetInit *pInit) { if (!(gw = (GButtonObject *)_gwidgetCreate(&gw->w, pInit, &buttonVMT))) return 0; - gw->toggle = GWIDGET_NO_INSTANCE; + #if GINPUT_NEED_TOGGLE + gw->toggle = GWIDGET_NO_INSTANCE; + #endif gw->c_up = GButtonDefaultColorsUp; gw->c_dn = GButtonDefaultColorsDown; gw->c_dis = GButtonDefaultColorsDisabled; diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 62f4c55b..74d612d2 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -24,42 +24,6 @@ // 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 role); -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); - -// The button 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 - { - MouseDown, // Process mouse down events - 0, // Process mouse up events (NOT USED) - 0, // Process mouse move events (NOT USED) - }, - { - 1, // 1 toggle role - ToggleAssign, // Assign Toggles - ToggleGet, // Get Toggles - 0, // Process toggle off events (NOT USED) - ToggleOn, // Process toggle on events - }, - { - 0, // No dial roles - 0, // Assign Dials (NOT USED) - 0, // Get Dials (NOT USED) - 0, // Process dial move events (NOT USED) - } -}; - static const GCheckboxColors defaultColors = { Black, // border Grey, // selected @@ -87,37 +51,77 @@ static void SendCheckboxEvent(GWidgetObject *gw) { #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); -} +#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 + +#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); + } -// A toggle on has occurred -static void ToggleOn(GWidgetObject *gw, uint16_t role) { - (void) role; - gw->g.flags ^= GCHECKBOX_FLG_CHECKED; - _gwidgetRedraw((GHandle)gw); - SendCheckboxEvent(gw); -} + static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GCheckboxObject *)gw)->toggle = instance; + } -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { - (void) role; - ((GCheckboxObject *)gw)->toggle = instance; -} + static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GCheckboxObject *)gw)->toggle; + } +#endif -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { - (void) role; - return ((GCheckboxObject *)gw)->toggle; -} +// 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 gwinCreateCheckbox(GCheckboxObject *gb, const GWidgetInit *pInit) { if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT))) return 0; - gb->toggle = (uint16_t) -1; + #if GINPUT_NEED_TOGGLE + gb->toggle = GWIDGET_NO_INSTANCE; + #endif gb->c = defaultColors; // assign the default colors gwinSetVisible((GHandle)gb, pInit->g.show); return (GHandle)gb; diff --git a/src/gwin/label.c b/src/gwin/label.c index e757892d..cd469210 100644 --- a/src/gwin/label.c +++ b/src/gwin/label.c @@ -62,24 +62,30 @@ static const gwidgetVMT labelVMT = { 0, // The after-clear routine }, gwinLabelDefaultDraw, // default drawing routine - { - 0, // Process mose down events (NOT USED) - 0, // Process mouse up events (NOT USED) - 0, // Process mouse move events (NOT USED) - }, - { - 0, // No toggle role - 0, // Assign Toggles (NOT USED) - 0, // Get Toggles (NOT USED) - 0, // Process toggle off event (NOT USED) - 0, // Process toggle on event (NOT USED) - }, - { - 0, // No dial roles - 0, // Assign Dials (NOT USED) - 0, // Get Dials (NOT USED) - 0, // Procees dial move events (NOT USED) - } + #if GINPUT_NEED_MOUSE + { + 0, // Process mose down events (NOT USED) + 0, // Process mouse up events (NOT USED) + 0, // Process mouse move events (NOT USED) + }, + #endif + #if GINPUT_NEED_TOGGLE + { + 0, // No toggle role + 0, // Assign Toggles (NOT USED) + 0, // Get Toggles (NOT USED) + 0, // Process toggle off event (NOT USED) + 0, // Process toggle on event (NOT USED) + }, + #endif + #if GINPUT_NEED_DIAL + { + 0, // No dial roles + 0, // Assign Dials (NOT USED) + 0, // Get Dials (NOT USED) + 0, // Procees dial move events (NOT USED) + }, + #endif }; GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) { diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 2dfa3a7c..5aa320f8 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -29,46 +29,6 @@ #define GWIN_SLIDER_TOGGLE_INC 20 // How many toggles to go from minimum to maximum #endif -// Prototypes for slider VMT functions -static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); -static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y); -static void ToggleOn(GWidgetObject *gw, uint16_t role); -static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max); -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); -static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance); -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role); -static uint16_t DialGet(GWidgetObject *gw, uint16_t role); - -// The button VMT table -static const gwidgetVMT sliderVMT = { - { - "Slider", // The classname - sizeof(GSliderObject), // The object size - _gwidgetDestroy, // The destroy routine - _gwidgetRedraw, // The redraw routine - 0, // The after-clear routine - }, - gwinSliderDraw_Std, // The default drawing routine - { - 0, // Process mouse down events (NOT USED) - MouseUp, // Process mouse up events - MouseMove, // Process mouse move events - }, - { - 2, // 1 toggle role - ToggleAssign, // Assign Toggles - ToggleGet, // Get Toggles - 0, // Process toggle off events (NOT USED) - ToggleOn, // Process toggle on events - }, - { - 1, // 1 dial roles - DialAssign, // Assign Dials - DialGet, // Get Dials - DialMove, // Process dial move events - } -}; - static const GSliderColors GSliderDefaultColors = { HTML2COLOR(0x404040), // color_edge HTML2COLOR(0x000000), // color_thumb @@ -105,140 +65,182 @@ static void ResetDisplayPos(GSliderObject *gsw) { gsw->dpos = ((gsw->w.g.width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min); } -// A mouse up event -static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { - #define gsw ((GSliderObject *)gw) - #define gh ((GHandle)gw) - - #if GWIN_BUTTON_LAZY_RELEASE - // Clip to the slider - if (x < 0) x = 0; - else if (x >= gh->width) x = gh->width-1; - if (y < 0) y = 0; - else if (y >= gh->height) x = gh->height-1; - #else - // Are we over the slider? - if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) { - // No - restore the slider - ResetDisplayPos(gsw); - _gwidgetRedraw(gh); - return; +#if GINPUT_NEED_MOUSE + // A mouse up event + static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gw) + #define gh ((GHandle)gw) + + #if GWIN_BUTTON_LAZY_RELEASE + // Clip to the slider + if (x < 0) x = 0; + else if (x >= gh->width) x = gh->width-1; + if (y < 0) y = 0; + else if (y >= gh->height) x = gh->height-1; + #else + // Are we over the slider? + if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) { + // No - restore the slider + ResetDisplayPos(gsw); + _gwidgetRedraw(gh); + return; + } + #endif + + // Set the new position + if (gh->width < gh->height) { + if (y > gh->height-GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->min; + else if (y < GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->max; + else + gsw->pos = (uint16_t)((int32_t)(gh->height-1-y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + } else { + if (x > gh->width-GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->max; + else if (x < GWIN_SLIDER_DEAD_BAND) + gsw->pos = gsw->min; + else + gsw->pos = (uint16_t)((int32_t)(x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); } - #endif - // Set the new position - if (gh->width < gh->height) { - if (y > gh->height-GWIN_SLIDER_DEAD_BAND) - gsw->pos = gsw->min; - else if (y < GWIN_SLIDER_DEAD_BAND) - gsw->pos = gsw->max; - else - gsw->pos = (uint16_t)((int32_t)(gh->height-1-y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); - } else { - if (x > gh->width-GWIN_SLIDER_DEAD_BAND) - gsw->pos = gsw->max; - else if (x < GWIN_SLIDER_DEAD_BAND) - gsw->pos = gsw->min; - else - gsw->pos = (uint16_t)((int32_t)(x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + ResetDisplayPos(gsw); + _gwidgetRedraw(gh); + + // Generate the event + SendSliderEvent(gw); + #undef gh + #undef gsw } - ResetDisplayPos(gsw); - _gwidgetRedraw(gh); + // A mouse move (or mouse down) event + static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gw) + + // Determine the temporary display position (with range checking) + if (gw->g.width < gw->g.height) { + if (y < 0) + gsw->dpos = 0; + else if (y >= gw->g.height) + gsw->dpos = gw->g.height-1; + else + gsw->dpos = y; + } else { + if (x < 0) + gsw->dpos = 0; + else if (x >= gw->g.width) + gsw->dpos = gw->g.width-1; + else + gsw->dpos = x; + } - // Generate the event - SendSliderEvent(gw); - #undef gh - #undef gsw -} + // Update the display + _gwidgetRedraw(&gw->g); + #undef gsw + } +#endif -// A mouse move (or mouse down) event -static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) { - #define gsw ((GSliderObject *)gw) +#if GINPUT_NEED_TOGGLE + // A toggle on has occurred + static void ToggleOn(GWidgetObject *gw, uint16_t role) { + #define gsw ((GSliderObject *)gw) + + if (role) { + gwinSetSliderPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + SendSliderEvent(gw); + } else { + gwinSetSliderPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + SendSliderEvent(gw); + } + #undef gsw + } - // Determine the temporary display position (with range checking) - if (gw->g.width < gw->g.height) { - if (y < 0) - gsw->dpos = 0; - else if (y >= gw->g.height) - gsw->dpos = gw->g.height-1; + static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + if (role) + ((GSliderObject *)gw)->t_up = instance; else - gsw->dpos = y; - } else { - if (x < 0) - gsw->dpos = 0; - else if (x >= gw->g.width) - gsw->dpos = gw->g.width-1; - else - gsw->dpos = x; + ((GSliderObject *)gw)->t_dn = instance; } - // Update the display - _gwidgetRedraw(&gw->g); - #undef gsw -} - -// A toggle on has occurred -static void ToggleOn(GWidgetObject *gw, uint16_t role) { - #define gsw ((GSliderObject *)gw) - - if (role) { - gwinSetSliderPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); - SendSliderEvent(gw); - } else { - gwinSetSliderPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); - SendSliderEvent(gw); + static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + return role ? ((GSliderObject *)gw)->t_up : ((GSliderObject *)gw)->t_dn; } - #undef gsw -} - -// A dial move event -static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max) { -#if GFX_USE_GINPUT && GINPUT_NEED_DIAL - #define gsw ((GSliderObject *)gw) - (void) role; +#endif - // Set the new position - gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min); +#if GINPUT_NEED_DIAL + // A dial move event + static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max) { + #define gsw ((GSliderObject *)gw) + (void) role; - ResetDisplayPos(gsw); - gwinDraw(&gw->g); + // Set the new position + gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min); - // Generate the event - SendSliderEvent(gw); - #undef gsw -#else - (void)gw; (void)role; (void)value; (void)max; -#endif -} + ResetDisplayPos(gsw); + _gwidgetRedraw((GHandle)gw); -static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { - if (role) - ((GSliderObject *)gw)->t_up = instance; - else - ((GSliderObject *)gw)->t_dn = instance; -} + // Generate the event + SendSliderEvent(gw); + #undef gsw + } -static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { - return role ? ((GSliderObject *)gw)->t_up : ((GSliderObject *)gw)->t_dn; -} + static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GSliderObject *)gw)->dial = instance; + } -static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { - (void) role; - ((GSliderObject *)gw)->dial = instance; -} + static uint16_t DialGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GSliderObject *)gw)->dial; + } +#endif -static uint16_t DialGet(GWidgetObject *gw, uint16_t role) { - (void) role; - return ((GSliderObject *)gw)->dial; -} +// The slider VMT table +static const gwidgetVMT sliderVMT = { + { + "Slider", // The classname + sizeof(GSliderObject), // The object size + _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine + 0, // The after-clear routine + }, + gwinSliderDraw_Std, // The default drawing routine + #if GINPUT_NEED_MOUSE + { + 0, // Process mouse down events (NOT USED) + MouseUp, // Process mouse up events + MouseMove, // Process mouse move events + }, + #endif + #if GINPUT_NEED_TOGGLE + { + 2, // 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 + { + 1, // 1 dial roles + DialAssign, // Assign Dials + DialGet, // Get Dials + DialMove, // Process dial move events + }, + #endif +}; GHandle gwinCreateSlider(GSliderObject *gs, const GWidgetInit *pInit) { if (!(gs = (GSliderObject *)_gwidgetCreate(&gs->w, pInit, &sliderVMT))) return 0; - gs->t_dn = (uint16_t) -1; - gs->t_up = (uint16_t) -1; - gs->dial = (uint16_t) -1; + #if GINPUT_NEED_TOGGLE + gs->t_dn = GWIDGET_NO_INSTANCE; + gs->t_up = GWIDGET_NO_INSTANCE; + #endif + #if GINPUT_NEED_DIAL + gs->dial = GWIDGET_NO_INSTANCE; + #endif gs->c = GSliderDefaultColors; gs->min = 0; gs->max = 100; -- cgit v1.2.3 From 5191c278e7195de62b619be58c19ea338c31d54c Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 6 Jul 2013 01:46:34 +1000 Subject: Add Radio buttons (can also be used as a Tab group) --- src/gwin/gwin.mk | 1 + src/gwin/radio.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 src/gwin/radio.c (limited to 'src') diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index b9e6a9ee..92b10b7b 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -8,4 +8,5 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/checkbox.c \ $(GFXLIB)/src/gwin/gimage.c \ $(GFXLIB)/src/gwin/label.c \ + $(GFXLIB)/src/gwin/radio.c \ diff --git a/src/gwin/radio.c b/src/gwin/radio.c new file mode 100644 index 00000000..d1c65dbc --- /dev/null +++ b/src/gwin/radio.c @@ -0,0 +1,260 @@ +/* + * This file is subject to the terms of the GFX License. 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/radio.c + * @brief GWIN sub-system radio button code. + * + * @defgroup RadioButton RadioButton + * @ingroup GWIN + * + * @{ + */ + +#include "gfx.h" + +#if GFX_USE_GWIN && GWIN_NEED_RADIO + +#include "gwin/class_gwin.h" + +// Our pressed state +#define GRADIO_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0) + +// Default color scheme +static const GRadioColors GRadioDefaultColorsUp = { + HTML2COLOR(0x404040), // color_up_edge; + HTML2COLOR(0xE0E0E0), // color_up_fill; + HTML2COLOR(0x000000), // color_up_txt; +}; +static const GRadioColors GRadioDefaultColorsDown = { + HTML2COLOR(0x404040), // color_dn_edge; + HTML2COLOR(0x808080), // color_dn_fill; + HTML2COLOR(0x404040), // color_dn_txt; +}; +static const GRadioColors GRadioDefaultColorsDisabled = { + HTML2COLOR(0x808080), // color_dis_edge; + HTML2COLOR(0xE0E0E0), // color_dis_fill; + HTML2COLOR(0xC0C0C0), // color_dis_txt; +}; + +// Send the button event +static void SendButtonEvent(GWidgetObject *gw) { + GSourceListener * psl; + GEvent * pe; + #define pbe ((GEventGWinRadio *)pe) + + // Trigger a GWIN Button Event + psl = 0; + while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) { + if (!(pe = geventGetEventBuffer(psl))) + continue; + pbe->type = GEVENT_GWIN_RADIO; + pbe->radio = (GHandle)gw; + pbe->group = ((GRadioObject *)gw)->group; + geventSendEvent(psl); + } + + #undef pbe +} + +#if GINPUT_NEED_MOUSE + // A mouse down has occurred over the button + static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { + (void) x; (void) y; + + gwinPressRadio((GHandle)gw); + } +#endif + +#if GINPUT_NEED_TOGGLE + // A toggle on has occurred + static void ToggleOn(GWidgetObject *gw, uint16_t role) { + (void) role; + + gwinPressRadio((GHandle)gw); + } + + static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { + (void) role; + ((GRadioObject *)gw)->toggle = instance; + } + + static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) { + (void) role; + return ((GRadioObject *)gw)->toggle; + } +#endif + +// The radio button VMT table +static const gwidgetVMT radioVMT = { + { + "Radio", // The classname + sizeof(GRadioObject), // The object size + _gwidgetDestroy, // The destroy routine + _gwidgetRedraw, // The redraw routine + 0, // The after-clear routine + }, + gwinRadioDraw_Radio, // 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 gwinCreateRadio(GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) { + if (!(gw = (GRadioObject *)_gwidgetCreate(&gw->w, pInit, &radioVMT))) + return 0; + + #if GINPUT_NEED_TOGGLE + gw->toggle = GWIDGET_NO_INSTANCE; + #endif + gw->group = group; + gw->c_up = GRadioDefaultColorsUp; + gw->c_dn = GRadioDefaultColorsDown; + gw->c_dis = GRadioDefaultColorsDisabled; + gwinSetVisible((GHandle)gw, pInit->g.show); + return (GHandle)gw; +} + +void gwinSetRadioColors(GHandle gh, const GRadioColors *pUp, const GRadioColors *pDown, const GRadioColors *pDisabled) { + if (gh->vmt != (gwinVMT *)&radioVMT) + return; + + if (pUp) ((GRadioObject *)gh)->c_up = *pUp; + if (pDown) ((GRadioObject *)gh)->c_dn = *pDown; + if (pDisabled) ((GRadioObject *)gh)->c_dis = *pDisabled; +} + +void gwinPressRadio(GHandle gh) { + GHandle gx; + + if (gh->vmt != (gwinVMT *)&radioVMT || (gh->flags & GRADIO_FLG_PRESSED)) + return; + + if ((gx = gwinActiveRadio(((GRadioObject *)gh)->group))) { + gx->flags &= ~GRADIO_FLG_PRESSED; + _gwidgetRedraw(gx); + } + gh->flags |= GRADIO_FLG_PRESSED; + _gwidgetRedraw(gh); + SendButtonEvent((GWidgetObject *)gh); +} + +bool_t gwinIsRadioPressed(GHandle gh) { + if (gh->vmt != (gwinVMT *)&radioVMT) + return FALSE; + + return (gh->flags & GRADIO_FLG_PRESSED) ? TRUE : FALSE; +} + +/** + * @brief Find the currently pressed radio button in the specified group + * @return The handle of the pressed radio button or NULL if none are pressed + * + * @param[in] gh The window handle (must be a radio widget) + * + * @api + */ +GHandle gwinActiveRadio(uint16_t group) { + const gfxQueueASyncItem * qi; + GHandle gh; + + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + gh = QItem2GWindow(qi); + if (gh->vmt == (gwinVMT *)&radioVMT && ((GRadioObject *)gh)->group == group && (gh->flags & GRADIO_FLG_PRESSED)) + return gh; + } + return 0; +} + +/*---------------------------------------------------------- + * Custom Draw Routines + *----------------------------------------------------------*/ + +static GRadioColors *getDrawColors(GWidgetObject *gw) { + if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &((GRadioObject *)gw)->c_dis; + if ((gw->g.flags & GRADIO_FLG_PRESSED)) return &((GRadioObject *)gw)->c_dn; + return &((GRadioObject *)gw)->c_up; +} + +void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) { + #define gcw ((GRadioObject *)gw) + coord_t ld, df; + GRadioColors * pcol; + (void) param; + + if (gw->g.vmt != (gwinVMT *)&radioVMT) return; + pcol = getDrawColors(gw); + + ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height; + + #if GDISP_NEED_CIRCLE + df = ld/2; + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->g.bgcolor); + gdispDrawCircle(gw->g.x+df, gw->g.y+df, df, pcol->color_edge); + + if (gw->g.flags & GRADIO_FLG_PRESSED) + gdispFillCircle(gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->color_fill); + #else + gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->g.bgcolor); + gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->color_edge); + + df = ld < 4 ? 1 : 2; + if (gw->g.flags & GRADIO_FLG_PRESSED) + gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->color_fill); + #endif + + gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->txt, gw->g.font, pcol->color_txt, gw->g.bgcolor, justifyLeft); + #undef gcw +} + +void gwinRadioDraw_Button(GWidgetObject *gw, void *param) { + (void) param; + GRadioColors * pcol; + + if (gw->g.vmt != (gwinVMT *)&radioVMT) return; + pcol = getDrawColors(gw); + + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); + gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->color_edge); + gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->color_edge); +} + +void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) { + (void) param; + GRadioColors * pcol; + + if (gw->g.vmt != (gwinVMT *)&radioVMT) return; + pcol = getDrawColors(gw); + + gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); +} + +#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */ +/** @} */ + -- cgit v1.2.3 From de28112a7d6db829142ad113c93eb8ad071b0d65 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 7 Jul 2013 19:39:17 +1000 Subject: GDISP fix bug in non-multithread --- src/gdisp/gdisp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index 1b16ac53..5c0f4709 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -135,6 +135,10 @@ gdisp_lld_init(); gfxMutexExit(&gdispMutex); } +#else + void _gdispInit(void) { + gdisp_lld_init(); + } #endif #if GDISP_NEED_MULTITHREAD -- cgit v1.2.3 From 3957505ab119b21c7b0f4e72f56030c97711988a Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 7 Jul 2013 19:40:37 +1000 Subject: GWIN renaming, tidy up, color styles --- src/gwin/button.c | 150 ++++++++++++++++++++-------------------------------- src/gwin/checkbox.c | 76 +++++++++++++++----------- src/gwin/console.c | 4 +- src/gwin/gimage.c | 8 +-- src/gwin/graph.c | 2 +- src/gwin/gwidget.c | 138 ++++++++++++++++++++++++++++++++++++++++------- src/gwin/gwin.c | 74 ++++++-------------------- src/gwin/gwm.c | 41 +++++++++++++- src/gwin/label.c | 26 ++++----- src/gwin/radio.c | 111 ++++++++++++++------------------------ src/gwin/slider.c | 90 +++++++++++++++---------------- 11 files changed, 384 insertions(+), 336 deletions(-) (limited to 'src') diff --git a/src/gwin/button.c b/src/gwin/button.c index 73f56c2e..e6f628c3 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -29,23 +29,6 @@ // Our pressed state #define GBUTTON_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0) -// Default color scheme -static const GButtonColors GButtonDefaultColorsUp = { - HTML2COLOR(0x404040), // color_up_edge; - HTML2COLOR(0xE0E0E0), // color_up_fill; - HTML2COLOR(0x000000), // color_up_txt; -}; -static const GButtonColors GButtonDefaultColorsDown = { - HTML2COLOR(0x404040), // color_dn_edge; - HTML2COLOR(0x808080), // color_dn_fill; - HTML2COLOR(0x404040), // color_dn_txt; -}; -static const GButtonColors GButtonDefaultColorsDisabled = { - HTML2COLOR(0x808080), // color_dis_edge; - HTML2COLOR(0xE0E0E0), // color_dis_fill; - HTML2COLOR(0xC0C0C0), // color_dis_txt; -}; - // Send the button event static void SendButtonEvent(GWidgetObject *gw) { GSourceListener * psl; @@ -153,30 +136,18 @@ static const gwidgetVMT buttonVMT = { #endif }; -GHandle gwinCreateButton(GButtonObject *gw, const GWidgetInit *pInit) { +GHandle gwinButtonCreate(GButtonObject *gw, const GWidgetInit *pInit) { if (!(gw = (GButtonObject *)_gwidgetCreate(&gw->w, pInit, &buttonVMT))) return 0; #if GINPUT_NEED_TOGGLE gw->toggle = GWIDGET_NO_INSTANCE; #endif - gw->c_up = GButtonDefaultColorsUp; - gw->c_dn = GButtonDefaultColorsDown; - gw->c_dis = GButtonDefaultColorsDisabled; gwinSetVisible((GHandle)gw, pInit->g.show); return (GHandle)gw; } -void gwinSetButtonColors(GHandle gh, const GButtonColors *pUp, const GButtonColors *pDown, const GButtonColors *pDisabled) { - if (gh->vmt != (gwinVMT *)&buttonVMT) - return; - - if (pUp) ((GButtonObject *)gh)->c_up = *pUp; - if (pDown) ((GButtonObject *)gh)->c_dn = *pDown; - if (pDisabled) ((GButtonObject *)gh)->c_dis = *pDisabled; -} - -bool_t gwinIsButtonPressed(GHandle gh) { +bool_t gwinButtonIsPressed(GHandle gh) { if (gh->vmt != (gwinVMT *)&buttonVMT) return FALSE; @@ -187,73 +158,64 @@ bool_t gwinIsButtonPressed(GHandle gh) { * Custom Draw Routines *----------------------------------------------------------*/ -static GButtonColors *getDrawColors(GWidgetObject *gw) { - if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &((GButtonObject *)gw)->c_dis; - if ((gw->g.flags & GBUTTON_FLG_PRESSED)) return &((GButtonObject *)gw)->c_dn; - return &((GButtonObject *)gw)->c_up; +static const GColorSet *getDrawColors(GWidgetObject *gw) { + if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &gw->pstyle->disabled; + if ((gw->g.flags & GBUTTON_FLG_PRESSED)) return &gw->pstyle->pressed; + return &gw->pstyle->enabled; } void gwinButtonDraw_3D(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); - gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); - gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->color_edge); - gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->color_edge); -} - -void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; - - if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; - pcol = getDrawColors(gw); - - gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter); + gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge); + gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge); } #if GDISP_NEED_ARC void gwinButtonDraw_Rounded(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); if (gw->g.width >= 2*RND_CNR_SIZE+10) { - gdispFillRoundedBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->color_fill); - gdispDrawStringBox(gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->txt, gw->g.font, pcol->color_txt, justifyCenter); - gdispDrawRoundedBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->color_edge); + gdispFillRoundedBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->fill); + gdispDrawStringBox(gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->text, gw->g.font, pcol->text, justifyCenter); + gdispDrawRoundedBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->edge); } else { - gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); + gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); } } #endif #if GDISP_NEED_ELLIPSE void gwinButtonDraw_Ellipse(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); - gdispFillEllipse(gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->color_fill); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); - gdispDrawEllipse(gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->color_edge); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispFillEllipse(gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->fill); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); + gdispDrawEllipse(gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->edge); } #endif #if GDISP_NEED_CONVEX_POLYGON void gwinButtonDraw_ArrowUp(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; - point arw[7]; + const GColorSet * pcol; + (void) param; + point arw[7]; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); @@ -266,15 +228,16 @@ void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height/ARROWHEAD_DIVIDER; arw[6].x = 0; arw[6].y = gw->g.height/ARROWHEAD_DIVIDER; - gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); - gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); } void gwinButtonDraw_ArrowDown(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; - point arw[7]; + const GColorSet * pcol; + (void) param; + point arw[7]; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); @@ -287,15 +250,16 @@ void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; arw[6].x = 0; arw[6].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER; - gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); - gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); } void gwinButtonDraw_ArrowLeft(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; - point arw[7]; + const GColorSet * pcol; + (void) param; + point arw[7]; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); @@ -308,15 +272,16 @@ void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { arw[5].x = gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; arw[6].x = gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1; - gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); - gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); } void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param) { - (void) param; - GButtonColors * pcol; - point arw[7]; + const GColorSet * pcol; + (void) param; + point arw[7]; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; pcol = getDrawColors(gw); @@ -329,32 +294,31 @@ void gwinButtonDraw_Box(GWidgetObject *gw, void *param) { arw[5].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2; arw[6].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1; - gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_fill); - gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->color_edge); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill); + gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); } #endif #if GDISP_NEED_IMAGE || defined(__DOXYGEN__) void gwinButtonDraw_Image(GWidgetObject *gw, void *param) { - GButtonColors * pcol; - coord_t sy; + const GColorSet * pcol; + coord_t sy; if (gw->g.vmt != (gwinVMT *)&buttonVMT) return; + pcol = getDrawColors(gw); if (!(gw->g.flags & GWIN_FLG_ENABLED)) { - pcol = &((GButtonObject *)gw)->c_dis; sy = 2 * gw->g.height; } else if ((gw->g.flags & GBUTTON_FLG_PRESSED)) { - pcol = &((GButtonObject *)gw)->c_dn; sy = gw->g.height; } else { - pcol = &((GButtonObject *)gw)->c_up; sy = 0; } gdispImageDraw((gdispImage *)param, gw->g.x, gw->g.y, gw->g.width, gw->g.height, 0, sy); - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, justifyCenter); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); } #endif diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index 74d612d2..84eb3b9f 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -24,13 +24,6 @@ // Our checked state #define GCHECKBOX_FLG_CHECKED (GWIN_FIRST_CONTROL_FLAG<<0) -static const GCheckboxColors defaultColors = { - Black, // border - Grey, // selected - White, // background - Black, // text -}; - // Send the checkbox event static void SendCheckboxEvent(GWidgetObject *gw) { GSourceListener * psl; @@ -115,70 +108,89 @@ static const gwidgetVMT checkboxVMT = { #endif }; -GHandle gwinCreateCheckbox(GCheckboxObject *gb, const GWidgetInit *pInit) { +GHandle gwinCheckboxCreate(GCheckboxObject *gb, const GWidgetInit *pInit) { if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT))) return 0; #if GINPUT_NEED_TOGGLE gb->toggle = GWIDGET_NO_INSTANCE; #endif - gb->c = defaultColors; // assign the default colors gwinSetVisible((GHandle)gb, pInit->g.show); return (GHandle)gb; } -bool_t gwinIsCheckboxChecked(GHandle gh) { +void gwinCheckboxCheck(GHandle gh, bool_t isChecked) { + if (gh->vmt != (gwinVMT *)&checkboxVMT) + return; + + 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; return (gh->flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE; } -void gwinCheckboxSetColors(GHandle gh, GCheckboxColors *pColors) { - if (gh->vmt != (gwinVMT *)&checkboxVMT) - return; +/*---------------------------------------------------------- + * Custom Draw Routines + *----------------------------------------------------------*/ - ((GCheckboxObject *)gh)->c = *pColors; +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_CheckOnLeft(GWidgetObject *gw, void *param) { - #define gcw ((GCheckboxObject *)gw) - coord_t ld, df; - (void) param; + #define gcw ((GCheckboxObject *)gw) + coord_t ld, df; + const GColorSet * pcol; + (void) param; - if (gw->g.vmt != (gwinVMT *)&checkboxVMT) - return; + if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return; + pcol = getDrawColors(gw); 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); + 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); 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); + 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->txt, gw->g.font, gcw->c.color_txt, gcw->c.color_bg, justifyLeft); + 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 } void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) { - #define gcw ((GCheckboxObject *)gw) - coord_t ep, ld, df; - (void) param; + #define gcw ((GCheckboxObject *)gw) + coord_t ep, ld, df; + const GColorSet * pcol; + (void) param; - if (gw->g.vmt != (gwinVMT *)&checkboxVMT) - return; + if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return; + pcol = getDrawColors(gw); 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); + 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); 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); + 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->txt, gw->g.font, gcw->c.color_txt, gcw->c.color_bg, justifyRight); + gdispFillStringBox(gw->g.x, gw->g.y, ep, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyRight); #undef gcw } diff --git a/src/gwin/console.c b/src/gwin/console.c index 105cc79d..06648e9b 100644 --- a/src/gwin/console.c +++ b/src/gwin/console.c @@ -66,7 +66,7 @@ static const gwinVMT consoleVMT = { AfterClear, // The after-clear routine }; -GHandle gwinCreateConsole(GConsoleObject *gc, const GWindowInit *pInit) { +GHandle gwinConsoleCreate(GConsoleObject *gc, const GWindowInit *pInit) { if (!(gc = (GConsoleObject *)_gwindowCreate(&gc->g, pInit, &consoleVMT, 0))) return 0; #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM @@ -79,7 +79,7 @@ GHandle gwinCreateConsole(GConsoleObject *gc, const GWindowInit *pInit) { } #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM - BaseSequentialStream *gwinGetConsoleStream(GHandle gh) { + BaseSequentialStream *gwinConsoleGetStream(GHandle gh) { if (gh->vmt != &consoleVMT) return 0; return (BaseSequentialStream *)&(((GConsoleObject *)(gh))->stream); diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c index 464bc595..eef47dc7 100644 --- a/src/gwin/gimage.c +++ b/src/gwin/gimage.c @@ -16,7 +16,7 @@ #include "gwin/class_gwin.h" -#define widget(gh) ((GImageWidget*)gh) +#define widget(gh) ((GImageObject *)gh) static void _destroy(GWindowObject *gh) { if (gdispImageIsOpen(&widget(gh)->image)) @@ -80,14 +80,14 @@ static void _redraw(GHandle gh) { static const gwinVMT imageVMT = { "Image", // The class name - sizeof(GImageWidget), // The object size + sizeof(GImageObject), // The object size _destroy, // The destroy routine _redraw, // The redraw routine 0, // The after-clear routine }; -GHandle gwinImageCreate(GImageWidget *gobj, GWindowInit *pInit) { - if (!(gobj = (GImageWidget *)_gwindowCreate(&gobj->g, pInit, &imageVMT, 0))) +GHandle gwinImageCreate(GImageObject *gobj, GWindowInit *pInit) { + if (!(gobj = (GImageObject *)_gwindowCreate(&gobj->g, pInit, &imageVMT, 0))) return 0; // Ensure the gdispImageIsOpen() gives valid results diff --git a/src/gwin/graph.c b/src/gwin/graph.c index 049f52e0..de447f4f 100644 --- a/src/gwin/graph.c +++ b/src/gwin/graph.c @@ -165,7 +165,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t } } -GHandle gwinCreateGraph(GGraphObject *gg, const GWindowInit *pInit) { +GHandle gwinGraphCreate(GGraphObject *gg, const GWindowInit *pInit) { if (!(gg = (GGraphObject *)_gwindowCreate(&gg->g, pInit, &graphVMT, 0))) return 0; gg->xorigin = gg->yorigin = 0; diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 6440f171..8fc6ba77 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -14,7 +14,67 @@ #include "gwin/class_gwin.h" /* Our listener for events for widgets */ -static GListener gl; +static GListener gl; + +/* Our default style - a white background theme */ +const GWidgetStyle WhiteWidgetStyle = { + HTML2COLOR(0xFFFFFF), // window background + + // enabled color set + { + HTML2COLOR(0x000000), // text + HTML2COLOR(0x404040), // edge + HTML2COLOR(0xE0E0E0), // fill + HTML2COLOR(0xE0E0E0), // progress - inactive area + }, + + // disabled color set + { + HTML2COLOR(0xC0C0C0), // text + HTML2COLOR(0x808080), // edge + HTML2COLOR(0xE0E0E0), // fill + HTML2COLOR(0xC0E0C0), // progress - active area + }, + + // pressed color set + { + HTML2COLOR(0x404040), // text + HTML2COLOR(0x404040), // edge + HTML2COLOR(0x808080), // fill + HTML2COLOR(0x00E000), // progress - active area + }, +}; + +/* Our black style */ +const GWidgetStyle BlackWidgetStyle = { + HTML2COLOR(0x000000), // window background + + // enabled color set + { + HTML2COLOR(0xC0C0C0), // text + HTML2COLOR(0xC0C0C0), // edge + HTML2COLOR(0x606060), // fill + HTML2COLOR(0x404040), // progress - inactive area + }, + + // disabled color set + { + HTML2COLOR(0x808080), // text + HTML2COLOR(0x404040), // edge + HTML2COLOR(0x404040), // fill + HTML2COLOR(0x004000), // progress - active area + }, + + // pressed color set + { + HTML2COLOR(0xFFFFFF), // text + HTML2COLOR(0xC0C0C0), // edge + HTML2COLOR(0xE0E0E0), // fill + HTML2COLOR(0x008000), // progress - active area + }, +}; + +static const GWidgetStyle * defaultStyle = &BlackWidgetStyle; /* We use these everywhere in this file */ #define gw ((GWidgetObject *)gh) @@ -169,9 +229,10 @@ GHandle _gwidgetCreate(GWidgetObject *pgw, const GWidgetInit *pInit, const gwidg if (!(pgw = (GWidgetObject *)_gwindowCreate(&pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) return 0; - pgw->txt = pInit->text ? pInit->text : ""; - pgw->fnDraw = vmt->DefaultDraw; - pgw->fnParam = 0; + pgw->text = pInit->text ? pInit->text : ""; + pgw->fnDraw = pInit->customDraw ? pInit->customDraw : vmt->DefaultDraw; + pgw->fnParam = pInit->customParam; + pgw->pstyle = pInit->customStyle ? pInit->customStyle : defaultStyle; return &pgw->g; } @@ -184,7 +245,7 @@ void _gwidgetDestroy(GHandle gh) { // Deallocate the text (if necessary) if ((gh->flags & GWIN_FLG_ALLOCTXT)) { gh->flags &= ~GWIN_FLG_ALLOCTXT; - gfxFree((void *)gw->txt); + gfxFree((void *)gw->text); } #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE @@ -226,32 +287,60 @@ void _gwidgetRedraw(GHandle gh) { gw->fnDraw(gw, gw->fnParam); } -void gwinSetText(GHandle gh, const char *txt, bool_t useAlloc) { +void gwinSetDefaultStyle(const GWidgetStyle *pstyle, bool_t updateAll) { + if (!pstyle) + pstyle = &BlackWidgetStyle; + + if (updateAll) { + const gfxQueueASyncItem * qi; + GHandle gh; + + for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) { + gh = QItem2GWindow(qi); + if ((gh->flags & GWIN_FLG_WIDGET) && ((GWidgetObject *)gh)->pstyle == defaultStyle) + gwinSetStyle(gh, pstyle); + } + } + gwinSetDefaultBgColor(pstyle->background); + defaultStyle = pstyle; +} + +/** + * @brief Get the current default style. + * + * @api + */ +const GWidgetStyle *gwinGetDefaultStyle(void) { + return defaultStyle; +} + + +void gwinSetText(GHandle gh, const char *text, 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 = ""; + if (gw->text) { + gfxFree((void *)gw->text); + gw->text = ""; } } // Alloc the new text if required - if (txt && !*txt) txt = 0; - if (txt && useAlloc) { + if (!text || !*text) + gw->text = ""; + else if (useAlloc) { char *str; - if ((str = (char *)gfxAlloc(strlen(txt)+1))) { + if ((str = (char *)gfxAlloc(strlen(text)+1))) { gh->flags |= GWIN_FLG_ALLOCTXT; - strcpy(str, txt); + strcpy(str, text); } - txt = (const char *)str; - } - - gw->txt = txt ? txt : ""; + gw->text = (const char *)str; + } else + gw->text = text; _gwidgetRedraw(gh); } @@ -259,7 +348,20 @@ const char *gwinGetText(GHandle gh) { if (!(gh->flags & GWIN_FLG_WIDGET)) return 0; - return gw->txt; + return gw->text; +} + +void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle) { + if (!(gh->flags & GWIN_FLG_WIDGET)) + return; + gw->pstyle = pstyle ? pstyle : defaultStyle; + gh->bgcolor = pstyle->background; + gh->color = pstyle->enabled.text; + _gwidgetRedraw(gh); +} + +const GWidgetStyle *gwinGetStyle(GHandle gh) { + return gw->pstyle; } void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) { diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 92b6cc03..2fd0c905 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -32,11 +32,6 @@ static color_t defaultBgColor = Black; #if GDISP_NEED_TEXT static font_t defaultFont; #endif -#if GWIN_NEED_WINDOWMANAGER - gfxQueueASync _GWINList; - extern GWindowManager GNullWindowManager; - static GWindowManager * cwm; -#endif /*----------------------------------------------- * Helper Routines @@ -52,9 +47,9 @@ static color_t defaultBgColor = Black; } else gwinClear(gh); } - static void _gwm_redim(GHandle gh, const GWindowInit *pInit) { - gh->x = pInit->x; gh->y = pInit->y; - gh->width = pInit->width; gh->height = pInit->height; + static void _gwm_redim(GHandle gh, coord_t x, coord_t y, coord_t width, coord_t height) { + gh->x = x; gh->y = y; + gh->width = width; gh->height = height; if (gh->x < 0) { gh->width += gh->x; gh->x = 0; } if (gh->y < 0) { gh->height += gh->y; gh->y = 0; } if (gh->x > gdispGetWidth()-MIN_WIN_WIDTH) gh->x = gdispGetWidth()-MIN_WIN_WIDTH; @@ -87,9 +82,9 @@ void _gwinInit(void) { _gwidgetInit(); #endif #if GWIN_NEED_WINDOWMANAGER - gfxQueueASyncInit(&_GWINList); - cwm = &GNullWindowManager; - cwm->vmt->Init(); + extern void _gwmInit(void); + + _gwmInit(); #endif } @@ -113,7 +108,7 @@ GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinV #endif #if GWIN_NEED_WINDOWMANAGER - if (!cwm->vmt->Add(pgw, pInit)) { + if (!_GWINwm->vmt->Add(pgw, pInit)) { if ((pgw->flags & GWIN_FLG_DYNAMIC)) gfxFree(pgw); return 0; @@ -129,18 +124,6 @@ GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinV * Routines that affect all windows *-----------------------------------------------*/ -#if GWIN_NEED_WINDOWMANAGER - void gwinSetWindowManager(struct GWindowManager *gwm) { - if (!gwm) - gwm = &GNullWindowManager; - if (cwm != gwm) { - cwm->vmt->DeInit(); - cwm = gwm; - cwm->vmt->Init(); - } - } -#endif - void gwinSetDefaultColor(color_t clr) { defaultFgColor = clr; } @@ -171,7 +154,7 @@ color_t gwinGetDefaultBgColor(void) { * The GWindow Routines *-----------------------------------------------*/ -GHandle gwinCreateWindow(GWindowObject *pgw, const GWindowInit *pInit) { +GHandle gwinWindowCreate(GWindowObject *pgw, const GWindowInit *pInit) { if (!(pgw = _gwindowCreate(pgw, pInit, &basegwinVMT, 0))) return 0; gwinSetVisible(pgw, pInit->show); @@ -181,7 +164,7 @@ GHandle gwinCreateWindow(GWindowObject *pgw, const GWindowInit *pInit) { void gwinDestroy(GHandle gh) { // Remove from the window manager #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Delete(gh); + _GWINwm->vmt->Delete(gh); #endif // Class destroy routine @@ -204,7 +187,7 @@ void gwinSetVisible(GHandle gh, bool_t visible) { if (!(gh->flags & GWIN_FLG_VISIBLE)) { gh->flags |= GWIN_FLG_VISIBLE; #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Visible(gh); + _GWINwm->vmt->Visible(gh); #else _gwm_vis(gh); #endif @@ -213,7 +196,7 @@ void gwinSetVisible(GHandle gh, bool_t visible) { if ((gh->flags & GWIN_FLG_VISIBLE)) { gh->flags &= ~GWIN_FLG_VISIBLE; #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Visible(gh); + _GWINwm->vmt->Visible(gh); #endif } } @@ -253,7 +236,7 @@ bool_t gwinGetEnabled(GHandle gh) { void gwinMove(GHandle gh, coord_t x, coord_t y) { #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Redim(gh, x, y, gh->width, gh->height); + _GWINwm->vmt->Redim(gh, x, y, gh->width, gh->height); #else _gwm_redim(gh, x, y, gh->width, gh->height); #endif @@ -261,44 +244,21 @@ void gwinMove(GHandle gh, coord_t x, coord_t y) { void gwinResize(GHandle gh, coord_t width, coord_t height) { #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Redim(gh, gh->x, gh->y, width, height); + _GWINwm->vmt->Redim(gh, gh->x, gh->y, width, height); #else _gwm_redim(gh, gh->x, gh->y, width, height); #endif } -void gwinSetMinMax(GHandle gh, GWindowMinMax minmax) { +void gwinRedraw(GHandle gh) { #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->MinMax(gh, minmax); + gwinRaise(gh); #else - (void) gh; - (void) minmax; + if ((gh->flags & GWIN_FLG_VISIBLE)) + _gwm_vis(gh); #endif } -void gwinRaise(GHandle gh) { - #if GWIN_NEED_WINDOWMANAGER - cwm->vmt->Raise(gh); - #else - if ((gh->flags & GWIN_FLG_VISIBLE)) { - if (gh->vmt->Redraw) { - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif - gh->vmt->Redraw(gh); - } - } - #endif -} - -GWindowMinMax gwinGetMinMax(GHandle gh) { - if (gh->flags & GWIN_FLG_MINIMIZED) - return GWIN_MINIMIZE; - if (gh->flags & GWIN_FLG_MAXIMIZED) - return GWIN_MAXIMIZE; - return GWIN_NORMAL; -} - #if GDISP_NEED_TEXT void gwinSetFont(GHandle gh, font_t font) { gh->font = font; diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c index 88d61a21..f9f56838 100644 --- a/src/gwin/gwm.c +++ b/src/gwin/gwm.c @@ -43,10 +43,49 @@ static const gwmVMT GNullWindowManagerVMT = { WM_MinMax, }; -const GWindowManager GNullWindowManager = { +static const GWindowManager GNullWindowManager = { &GNullWindowManagerVMT, }; +gfxQueueASync _GWINList; +GWindowManager * _GWINwm; + +/*----------------------------------------------- + * Window Routines + *-----------------------------------------------*/ + +void _gwmInit(void) { + gfxQueueASyncInit(&_GWINList); + _GWINwm = (GWindowManager *)&GNullWindowManager; + _GWINwm->vmt->Init(); +} + +void gwinSetWindowManager(struct GWindowManager *gwm) { + if (!gwm) + gwm = (GWindowManager *)&GNullWindowManager; + if (_GWINwm != gwm) { + _GWINwm->vmt->DeInit(); + _GWINwm = gwm; + _GWINwm->vmt->Init(); + } +} + +void gwinSetMinMax(GHandle gh, GWindowMinMax minmax) { + _GWINwm->vmt->MinMax(gh, minmax); +} + +void gwinRaise(GHandle gh) { + _GWINwm->vmt->Raise(gh); +} + +GWindowMinMax gwinGetMinMax(GHandle gh) { + if (gh->flags & GWIN_FLG_MINIMIZED) + return GWIN_MINIMIZE; + if (gh->flags & GWIN_FLG_MAXIMIZED) + return GWIN_MAXIMIZE; + return GWIN_NORMAL; +} + /*----------------------------------------------- * Window Manager Routines *-----------------------------------------------*/ diff --git a/src/gwin/label.c b/src/gwin/label.c index cd469210..71ed18eb 100644 --- a/src/gwin/label.c +++ b/src/gwin/label.c @@ -25,38 +25,40 @@ #define GLABEL_FLG_HAUTO (GWIN_FIRST_CONTROL_FLAG<<1) // Simple: single line with no wrapping -static coord_t getwidth(const char *txt, font_t font, coord_t maxwidth) { +static coord_t getwidth(const char *text, font_t font, coord_t maxwidth) { (void) maxwidth; - return gdispGetStringWidth(txt, font)+2; // Allow one pixel of padding on each side + return gdispGetStringWidth(text, font)+2; // Allow one pixel of padding on each side } // Simple: single line with no wrapping -static coord_t getheight(const char *txt, font_t font, coord_t maxwidth) { - (void) txt; +static coord_t getheight(const char *text, font_t font, coord_t maxwidth) { + (void) text; (void) maxwidth; return gdispGetFontMetric(font, fontHeight); } static void gwinLabelDefaultDraw(GWidgetObject *gw, void *param) { - (void) param; - coord_t w, h; + coord_t w, h; + (void) param; - w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.width; - h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.height; + w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->text, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.width; + h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->text, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.height; if (gw->g.width != w || gw->g.height != h) { gwinResize(&gw->g, w, h); return; } - gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->txt, gw->g.font, gw->g.color, gw->g.bgcolor, justifyLeft); + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->text, gw->g.font, + (gw->g.flags & GWIN_FLG_ENABLED) ? gw->pstyle->enabled.text : gw->pstyle->disabled.text, gw->pstyle->background, + justifyLeft); } static const gwidgetVMT labelVMT = { { "Label", // The class name - sizeof(GLabelWidget), // The object size + sizeof(GLabelObject), // The object size _gwidgetDestroy, // The destroy routine _gwidgetRedraw, // The redraw routine 0, // The after-clear routine @@ -88,7 +90,7 @@ static const gwidgetVMT labelVMT = { #endif }; -GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) { +GHandle gwinLabelCreate(GLabelObject *widget, GWidgetInit *pInit) { uint16_t flags = 0; // auto assign width @@ -103,7 +105,7 @@ GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) { pInit->g.height = getheight(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x); } - if (!(widget = (GLabelWidget *)_gwidgetCreate(&widget->w, pInit, &labelVMT))) + if (!(widget = (GLabelObject *)_gwidgetCreate(&widget->w, pInit, &labelVMT))) return 0; widget->w.g.flags |= flags; diff --git a/src/gwin/radio.c b/src/gwin/radio.c index d1c65dbc..26ff0b83 100644 --- a/src/gwin/radio.c +++ b/src/gwin/radio.c @@ -24,25 +24,8 @@ // Our pressed state #define GRADIO_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0) -// Default color scheme -static const GRadioColors GRadioDefaultColorsUp = { - HTML2COLOR(0x404040), // color_up_edge; - HTML2COLOR(0xE0E0E0), // color_up_fill; - HTML2COLOR(0x000000), // color_up_txt; -}; -static const GRadioColors GRadioDefaultColorsDown = { - HTML2COLOR(0x404040), // color_dn_edge; - HTML2COLOR(0x808080), // color_dn_fill; - HTML2COLOR(0x404040), // color_dn_txt; -}; -static const GRadioColors GRadioDefaultColorsDisabled = { - HTML2COLOR(0x808080), // color_dis_edge; - HTML2COLOR(0xE0E0E0), // color_dis_fill; - HTML2COLOR(0xC0C0C0), // color_dis_txt; -}; - // Send the button event -static void SendButtonEvent(GWidgetObject *gw) { +static void SendRadioEvent(GWidgetObject *gw) { GSourceListener * psl; GEvent * pe; #define pbe ((GEventGWinRadio *)pe) @@ -66,7 +49,7 @@ static void SendButtonEvent(GWidgetObject *gw) { static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) { (void) x; (void) y; - gwinPressRadio((GHandle)gw); + gwinRadioPress((GHandle)gw); } #endif @@ -75,7 +58,7 @@ static void SendButtonEvent(GWidgetObject *gw) { static void ToggleOn(GWidgetObject *gw, uint16_t role) { (void) role; - gwinPressRadio((GHandle)gw); + gwinRadioPress((GHandle)gw); } static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) { @@ -125,7 +108,7 @@ static const gwidgetVMT radioVMT = { #endif }; -GHandle gwinCreateRadio(GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) { +GHandle gwinRadioCreate(GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) { if (!(gw = (GRadioObject *)_gwidgetCreate(&gw->w, pInit, &radioVMT))) return 0; @@ -133,53 +116,33 @@ GHandle gwinCreateRadio(GRadioObject *gw, const GWidgetInit *pInit, uint16_t gro gw->toggle = GWIDGET_NO_INSTANCE; #endif gw->group = group; - gw->c_up = GRadioDefaultColorsUp; - gw->c_dn = GRadioDefaultColorsDown; - gw->c_dis = GRadioDefaultColorsDisabled; gwinSetVisible((GHandle)gw, pInit->g.show); return (GHandle)gw; } -void gwinSetRadioColors(GHandle gh, const GRadioColors *pUp, const GRadioColors *pDown, const GRadioColors *pDisabled) { - if (gh->vmt != (gwinVMT *)&radioVMT) - return; - - if (pUp) ((GRadioObject *)gh)->c_up = *pUp; - if (pDown) ((GRadioObject *)gh)->c_dn = *pDown; - if (pDisabled) ((GRadioObject *)gh)->c_dis = *pDisabled; -} - -void gwinPressRadio(GHandle gh) { +void gwinRadioPress(GHandle gh) { GHandle gx; if (gh->vmt != (gwinVMT *)&radioVMT || (gh->flags & GRADIO_FLG_PRESSED)) return; - if ((gx = gwinActiveRadio(((GRadioObject *)gh)->group))) { + if ((gx = gwinRadioGetActive(((GRadioObject *)gh)->group))) { gx->flags &= ~GRADIO_FLG_PRESSED; _gwidgetRedraw(gx); } gh->flags |= GRADIO_FLG_PRESSED; _gwidgetRedraw(gh); - SendButtonEvent((GWidgetObject *)gh); + SendRadioEvent((GWidgetObject *)gh); } -bool_t gwinIsRadioPressed(GHandle gh) { +bool_t gwinRadioIsPressed(GHandle gh) { if (gh->vmt != (gwinVMT *)&radioVMT) return FALSE; return (gh->flags & GRADIO_FLG_PRESSED) ? TRUE : FALSE; } -/** - * @brief Find the currently pressed radio button in the specified group - * @return The handle of the pressed radio button or NULL if none are pressed - * - * @param[in] gh The window handle (must be a radio widget) - * - * @api - */ -GHandle gwinActiveRadio(uint16_t group) { +GHandle gwinRadioGetActive(uint16_t group) { const gfxQueueASyncItem * qi; GHandle gh; @@ -195,17 +158,17 @@ GHandle gwinActiveRadio(uint16_t group) { * Custom Draw Routines *----------------------------------------------------------*/ -static GRadioColors *getDrawColors(GWidgetObject *gw) { - if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &((GRadioObject *)gw)->c_dis; - if ((gw->g.flags & GRADIO_FLG_PRESSED)) return &((GRadioObject *)gw)->c_dn; - return &((GRadioObject *)gw)->c_up; +static const GColorSet *getDrawColors(GWidgetObject *gw) { + if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &gw->pstyle->disabled; + if ((gw->g.flags & GRADIO_FLG_PRESSED)) return &gw->pstyle->pressed; + return &gw->pstyle->enabled; } void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) { - #define gcw ((GRadioObject *)gw) - coord_t ld, df; - GRadioColors * pcol; - (void) param; + #define gcw ((GRadioObject *)gw) + coord_t ld, df; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&radioVMT) return; pcol = getDrawColors(gw); @@ -213,46 +176,52 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) { ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height; #if GDISP_NEED_CIRCLE - df = ld/2; - gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->g.bgcolor); - gdispDrawCircle(gw->g.x+df, gw->g.y+df, df, pcol->color_edge); + df = (ld-1)/2; + gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background); + gdispDrawCircle(gw->g.x+df, gw->g.y+df, df, pcol->edge); if (gw->g.flags & GRADIO_FLG_PRESSED) - gdispFillCircle(gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->color_fill); + gdispFillCircle(gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->fill); #else - gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->g.bgcolor); - gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->color_edge); + 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); df = ld < 4 ? 1 : 2; if (gw->g.flags & GRADIO_FLG_PRESSED) - gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->color_fill); + gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill); #endif - gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->txt, gw->g.font, pcol->color_txt, gw->g.bgcolor, justifyLeft); + 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 } void gwinRadioDraw_Button(GWidgetObject *gw, void *param) { - (void) param; - GRadioColors * pcol; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&radioVMT) return; pcol = getDrawColors(gw); - gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); - gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->color_edge); - gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->color_edge); + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter); + gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge); + gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge); } void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) { - (void) param; - GRadioColors * pcol; + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&radioVMT) return; pcol = getDrawColors(gw); - gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter); - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge); + if ((gw->g.flags & GRADIO_FLG_PRESSED)) { + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); + gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter); + } else { + gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter); + gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge); + gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge); + } } #endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */ diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 5aa320f8..4d9c3510 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -29,14 +29,6 @@ #define GWIN_SLIDER_TOGGLE_INC 20 // How many toggles to go from minimum to maximum #endif -static const GSliderColors GSliderDefaultColors = { - HTML2COLOR(0x404040), // color_edge - HTML2COLOR(0x000000), // color_thumb - HTML2COLOR(0x00E000), // color_active - HTML2COLOR(0xE0E0E0), // color_inactive - HTML2COLOR(0xFFFFFF), // color_txt -}; - // Send the slider event static void SendSliderEvent(GWidgetObject *gw) { GSourceListener * psl; @@ -146,10 +138,10 @@ static void ResetDisplayPos(GSliderObject *gsw) { #define gsw ((GSliderObject *)gw) if (role) { - gwinSetSliderPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + gwinSliderSetPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); SendSliderEvent(gw); } else { - gwinSetSliderPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); + gwinSliderSetPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC); SendSliderEvent(gw); } #undef gsw @@ -231,7 +223,7 @@ static const gwidgetVMT sliderVMT = { #endif }; -GHandle gwinCreateSlider(GSliderObject *gs, const GWidgetInit *pInit) { +GHandle gwinSliderCreate(GSliderObject *gs, const GWidgetInit *pInit) { if (!(gs = (GSliderObject *)_gwidgetCreate(&gs->w, pInit, &sliderVMT))) return 0; #if GINPUT_NEED_TOGGLE @@ -241,7 +233,6 @@ GHandle gwinCreateSlider(GSliderObject *gs, const GWidgetInit *pInit) { #if GINPUT_NEED_DIAL gs->dial = GWIDGET_NO_INSTANCE; #endif - gs->c = GSliderDefaultColors; gs->min = 0; gs->max = 100; gs->pos = 0; @@ -250,7 +241,7 @@ GHandle gwinCreateSlider(GSliderObject *gs, const GWidgetInit *pInit) { return (GHandle)gs; } -void gwinSetSliderRange(GHandle gh, int min, int max) { +void gwinSliderSetRange(GHandle gh, int min, int max) { #define gsw ((GSliderObject *)gh) if (gh->vmt != (gwinVMT *)&sliderVMT) @@ -265,7 +256,7 @@ void gwinSetSliderRange(GHandle gh, int min, int max) { #undef gsw } -void gwinSetSliderPosition(GHandle gh, int pos) { +void gwinSliderSetPosition(GHandle gh, int pos) { #define gsw ((GSliderObject *)gh) if (gh->vmt != (gwinVMT *)&sliderVMT) @@ -284,61 +275,70 @@ void gwinSetSliderPosition(GHandle gh, int pos) { #undef gsw } -void gwinSetSliderColors(GHandle gh, const GSliderColors *pColors) { - if (gh->vmt != (gwinVMT *)&sliderVMT) - return; - - ((GSliderObject *)gh)->c = *pColors; -} +/*---------------------------------------------------------- + * Custom Draw Routines + *----------------------------------------------------------*/ void gwinSliderDraw_Std(GWidgetObject *gw, void *param) { - #define gsw ((GSliderObject *)gw) - (void) param; + #define gsw ((GSliderObject *)gw) + const GColorSet * pcol; + (void) param; if (gw->g.vmt != (gwinVMT *)&sliderVMT) return; + if ((gw->g.flags & GWIN_FLG_ENABLED)) + pcol = &gw->pstyle->pressed; + else + pcol = &gw->pstyle->disabled; + if (gw->g.width < gw->g.height) { // Vertical slider if (gsw->dpos != gw->g.height-1) - gdispFillArea(gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, gsw->c.color_active); + gdispFillArea(gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area if (gsw->dpos != 0) - gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gsw->c.color_inactive); - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); - gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, gsw->c.color_thumb); + gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb if (gsw->dpos >= 2) - gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos-2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos-2, gsw->c.color_thumb); + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos-2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos-2, pcol->edge); // Thumb if (gsw->dpos <= gw->g.height-2) - gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos+2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos+2, gsw->c.color_thumb); + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos+2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos+2, pcol->edge); // Thumb // Horizontal slider } else { if (gsw->dpos != gw->g.width-1) - gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gsw->c.color_inactive); + gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area if (gsw->dpos != 0) - gdispFillArea(gw->g.x, gw->g.y, gsw->dpos, gw->g.height, gsw->c.color_active); - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); - gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + gdispFillArea(gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge + gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb if (gsw->dpos >= 2) - gdispDrawLine(gw->g.x+gsw->dpos-2, gw->g.y, gw->g.x+gsw->dpos-2, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + gdispDrawLine(gw->g.x+gsw->dpos-2, gw->g.y, gw->g.x+gsw->dpos-2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb if (gsw->dpos <= gw->g.width-2) - gdispDrawLine(gw->g.x+gsw->dpos+2, gw->g.y, gw->g.x+gsw->dpos+2, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + gdispDrawLine(gw->g.x+gsw->dpos+2, gw->g.y, gw->g.x+gsw->dpos+2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb } - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, gsw->c.color_txt, justifyCenter); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); #undef gsw } void gwinSliderDraw_Image(GWidgetObject *gw, void *param) { - #define gsw ((GSliderObject *)gw) - #define gi ((gdispImage *)param) - coord_t z, v; + #define gsw ((GSliderObject *)gw) + #define gi ((gdispImage *)param) + const GColorSet * pcol; + coord_t z, v; if (gw->g.vmt != (gwinVMT *)&sliderVMT) return; + if ((gw->g.flags & GWIN_FLG_ENABLED)) + pcol = &gw->pstyle->pressed; + else + pcol = &gw->pstyle->disabled; + if (gw->g.width < gw->g.height) { // Vertical slider if (gsw->dpos != 0) // The unfilled area - gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gsw->c.color_inactive); + gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area if (gsw->dpos != gw->g.height-1) { // The filled area for(z=gw->g.height, v=gi->height; z > gsw->dpos;) { z -= v; @@ -349,13 +349,13 @@ void gwinSliderDraw_Image(GWidgetObject *gw, void *param) { gdispImageDraw(gi, gw->g.x, gw->g.y+z, gw->g.width, v, 0, gi->height-v); } } - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); - gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, gsw->c.color_thumb); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge + gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb // Horizontal slider } else { if (gsw->dpos != gw->g.width-1) // The unfilled area - gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gsw->c.color_inactive); + gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area if (gsw->dpos != 0) { // The filled area for(z=0, v=gi->width; z < gsw->dpos; z += v) { if (z+v > gsw->dpos) @@ -363,10 +363,10 @@ void gwinSliderDraw_Image(GWidgetObject *gw, void *param) { gdispImageDraw(gi, gw->g.x+z, gw->g.y, v, gw->g.height, 0, 0); } } - gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gsw->c.color_edge); - gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, gsw->c.color_thumb); + gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge + gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb } - gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, gsw->c.color_txt, justifyCenter); + gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter); #undef gsw } -- cgit v1.2.3 From 7f92794b1151076012ad58d390f489118ad419f4 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 7 Jul 2013 20:11:13 +1000 Subject: Fix image background color bug --- src/gwin/gimage.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c index eef47dc7..2dcba4ba 100644 --- a/src/gwin/gimage.c +++ b/src/gwin/gimage.c @@ -25,16 +25,18 @@ static void _destroy(GWindowObject *gh) { static void _redraw(GHandle gh) { coord_t x, y, w, h, dx, dy; + color_t bg; // The default display area x = gh->x; y = gh->y; w = gh->width; h = gh->height; + bg = gwinGetDefaultBgColor(); // If the image isn't open just clear the area if (!gdispImageIsOpen(&widget(gh)->image)) { - gdispFillArea(x, y, w, h, gh->bgcolor); + gdispFillArea(x, y, w, h, bg); return; } @@ -44,8 +46,8 @@ static void _redraw(GHandle gh) { dx = (gh->width-w)/2; x += dx; if (dx) - gdispFillArea(gh->x, y, dx, h, gh->bgcolor); - gdispFillArea(x+w, y, gh->width-dx-w, h, gh->bgcolor); + gdispFillArea(gh->x, y, dx, h, bg); + gdispFillArea(x+w, y, gh->width-dx-w, h, bg); dx = 0; } @@ -60,8 +62,8 @@ static void _redraw(GHandle gh) { dy = (gh->height-h)/2; y += dy; if (dy) - gdispFillArea(x, gh->y, w, dy, gh->bgcolor); - gdispFillArea(x, y+h, w, gh->height-dy-h, gh->bgcolor); + gdispFillArea(x, gh->y, w, dy, bg); + gdispFillArea(x, y+h, w, gh->height-dy-h, bg); dy = 0; } @@ -71,7 +73,7 @@ static void _redraw(GHandle gh) { } // Reset the background color in case it has changed - gdispImageSetBgColor(&widget(gh)->image, gh->bgcolor); + gdispImageSetBgColor(&widget(gh)->image, bg); // Display the image gdispImageDraw(&widget(gh)->image, x, y, w, h, dx, dy); -- cgit v1.2.3 From c5ec72027787c9cd5f5b36a46eb55f03fd95d894 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 7 Jul 2013 20:11:38 +1000 Subject: Fix enabled visibility bug --- src/gwin/gwin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 2fd0c905..e5997bc8 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -210,7 +210,7 @@ void gwinSetEnabled(GHandle gh, bool_t enabled) { if (enabled) { if (!(gh->flags & GWIN_FLG_ENABLED)) { gh->flags |= GWIN_FLG_ENABLED; - if (gh->vmt->Redraw) { + if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) { #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif @@ -220,7 +220,7 @@ void gwinSetEnabled(GHandle gh, bool_t enabled) { } else { if ((gh->flags & GWIN_FLG_ENABLED)) { gh->flags &= ~GWIN_FLG_ENABLED; - if (gh->vmt->Redraw) { + if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) { #if GDISP_NEED_CLIP gdispSetClip(gh->x, gh->y, gh->width, gh->height); #endif -- cgit v1.2.3