SmoothProgress 1.0.0
Displays smooth progress bars on a character based LCD displays for Arduino
SmoothProgress.h
1
33#ifndef SMOOTH_PROGRESS_H
34#define SMOOTH_PROGRESS_H
35
36#define SMOOTH_PROGRESS_VER 1.0.0
37
38#include <barstyle.h>
39
40//try to determine the LCD library included
41#if defined(LiquidCrystal_I2C_h)
42#define LCD_OBJ LiquidCrystal_I2C
43//#if defined(hd44780_h)
44#elif defined(hd44780_I2Cexp_h)
45#define LCD_OBJ hd44780_I2Cexp
46#elif defined(hd44780_HC1627_I2C_h)
47#define LCD_OBJ hd44780_HC1627_I2C
48#elif defined(hd44780_I2Clcd_h)
49#define LCD_OBJ hd44780_I2Clcd
50#elif defined(FDB_LIQUID_CRYSTAL_I2C_H)
51#define LCD_OBJ LiquidCrystal_I2C
52#elif defined(LiquidCrystal_h)
53#define LCD_OBJ LiquidCrystal
54#else
55#define LCD_OBJ ERROR_NO_LCD_OBJ
56#error "No supported LiquidCrystal library included. Please check that the LiquidCrystal library is included BEFORE SmoothProgress.h"
57#endif
58
59// constants to specify where there the data for the progress bar style (bit-masks) are stored in memory (SRAM) or in flash (PROGMEM)
60enum MemoryType { RAM = 0, FLASH = 1, DATA = 0, PROG = 1 };
61
62class __FlashBarStyleHelper;
63#define FBS(style) (reinterpret_cast<const __FlashBarStyleHelper *>(style))
64
73{
74public:
80 inPROGMEM(const barstyle& bs) : bsp(&bs) {}
81 inline const barstyle* unwrap() const { return bsp; }
82private:
83 const barstyle* bsp;
84};
85
86template <class DISP = LCD_OBJ>
88{
89public:
90 // constants defining which character positions for the user definable characters will be used for what purpose when drawing the progress bar
91 enum UDCharCode : byte { ProgBarCharBlank = 0, ProgBarCharFull, ProgBarCharBegin, ProgBarCharEnd, ProgBarCharPartial };
92
100 BarDisplay(DISP& displ, const barstyle& bs) : disp(displ), barStyle(&bs), styleMemPlacement(RAM) { }
101
109 BarDisplay(DISP& displ, const inPROGMEM& wraped) : disp(displ), barStyle(wraped.unwrap()), styleMemPlacement(FLASH) { }
110
111 BarDisplay(DISP& displ, const barstyle* bsp) : disp(displ), barStyle(bsp), styleMemPlacement(RAM) { }
112 BarDisplay(DISP& displ, const __FlashBarStyleHelper* bspf) : disp(displ), barStyle(bspf), styleMemPlacement(FLASH) { }
113
114 BarDisplay(const BarDisplay&) = delete;
115 BarDisplay& operator=(const BarDisplay&) = delete;
116
121 inline DISP & dsplay() const
122 {
123 return disp;
124 }
125
130 inline const barstyle& getStyle() const
131 {
132 return *barStyle;
133 }
134
139 void setStyle(const barstyle& bs)
140 {
141 barStyle = &bs;
142 styleMemPlacement = RAM;
143 begin();
144 }
145
150 void setStyle(const inPROGMEM& wraped)
151 {
152 barStyle = wraped.unwrap();
153 styleMemPlacement = FLASH;
154 begin();
155 }
156
162 {
163 if (styleMemPlacement == RAM)
164 {
165 return(barStyle->stylePar);
166 }
167 else
168 {
169 uint8_t m = pgm_read_byte(&(barStyle->stylePar));
170 return *(reinterpret_cast<struct barstyle::bspar*>(&m));
171 }
172 }
173
178 inline int styleStartOffset() const
179 {
180 return stylePar().startOffset;
181 }
182
187 inline int styleEndOffset() const
188 {
189 return stylePar().endOffset;
190 }
191
196 inline uint8_t styleOrientation() const
197 {
198 return stylePar().dir;
199 }
200
204 void begin() const
205 {
206 // create the blank piece in the middle
207 createChar(ProgBarCharBlank, (barStyle->middleMask[barstyle::ORmask]));
208 // create the completely filled piece in the middle
209 createChar(ProgBarCharFull, barStyle->middleMask);
210 // create the full piece at the beginning (left edge of the frame when filled, bottom on vertical progress bar)
211 createChar(ProgBarCharBegin, barStyle->startMask);
212 // create the blank piece at the end (right edge of the frame when blank, top on vertical progress bar)
213 createChar(ProgBarCharEnd, (barStyle->endMask[barstyle::ORmask]));
214 }
215
222 void makeChar(byte udChr, const uint8_t xMask[2][barstyle::CharPatRows], uint8_t mask) const
223 {
224 uint8_t t[barstyle::CharPatRows];
225 if (styleMemPlacement == RAM)
226 {
227 makeCharMask(t, xMask, mask);
228 }
229 else // in FLASH
230 {
231 uint8_t tao[2][barstyle::CharPatRows];
232 memcpy_P(tao, xMask, barstyle::CharPatRows << 1);
233 makeCharMask(t, tao, mask);
234 }
235 disp.createChar(udChr, t);
236 }
237
238protected:
245 void makeCharMask(uint8_t out[barstyle::CharPatRows], const uint8_t xMask[2][barstyle::CharPatRows], uint8_t mask) const
246 {
247 if (styleOrientation() == barstyle::Vertical)
248 {
249 for (byte i = 0; i < barstyle::CharPatRows; i++, mask >>= 1)
250 {
251 out[i] = (mask & 1) ? (xMask[0][i] | xMask[1][i]) : xMask[1][i];
252 }
253 }
254 else // Horizontal
255 {
256 for (byte i = 0; i < barstyle::CharPatRows; i++)
257 {
258 out[i] = (mask & xMask[0][i]) | xMask[1][i];
259 }
260 }
261 }
262
269 void createChar(byte udChr, const uint8_t bitMask[barstyle::CharPatRows]) const
270 {
271 if (styleMemPlacement == RAM)
272 {
273 disp.createChar(udChr, const_cast<uint8_t*>(bitMask));
274 }
275 else // in FLASH
276 {
277 uint8_t ta[barstyle::CharPatRows];
278 memcpy_P(ta, bitMask, barstyle::CharPatRows);
279 disp.createChar(udChr, ta);
280 }
281 }
282
289 void createChar(byte udChr, const uint8_t xMask[2][barstyle::CharPatRows]) const
290 {
291 if (styleMemPlacement == RAM)
292 {
293 uint8_t t[barstyle::CharPatRows];
294 for (byte i = 0; i < barstyle::CharPatRows; i++)
295 {
296 t[i] = xMask[0][i] | xMask[1][i];
297 }
298 disp.createChar(udChr, t);
299 }
300 else // in FLASH
301 {
302 uint8_t tao[2][barstyle::CharPatRows];
303 memcpy_P(tao, xMask, barstyle::CharPatRows << 1);
304 for (byte i = 0; i < barstyle::CharPatRows; i++)
305 {
306 tao[0][i] |= tao[1][i];
307 }
308 disp.createChar(udChr, tao[0]);
309 }
310 }
311
312 DISP & disp; // pointer to the display object
313 const barstyle* barStyle; // pointer to the bar style struct
314 MemoryType styleMemPlacement; // where the bitmaps defining the style (barstyle*) are stored, RAM or FLASH
315};
316
321{
322public:
330 BarPos(byte _len, byte _col, byte _row, byte _id = 0)
331 : par(ProgBarPar{ _col, _row, _len, _id }) { }
332
337 inline void setLength(int _len) // in characters
338 {
339 par.len = _len;
340 }
341
346 inline int getLength() const
347 {
348 return par.len;
349 }
350
358 inline void setPosition(byte _col, byte _row)
359 {
360 par.col = _col;
361 par.row = _row;
362 }
363
368 inline uint8_t col() const
369 {
370 return par.col;
371 }
372
377 inline uint8_t row() const
378 {
379 return par.row;
380 }
381
382protected:
384 {
385 byte col : 6; // column position of the progress bar
386 byte row : 2; // row position of the progress bar
387 byte len : 6; // progress bar length in characters
388 const byte id : 2; // progress bar number 0-3
389 } par;
390};
391
396template < class DISP >
397class ProgressBar : public BarPos
398{
399private:
400 ProgressBar(byte _len, byte _col, byte _row, byte _id = 0)
401 : BarPos(_len, _col, _row, _id) { }
402
403public:
412 ProgressBar(DISP& disp, byte _width, byte _col, byte _row, byte _pbn = 0)
413 : BarPos(_width, _col, _row, _pbn), barDisp(disp) { }
414
419 unsigned int size() const
420 {
421 const barstyle::bspar & barStylePar = barDisp.stylePar();
422 return par.len * (barStylePar.dir ? barstyle::CharPatRows : barstyle::CharPatCols) - barStylePar.startOffset - barStylePar.endOffset;
423 }
424
430 void showProgress(int val)
431 {
432 //const barstyle::bspar& barStylePar = barDisp.stylePar();
433 //showProg(val + barStylePar.startOffset, par.id);
434 showProg(val + barDisp.styleStartOffset(), par.id);
435 }
436
442 void showProgressPct(int val) { showProgress((val * size()) / 100); }
443
444protected:
450 void showProg(int val, byte n)
451 {
452 const barstyle::bspar& barStylePar = barDisp.stylePar();
453 const byte cellDim = barStylePar.dir ? barstyle::CharPatRows : barstyle::CharPatCols;
454 const byte rem = (cellDim - (val % cellDim));
455 uint8_t mask = barStylePar.dir ?
456 (barstyle::AllRows << rem) :
457 ((barstyle::AllCols << rem));
458 byte full = min(max(0, val / cellDim - 1), par.len - 2);
459 const byte partial = (val > cellDim && val < (par.len - 1) * cellDim);
460 byte blank = max(0, par.len - full - 2 - partial);
461
462 // determine and prepare the user defined characters
463 if (val < cellDim) // still filling the first block, create and use the middle char
464 {
465 barDisp.makeChar(DISP::ProgBarCharPartial + n, barDisp.getStyle().startMask, mask);
466 }
467 if (partial)
468 {
469 barDisp.makeChar(DISP::ProgBarCharPartial + n, barDisp.getStyle().middleMask, mask);
470 }
471 if (val > (par.len - 1) * cellDim) // last block partially (or fully) filled, create and use the middle char
472 {
473 if (val >= par.len * cellDim) // special case val == size() - last block completely full
474 {
475 mask = (barStylePar.dir ? barstyle::AllRows : barstyle::AllCols);
476 }
477 barDisp.makeChar(DISP::ProgBarCharPartial + n, barDisp.getStyle().endMask, mask);
478 }
479
480 barDisp.dsplay().setCursor(par.col, par.row);
481 barDisp.dsplay().write((val < cellDim) ? (DISP::ProgBarCharPartial + n) : DISP::ProgBarCharBegin);
482
483 // show on the display
484 byte crow = par.row;
485 while (full--)
486 {
487 if (barStylePar.dir)
488 {
489 barDisp.dsplay().setCursor(par.col, --crow);
490 }
491 barDisp.dsplay().write(DISP::ProgBarCharFull);
492 }
493 if (partial)
494 {
495 if (barStylePar.dir)
496 {
497 barDisp.dsplay().setCursor(par.col, --crow);
498 }
499 barDisp.dsplay().write(DISP::ProgBarCharPartial + n);
500 }
501 while (blank--)
502 {
503 if (barStylePar.dir)
504 {
505 barDisp.dsplay().setCursor(par.col, --crow);
506 }
507 barDisp.dsplay().write(DISP::ProgBarCharBlank);
508 }
509 if (barStylePar.dir)
510 {
511 barDisp.dsplay().setCursor(par.col, --crow);
512 }
513 barDisp.dsplay().write((val > (par.len - 1) * cellDim) ? (DISP::ProgBarCharPartial + n) : DISP::ProgBarCharEnd);
514 }
515
516 //data
517 const DISP& barDisp; // reference to the display wrapper object
518};
519
522
523
524#endif // SMOOTH_PROGRESS_H
Definition: SmoothProgress.h:88
void makeChar(byte udChr, const uint8_t xMask[2][barstyle::CharPatRows], uint8_t mask) const
Creates a user defined character in the CGRAM of the LCD display
Definition: SmoothProgress.h:222
barstyle::bspar stylePar() const
Access to the parameters of the style
Definition: SmoothProgress.h:161
int styleStartOffset() const
Returns the start offset (in pixels) of the progress bars
Definition: SmoothProgress.h:178
DISP & dsplay() const
Access to the display object for low level functions of the LCD
Definition: SmoothProgress.h:121
void setStyle(const barstyle &bs)
Sets the style of the progress bars on the display
Definition: SmoothProgress.h:139
void makeCharMask(uint8_t out[barstyle::CharPatRows], const uint8_t xMask[2][barstyle::CharPatRows], uint8_t mask) const
Prepares the bitmap for making the user defined character
Definition: SmoothProgress.h:245
void begin() const
Initializes the BarDisplay object with the progress bar style
Definition: SmoothProgress.h:204
BarDisplay(DISP &displ, const inPROGMEM &wraped)
BarDisplay constructor creates the object that bounds the LCD display to the bar style defined in the...
Definition: SmoothProgress.h:109
void createChar(byte udChr, const uint8_t bitMask[barstyle::CharPatRows]) const
Creates a user defined character in the CGRAM of the LCD display using the bitmap stored in bitMask a...
Definition: SmoothProgress.h:269
const barstyle & getStyle() const
Access to the bar style structure
Definition: SmoothProgress.h:130
void createChar(byte udChr, const uint8_t xMask[2][barstyle::CharPatRows]) const
Creates a user defined character in the CGRAM of the LCD display using the bitmaps stored in xMask ar...
Definition: SmoothProgress.h:289
uint8_t styleOrientation() const
Returns the orientation of the progress bar
Definition: SmoothProgress.h:196
void setStyle(const inPROGMEM &wraped)
Sets the style of the progress bars on the display
Definition: SmoothProgress.h:150
BarDisplay(DISP &displ, const barstyle &bs)
BarDisplay constructor creates the object that bounds the LCD display to the bar style defined in the...
Definition: SmoothProgress.h:100
int styleEndOffset() const
Returns the end offset (in pixels) of the progress bars
Definition: SmoothProgress.h:187
Class defining the position and the size of the progress bar on the display
Definition: SmoothProgress.h:321
uint8_t row() const
Returns the position of the progress bar on the display
Definition: SmoothProgress.h:377
BarPos(byte _len, byte _col, byte _row, byte _id=0)
Constructs the BarPos object representing the position and the size of the progress bar on the displa...
Definition: SmoothProgress.h:330
void setLength(int _len)
Sets the length of the progress bar
Definition: SmoothProgress.h:337
int getLength() const
Gets the length of the progress bar (in characters)
Definition: SmoothProgress.h:346
void setPosition(byte _col, byte _row)
Sets the position of the progress bar on the display the row and the column represents the position o...
Definition: SmoothProgress.h:358
uint8_t col() const
Returns the position of the progress bar on the display
Definition: SmoothProgress.h:368
Class representing a smooth progress bar
Definition: SmoothProgress.h:398
void showProg(int val, byte n)
Draws the horizontal progress bar on the LCD display
Definition: SmoothProgress.h:450
void showProgressPct(int val)
Draws the progress bar on the LCD display
Definition: SmoothProgress.h:442
ProgressBar(DISP &disp, byte _width, byte _col, byte _row, byte _pbn=0)
Creates horizontal ProgressBar object
Definition: SmoothProgress.h:412
unsigned int size() const
Returns the size of the progress bar in pixels (height for vertical, width for horizontal)
Definition: SmoothProgress.h:419
void showProgress(int val)
Draws the progress bar on the LCD display
Definition: SmoothProgress.h:430
Helper class to wrap the barstyle structure when passing the structure "object" to a function so that...
Definition: SmoothProgress.h:73
inPROGMEM(const barstyle &bs)
Wrapper to be used when passing the barstyle structure (as const reference) to the functions / constr...
Definition: SmoothProgress.h:80
Definition: SmoothProgress.h:384
Definition: barstyle.h:49
Structure holding the bit-masks and other data used for drawing the edges of the progress bar that de...
Definition: barstyle.h:40