2013-12-01 22:53:42 +00:00
|
|
|
/*
|
|
|
|
* 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://ugfx.org/license.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2014-08-20 07:42:53 +00:00
|
|
|
* @file src/gwin/gwin_progressbar.c
|
2014-05-20 16:05:38 +00:00
|
|
|
* @brief GWIN sub-system progressbar code
|
2013-12-01 22:53:42 +00:00
|
|
|
*/
|
|
|
|
|
2015-11-21 09:27:08 +00:00
|
|
|
#include "../../gfx.h"
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
#if (GFX_USE_GWIN && GWIN_NEED_PROGRESSBAR) || defined(__DOXYGEN__)
|
|
|
|
|
2014-08-20 07:42:53 +00:00
|
|
|
#include "gwin_class.h"
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
// Reset the display position back to the value predicted by the saved progressbar position
|
2015-06-08 04:14:40 +00:00
|
|
|
static void PBResetDisplayPos(GProgressbarObject *gsw) {
|
2013-12-01 22:53:42 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-04-23 21:55:35 +00:00
|
|
|
// We have to deinitialize the timer which auto updates the progressbar if any
|
2015-06-08 04:14:40 +00:00
|
|
|
static void PBDestroy(GHandle gh) {
|
2014-05-11 18:20:49 +00:00
|
|
|
#if GWIN_PROGRESSBAR_AUTO
|
2015-01-03 08:44:48 +00:00
|
|
|
gtimerStop(&((GProgressbarObject *)gh)->gt);
|
|
|
|
gtimerDeinit(&((GProgressbarObject *)gh)->gt);
|
2014-04-23 21:55:35 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
_gwidgetDestroy(gh);
|
|
|
|
}
|
|
|
|
|
2013-12-01 22:53:42 +00:00
|
|
|
// The progressbar VMT table
|
|
|
|
static const gwidgetVMT progressbarVMT = {
|
|
|
|
{
|
|
|
|
"Progressbar", // The classname
|
|
|
|
sizeof(GProgressbarObject), // The object size
|
2015-06-08 04:14:40 +00:00
|
|
|
PBDestroy, // The destroy routine
|
2013-12-01 22:53:42 +00:00
|
|
|
_gwidgetRedraw, // The redraw routine
|
|
|
|
0, // The after-clear routine
|
|
|
|
},
|
|
|
|
gwinProgressbarDraw_Std, // The default drawing routine
|
|
|
|
#if GINPUT_NEED_MOUSE
|
|
|
|
{
|
|
|
|
0, // Process mouse down events (NOT USED)
|
|
|
|
0, // Process mouse up events
|
|
|
|
0, // Process mouse move events
|
|
|
|
},
|
|
|
|
#endif
|
2015-08-16 14:18:54 +00:00
|
|
|
#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
|
2015-08-12 15:32:38 +00:00
|
|
|
{
|
|
|
|
0 // Process keyboard events
|
|
|
|
},
|
|
|
|
#endif
|
2013-12-01 22:53:42 +00:00
|
|
|
#if GINPUT_NEED_TOGGLE
|
|
|
|
{
|
|
|
|
0, // 1 toggle role
|
|
|
|
0, // Assign Toggles
|
|
|
|
0, // Get Toggles
|
|
|
|
0, // Process toggle off events (NOT USED)
|
|
|
|
0, // Process toggle on events
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#if GINPUT_NEED_DIAL
|
|
|
|
{
|
|
|
|
0, // 1 dial roles
|
|
|
|
0, // Assign Dials
|
|
|
|
0, // Get Dials
|
|
|
|
0, // Process dial move events
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidgetInit *pInit) {
|
|
|
|
if (!(gs = (GProgressbarObject *)_gwidgetCreate(g, &gs->w, pInit, &progressbarVMT)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
gs->min = 0;
|
|
|
|
gs->max = 100;
|
|
|
|
gs->res = 1;
|
|
|
|
gs->pos = 0;
|
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
#if GWIN_PROGRESSBAR_AUTO
|
|
|
|
gtimerInit(&gs->gt);
|
|
|
|
#endif
|
|
|
|
|
2015-06-08 04:14:40 +00:00
|
|
|
PBResetDisplayPos(gs);
|
2013-12-01 22:53:42 +00:00
|
|
|
gwinSetVisible((GHandle)gs, pInit->g.show);
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2013-12-01 22:53:42 +00:00
|
|
|
return (GHandle)gs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gwinProgressbarSetRange(GHandle gh, int min, int max) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
|
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (min == max) // prevent divide by 0 errors.
|
|
|
|
max++;
|
|
|
|
gsw->min = min;
|
|
|
|
gsw->max = max;
|
|
|
|
gsw->pos = min;
|
|
|
|
|
2015-06-08 04:14:40 +00:00
|
|
|
PBResetDisplayPos(gsw);
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
|
|
|
|
void gwinProgressbarSetPosition(GHandle gh, int pos) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
|
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gsw->min <= gsw->max) {
|
|
|
|
if (pos < gsw->min) gsw->pos = gsw->min;
|
|
|
|
else if (pos > gsw->max) gsw->pos = gsw->max;
|
|
|
|
else gsw->pos = pos;
|
|
|
|
} else {
|
|
|
|
if (pos > gsw->min) gsw->pos = gsw->min;
|
|
|
|
else if (pos < gsw->max) gsw->pos = gsw->max;
|
|
|
|
else gsw->pos = pos;
|
|
|
|
}
|
|
|
|
|
2015-06-08 04:14:40 +00:00
|
|
|
PBResetDisplayPos(gsw);
|
2014-05-21 03:02:00 +00:00
|
|
|
_gwinUpdate(gh);
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
|
|
|
|
void gwinProgressbarSetResolution(GHandle gh, int resolution) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
|
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (resolution <= 0)
|
|
|
|
resolution = 1;
|
|
|
|
|
|
|
|
gsw->res = resolution;
|
|
|
|
|
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
|
|
|
|
void gwinProgressbarIncrement(GHandle gh) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
|
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gsw->max - gsw->pos > gsw->res)
|
|
|
|
gsw->pos += gsw->res;
|
|
|
|
else
|
|
|
|
gsw->pos = gsw->max;
|
|
|
|
|
2015-06-08 04:14:40 +00:00
|
|
|
PBResetDisplayPos(gsw);
|
2014-05-21 03:02:00 +00:00
|
|
|
_gwinUpdate(gh);
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
|
|
|
|
void gwinProgressbarDecrement(GHandle gh) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
|
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gsw->pos > gsw->res)
|
|
|
|
gsw->pos -= gsw->min;
|
|
|
|
else
|
|
|
|
gsw->pos = gsw->min;
|
|
|
|
|
|
|
|
gsw->pos -= gsw->res;
|
|
|
|
|
2015-06-08 04:14:40 +00:00
|
|
|
PBResetDisplayPos(gsw);
|
2014-05-21 03:02:00 +00:00
|
|
|
_gwinUpdate(gh);
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
#if GWIN_PROGRESSBAR_AUTO
|
|
|
|
// used by gwinProgressbarStart();
|
|
|
|
static void _progressbarCallback(void *param) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
|
|
|
GHandle gh = (GHandle)param;
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
gwinProgressbarIncrement(gh);
|
2014-09-29 05:46:34 +00:00
|
|
|
|
|
|
|
if (gsw->pos >= gsw->max)
|
|
|
|
gtimerStop(&gsw->gt);
|
|
|
|
|
|
|
|
#undef gsw
|
2014-05-08 12:37:13 +00:00
|
|
|
}
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
void gwinProgressbarStart(GHandle gh, delaytime_t delay) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
2014-09-29 05:46:34 +00:00
|
|
|
|
|
|
|
gtimerStart(&gsw->gt, _progressbarCallback, gh, TRUE, delay);
|
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
#undef gsw
|
|
|
|
}
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
void gwinProgressbarStop(GHandle gh) {
|
|
|
|
#define gsw ((GProgressbarObject *)gh)
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
if (gh->vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
2014-09-29 05:46:34 +00:00
|
|
|
|
|
|
|
gtimerStop(&gsw->gt);
|
|
|
|
|
2014-05-08 12:37:13 +00:00
|
|
|
#undef gsw
|
|
|
|
}
|
|
|
|
#endif /* GWIN_PROGRESSBAR_AUTO */
|
2014-04-23 21:29:50 +00:00
|
|
|
|
2013-12-01 22:53:42 +00:00
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Custom Draw Routines
|
|
|
|
*----------------------------------------------------------*/
|
|
|
|
|
|
|
|
void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param) {
|
|
|
|
#define gsw ((GProgressbarObject *)gw)
|
2014-09-29 05:46:34 +00:00
|
|
|
|
2013-12-01 22:53:42 +00:00
|
|
|
const GColorSet * pcol;
|
|
|
|
(void) param;
|
|
|
|
|
|
|
|
if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
2014-04-26 01:07:21 +00:00
|
|
|
// get the colors right
|
2014-05-09 15:11:30 +00:00
|
|
|
if ((gw->g.flags & GWIN_FLG_SYSENABLED))
|
2015-12-18 21:49:59 +00:00
|
|
|
pcol = &gw->pstyle->enabled;
|
2013-12-01 22:53:42 +00:00
|
|
|
else
|
|
|
|
pcol = &gw->pstyle->disabled;
|
|
|
|
|
2014-04-26 01:07:21 +00:00
|
|
|
// Vertical progressbar
|
|
|
|
if (gw->g.width < gw->g.height) {
|
2013-12-01 22:53:42 +00:00
|
|
|
if (gsw->dpos != gw->g.height-1)
|
2014-04-26 01:07:21 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area
|
2013-12-01 22:53:42 +00:00
|
|
|
if (gsw->dpos != 0)
|
2015-12-18 21:49:59 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, pcol->fill); // Inactive area
|
2014-04-26 01:07:21 +00:00
|
|
|
gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
|
|
|
|
gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
// Horizontal progressbar
|
|
|
|
} else {
|
|
|
|
if (gsw->dpos != gw->g.width-1)
|
2015-12-18 21:49:59 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, pcol->fill); // Inactive area
|
2013-12-01 22:53:42 +00:00
|
|
|
if (gsw->dpos != 0)
|
2014-04-26 01:07:21 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area
|
|
|
|
gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
|
|
|
|
gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
|
2013-12-01 22:53:42 +00:00
|
|
|
}
|
|
|
|
gdispGDrawStringBox(gw->g.display, 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
|
|
|
|
}
|
|
|
|
|
|
|
|
#if GDISP_NEED_IMAGE
|
|
|
|
void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param) {
|
|
|
|
#define gsw ((GProgressbarObject *)gw)
|
|
|
|
#define gi ((gdispImage *)param)
|
|
|
|
const GColorSet * pcol;
|
|
|
|
coord_t z, v;
|
|
|
|
|
|
|
|
if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
|
|
|
|
return;
|
|
|
|
|
2014-05-09 15:11:30 +00:00
|
|
|
if ((gw->g.flags & GWIN_FLG_SYSENABLED))
|
2015-12-18 21:49:59 +00:00
|
|
|
pcol = &gw->pstyle->enabled;
|
2013-12-01 22:53:42 +00:00
|
|
|
else
|
|
|
|
pcol = &gw->pstyle->disabled;
|
|
|
|
|
2015-12-18 21:49:59 +00:00
|
|
|
// Vertical progressbar
|
|
|
|
if (gw->g.width < gw->g.height) {
|
2013-12-01 22:53:42 +00:00
|
|
|
if (gsw->dpos != 0) // The unfilled area
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gsw->dpos-1, gw->pstyle->enabled.progress); // Inactive area
|
2013-12-01 22:53:42 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGImageDraw(gw->g.display, gi, gw->g.x+1, gw->g.y+z+1, gw->g.width-1, v-2, 0, gi->height-v);
|
2013-12-01 22:53:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGDrawLine(gw->g.display, gw->g.x+1, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-2, gw->g.y+gsw->dpos, pcol->edge); // Thumb
|
2013-12-01 22:53:42 +00:00
|
|
|
|
|
|
|
// Horizontal progressbar
|
|
|
|
} else {
|
|
|
|
if (gsw->dpos != gw->g.width-1) // The unfilled area
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos+1, gw->g.y+1, gw->g.width-gsw->dpos-2, gw->g.height-2, gw->pstyle->enabled.progress); // Inactive area
|
2013-12-01 22:53:42 +00:00
|
|
|
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;
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGImageDraw(gw->g.display, gi, gw->g.x+z+1, gw->g.y+1, v-1, gw->g.height-2, 0, 0);
|
2013-12-01 22:53:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
|
2016-02-13 01:33:20 +00:00
|
|
|
gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y+1, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-2, pcol->edge); // Thumb
|
2013-12-01 22:53:42 +00:00
|
|
|
}
|
|
|
|
gdispGDrawStringBox(gw->g.display, 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
|
|
|
|
}
|
|
|
|
#endif /* GDISP_NEED_IMAGE */
|
|
|
|
|
|
|
|
#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
|