version 2.8
gwin_progressbar.c
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.org/license.html
6  */
7 
8 /**
9  * @file src/gwin/gwin_progressbar.c
10  * @brief GWIN sub-system progressbar code
11  */
12 
13 #include "../../gfx.h"
14 
15 #if (GFX_USE_GWIN && GWIN_NEED_PROGRESSBAR) || defined(__DOXYGEN__)
16 
17 #include "gwin_class.h"
18 
19 // Reset the display position back to the value predicted by the saved progressbar position
20 static void PBResetDisplayPos(GProgressbarObject *gsw) {
21  if (gsw->w.g.width < gsw->w.g.height)
22  gsw->dpos = gsw->w.g.height-1-((gsw->w.g.height-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min);
23  else
24  gsw->dpos = ((gsw->w.g.width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min);
25 }
26 
27 // We have to deinitialize the timer which auto updates the progressbar if any
28 static void PBDestroy(GHandle gh) {
29  #if GWIN_PROGRESSBAR_AUTO
30  gtimerStop(&((GProgressbarObject *)gh)->gt);
31  gtimerDeinit(&((GProgressbarObject *)gh)->gt);
32  #endif
33 
34  _gwidgetDestroy(gh);
35 }
36 
37 // The progressbar VMT table
38 static const gwidgetVMT progressbarVMT = {
39  {
40  "Progressbar", // The classname
41  sizeof(GProgressbarObject), // The object size
42  PBDestroy, // The destroy routine
43  _gwidgetRedraw, // The redraw routine
44  0, // The after-clear routine
45  },
46  gwinProgressbarDraw_Std, // The default drawing routine
48  {
49  0, // Process mouse down events (NOT USED)
50  0, // Process mouse up events
51  0, // Process mouse move events
52  },
53  #endif
54  #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
55  {
56  0 // Process keyboard events
57  },
58  #endif
59  #if GINPUT_NEED_TOGGLE
60  {
61  0, // 1 toggle role
62  0, // Assign Toggles
63  0, // Get Toggles
64  0, // Process toggle off events (NOT USED)
65  0, // Process toggle on events
66  },
67  #endif
68  #if GINPUT_NEED_DIAL
69  {
70  0, // 1 dial roles
71  0, // Assign Dials
72  0, // Get Dials
73  0, // Process dial move events
74  },
75  #endif
76 };
77 
78 GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidgetInit *pInit) {
79  if (!(gs = (GProgressbarObject *)_gwidgetCreate(g, &gs->w, pInit, &progressbarVMT)))
80  return 0;
81 
82  gs->min = 0;
83  gs->max = 100;
84  gs->res = 1;
85  gs->pos = 0;
86 
87  #if GWIN_PROGRESSBAR_AUTO
88  gtimerInit(&gs->gt);
89  #endif
90 
91  PBResetDisplayPos(gs);
92  gwinSetVisible((GHandle)gs, pInit->g.show);
93 
94  return (GHandle)gs;
95 }
96 
97 void gwinProgressbarSetRange(GHandle gh, int min, int max) {
98  #define gsw ((GProgressbarObject *)gh)
99 
100  if (gh->vmt != (gwinVMT *)&progressbarVMT)
101  return;
102 
103  if (min == max) // prevent divide by 0 errors.
104  max++;
105  if (min <= max) {
106  gsw->min = min;
107  gsw->max = max;
108  gsw->pos = min;
109  gsw->res = 1;
110  } else {
111  gsw->min = max;
112  gsw->max = min;
113  gsw->pos = min;
114  gsw->res = -1;
115  }
116 
117  PBResetDisplayPos(gsw);
118 
119  #undef gsw
120 }
121 
123  #define gsw ((GProgressbarObject *)gh)
124 
125  if (gh->vmt != (gwinVMT *)&progressbarVMT)
126  return;
127 
128  if (pos < gsw->min) gsw->pos = gsw->min;
129  else if (pos > gsw->max) gsw->pos = gsw->max;
130  else gsw->pos = pos;
131 
132  PBResetDisplayPos(gsw);
133  _gwinUpdate(gh);
134 
135  #undef gsw
136 }
137 
138 void gwinProgressbarSetResolution(GHandle gh, int resolution) {
139  #define gsw ((GProgressbarObject *)gh)
140 
141  if (gh->vmt != (gwinVMT *)&progressbarVMT)
142  return;
143 
144  gsw->res = resolution;
145 
146  #undef gsw
147 }
148 
150  #define gsw ((GProgressbarObject *)gh)
151 
152  if (gh->vmt != (gwinVMT *)&progressbarVMT)
153  return;
154 
155  gsw->pos += gsw->res;
156  if (gsw->pos < gsw->min) gsw->pos = gsw->min;
157  else if (gsw->pos > gsw->max) gsw->pos = gsw->max;
158 
159  PBResetDisplayPos(gsw);
160  _gwinUpdate(gh);
161 
162  #undef gsw
163 }
164 
166  #define gsw ((GProgressbarObject *)gh)
167 
168  if (gh->vmt != (gwinVMT *)&progressbarVMT)
169  return;
170 
171  gsw->pos -= gsw->res;
172  if (gsw->pos < gsw->min) gsw->pos = gsw->min;
173  else if (gsw->pos > gsw->max) gsw->pos = gsw->max;
174 
175  PBResetDisplayPos(gsw);
176  _gwinUpdate(gh);
177 
178  #undef gsw
179 }
180 
181 #if GWIN_PROGRESSBAR_AUTO
182  // used by gwinProgressbarStart();
183  static void _progressbarCallback(void *param) {
184  #define gsw ((GProgressbarObject *)gh)
185  GHandle gh = (GHandle)param;
186 
187  if (gh->vmt != (gwinVMT *)&progressbarVMT)
188  return;
189 
191 
192  if (gsw->pos >= gsw->max)
193  gtimerStop(&gsw->gt);
194 
195  #undef gsw
196  }
197 
198  void gwinProgressbarStart(GHandle gh, delaytime_t delay) {
199  #define gsw ((GProgressbarObject *)gh)
200 
201  if (gh->vmt != (gwinVMT *)&progressbarVMT)
202  return;
203 
204  gtimerStart(&gsw->gt, _progressbarCallback, gh, TRUE, delay);
205 
206  #undef gsw
207  }
208 
209  void gwinProgressbarStop(GHandle gh) {
210  #define gsw ((GProgressbarObject *)gh)
211 
212  if (gh->vmt != (gwinVMT *)&progressbarVMT)
213  return;
214 
215  gtimerStop(&gsw->gt);
216 
217  #undef gsw
218  }
219 #endif /* GWIN_PROGRESSBAR_AUTO */
220 
221 /*----------------------------------------------------------
222  * Custom Draw Routines
223  *----------------------------------------------------------*/
224 
225 void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param) {
226  #define gsw ((GProgressbarObject *)gw)
227 
228  const GColorSet * pcol;
229  (void) param;
230 
231  if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
232  return;
233 
234  // get the colors right
235  if ((gw->g.flags & GWIN_FLG_SYSENABLED))
236  pcol = &gw->pstyle->enabled;
237  else
238  pcol = &gw->pstyle->disabled;
239 
240  // Vertical progressbar
241  if (gw->g.width < gw->g.height) {
242  if (gsw->dpos != gw->g.height-1)
243  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area
244  if (gsw->dpos != 0)
245  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, pcol->fill); // Inactive area
246  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
247  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
248 
249  // Horizontal progressbar
250  } else {
251  if (gsw->dpos != gw->g.width-1)
252  gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, pcol->fill); // Inactive area
253  if (gsw->dpos != 0)
254  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area
255  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
256  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
257  }
258  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);
259 
260  #undef gsw
261 }
262 
263 #if GDISP_NEED_IMAGE
264 void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param) {
265  #define gsw ((GProgressbarObject *)gw)
266  #define gi ((gdispImage *)param)
267  const GColorSet * pcol;
268  coord_t z, v;
269 
270  if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
271  return;
272 
273  if ((gw->g.flags & GWIN_FLG_SYSENABLED))
274  pcol = &gw->pstyle->enabled;
275  else
276  pcol = &gw->pstyle->disabled;
277 
278  // Vertical progressbar
279  if (gw->g.width < gw->g.height) {
280  if (gsw->dpos != 0) // The unfilled area
281  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
282  if (gsw->dpos != gw->g.height-1) { // The filled area
283  for(z=gw->g.height, v=gi->height; z > gsw->dpos;) {
284  z -= v;
285  if (z < gsw->dpos) {
286  v -= gsw->dpos - z;
287  z = gsw->dpos;
288  }
289  gdispGImageDraw(gw->g.display, gi, gw->g.x+1, gw->g.y+z+1, gw->g.width-1, v-2, 0, gi->height-v);
290  }
291  }
292  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
293  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
294 
295  // Horizontal progressbar
296  } else {
297  if (gsw->dpos != gw->g.width-1) // The unfilled area
298  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
299  if (gsw->dpos != 0) { // The filled area
300  for(z=0, v=gi->width; z < gsw->dpos; z += v) {
301  if (z+v > gsw->dpos)
302  v -= z+v - gsw->dpos;
303  gdispGImageDraw(gw->g.display, gi, gw->g.x+z+1, gw->g.y+1, v-1, gw->g.height-2, 0, 0);
304  }
305  }
306  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
307  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
308  }
309  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);
310 
311  #undef gsw
312 }
313 #endif /* GDISP_NEED_IMAGE */
314 
315 #endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
#define gt(str)
A wrapper macro to make writing and reading translatable applications easier.
Definition: gtrans.h:41
const struct gwinVMT * vmt
Definition: gwin.h:45
void gtimerDeinit(GTimer *pt)
Deinitialise a timer.
Definition: gtimer.c:134
void gtimerInit(GTimer *pt)
Initialise a timer.
Definition: gtimer.c:129
uint32_t flags
Definition: gwin.h:53
int16_t coord_t
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
The structure to initialise a widget.
Definition: gwin_widget.h:97
GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidgetInit *pInit)
Create a progressbar window.
coord_t y
Definition: gwin.h:48
coord_t x
Definition: gwin.h:47
color_t text
Definition: gwin_widget.h:38
GWindowInit g
Definition: gwin_widget.h:98
void gtimerStop(GTimer *pt)
Stop a timer (periodic or otherwise)
Definition: gtimer.c:190
#define GINPUT_NEED_MOUSE
Should mouse/touch functions be included.
The GColorSet structure.
Definition: gwin_widget.h:37
GWindowObject g
Definition: gwin_widget.h:119
void gwinProgressbarSetResolution(GHandle gh, int resolution)
Set the resolution for the incrementation and decrementation of the progressbar.
void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color)
Draw a line.
GColorSet disabled
Definition: gwin_widget.h:56
void gwinProgressbarSetRange(GHandle gh, int min, int max)
Set the progressbar range.
void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color)
Fill an area with a color.
GColorSet enabled
Definition: gwin_widget.h:55
const char * text
Definition: gwin_widget.h:120
void gwinSetVisible(GHandle gh, bool_t visible)
Sets whether a window is visible or not.
const GWidgetStyle * pstyle
Definition: gwin_widget.h:123
The GWIN Widget structure.
Definition: gwin_widget.h:118
bool_t show
Definition: gwin.h:80
void gwinProgressbarDecrement(GHandle gh)
Decrement the progressbar value.
GDisplay * display
Definition: gwin.h:46
void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char *str, font_t font, color_t color, justify_t justify)
Draw a text string vertically centered within the specified box.
coord_t height
Definition: gwin.h:50
void gwinProgressbarIncrement(GHandle gh)
Increment the progressbar value.
The Virtual Method Table for a widget.
Definition: gwin_class.h:85
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, delaytime_t millisec)
Set a timer going or alter its properties if it is already going.
Definition: gtimer.c:139
coord_t width
Definition: gwin.h:49
color_t progress
Definition: gwin_widget.h:41
gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy)
Draw the image.
void gwinProgressbarStop(GHandle gh)
Stop the timer which is started by gwinProgressbarStart()
void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color)
Draw a rectangular box.
color_t fill
Definition: gwin_widget.h:40
The Virtual Method Table for a GWIN window.
Definition: gwin_class.h:55
A window object structure.
Definition: gwin.h:40
void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param)
The default rendering function for the progressbar widget.
void gwinProgressbarSetPosition(GHandle gh, int pos)
Set the progressbar position.
void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param)
Renders a progressbar using an image.
void gwinProgressbarStart(GHandle gh, delaytime_t delay)
Automatically increments the progress bar.
#define TRUE
Generic &#39;true&#39; boolean constant.
Definition: gfx.h:38
color_t edge
Definition: gwin_widget.h:39