17 Commits

Author SHA1 Message Date
JP Liew
a4a45b7e6d Merge branch 'master' of https://github.com/geekammo/MicroView-Arduino-Library 2015-03-29 09:31:39 +11:00
JP Liew
601881997d Merge pull request #28 from MLXXXp/widget_background_demo
Example sketch to demonstrate use of widget setValue() optional second argument
2015-03-29 09:29:10 +11:00
JP Liew
2a7b01cfbc updated History 2015-03-29 09:28:33 +11:00
JP Liew
b35e3f2e01 Merge pull request #27 from MLXXXp/widget_setvalue_nodraw
Add optional second argument to widget setValue which can supress display buffer update
2015-03-29 09:26:15 +11:00
Scott Allen
66405a0972 Added example sketch to demonstrate use of widget setValue() function's
optional second argument.
2015-03-27 17:54:16 -04:00
Scott Allen
82f3863036 Overloaded the widget setValue() function to add a boolean variable which
controls whether the display buffer is updated.

Also changed bool declarations to boolean, for consistency.
2015-03-25 17:51:42 -04:00
JP
301bd6acf5 added history to newly commited code 2014-10-04 14:00:42 +10:00
jpliew
80a0c70c34 Merge pull request #22 from MLXXXp/widget_protected_variables
Changed private variables in the MicroViewWidget base class to protected, for direct use by child classes
2014-10-04 13:52:36 +10:00
jpliew
c75d14abff Merge pull request #21 from ben-zen/circle_drawing
Improved circleFill() drawing
2014-10-04 13:52:12 +10:00
jpliew
1aa32fb0c2 Merge pull request #20 from MLXXXp/replace_sprintf
Replaced sprintf calls with dedicated code
2014-10-04 13:51:22 +10:00
Scott Allen
5e24583c31 Refactored widget code to eliminate needFirstDraw variable 2014-09-25 16:43:43 -04:00
Scott Allen
b05451f4c6 Use constructor initialisation lists for widget variables 2014-09-25 16:02:47 -04:00
Scott Allen
0d8545d6f8 Changed widget base class variables from private to protected
Base variables are now accessed directly by child widgets instead of
using methods
2014-09-25 12:48:21 -04:00
ben-zen
8ae691c4c2 Fixed whitespace before pull request. 2014-09-23 21:39:06 -07:00
ben-zen
12a9c5c2ac Merged up-to-date geekammo repo with my circleFill() changes. 2014-09-23 21:22:34 -07:00
ben-zen
68f0c20fd5 Replaced body of previous circleFill() method in the MicroView class, in preparation for a pull request. 2014-09-23 21:14:20 -07:00
Scott Allen
38be4163c0 Replaced sprintf calls with dedicated code
Using sprintf generates a large amount of code. By replacing the
sprintf calls with dedicated code, program size is reduced when
widgets are used.

Also:
- Added a getValLen method for widgets which returns the print
length for the current value, similar to the existing getMaxValLen.
- The value for widgets is now initialised to the minimum value,
instead of 0, because 0 could be outside the specified range.
- Added getValLen and getMaxValLen keywords.
- The MicroViewWidgetDemo example sketch was modified to use
the new getValLen method, plus a few other small changes.
2014-09-22 19:16:34 -04:00
6 changed files with 330 additions and 174 deletions

View File

@@ -604,47 +604,62 @@ void MicroView::circleFill(uint8_t x0, uint8_t y0, uint8_t radius) {
/** \brief Draw filled circle with color and mode.
Draw filled circle with radius using color and mode at x,y of the screen buffer.
Draw filled circle with radius using color and mode at x,y of the screen
buffer. Uses the Bresenham circle algorithm with a few modifications to
paint the circle without overlapping draw operations.
*/
void MicroView::circleFill(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t color, uint8_t mode) {
// Don't bother trying to draw something totally offscreen
if (x0 - radius >= LCDWIDTH || y0 - radius >= LCDHEIGHT) {
return;
}
// High-level algorithm overview:
// Scan horizontally from left to right, then top to bottom, checking if each pixel
// is within the circle. We use uint16_t's because even the small screen squares beyond 8 bits.
uint16_t radiusSq = radius * radius;
// Optimization: define the start and end onscreen
uint16_t xStart = max(0, x0-radius);
uint16_t xEnd = min(LCDWIDTH-1, x0+radius);
uint16_t yStart = max(0, y0-radius);
uint16_t yEnd = min(LCDHEIGHT-1, y0+radius);
// scan horizontally...
for (uint16_t x = xStart; x <= xEnd; ++x) {
// Optimization: Record where if we have intersected the circle on this vertical
// scan. Once we have intersected, then don't intersect anymore, don't bother
// drawing; we've exited the circle.
bool intersected = false;
// Optimization: relative x squared only changes with the outer loop/the horizontal scan.
uint16_t rx2 = (x-x0) * (x-x0);
// Scan vertically...
for (uint16_t y = yStart; y <= yEnd; ++y) {
uint16_t ry2 = (y-y0) * (y-y0);
if (rx2 + ry2 <= radiusSq) {
pixel(x, y, color, mode);
intersected = true;
void MicroView::circleFill(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t
color, uint8_t mode) {
int8_t x = radius;
int8_t y = 0;
int8_t radiusError = 1 - x;
int8_t y_last = y0 + x;
int8_t y_low;
int8_t x_alt;
int8_t x_alt_max;
while (x >= y) {
pixel(x + x0, y + y0, color, mode);
x_alt = (x0 - x);
x_alt_max = x0 + x;
while (x_alt < x_alt_max) {
pixel(x_alt, y + y0, color, mode);
x_alt++;
}
if (y != x) {
pixel(y + x0, x + y0, color, mode);
pixel(y + x0, y0 - x, color, mode);
}
if (y != 0) {
pixel(x + x0, y0 - y, color, mode);
x_alt = (x0 - x);
x_alt_max = x0 + x;
while (x_alt < x_alt_max) {
pixel(x_alt, y0 - y, color, mode);
x_alt++;
}
else if (intersected) {
// We've left the circle. Move on to the next horizontal scan line.
break;
if (y != x) {
pixel(x0 - y, x + y0, color, mode);
pixel(x0 - y, y0 - x, color, mode);
if (y_last > y0 + x) {
x_alt = x0 - y + 1;
x_alt_max = x0 + y;
y_last = y0 + x;
y_low = y0 - x;
while (x_alt < x_alt_max) {
pixel(x_alt, y_last, color, mode);
pixel(x_alt, y_low, color, mode);
x_alt++;
}
}
}
}
y++;
if (radiusError<0) {
radiusError += 2 * y + 1;
} else {
x--;
radiusError += 2 * (y - x + 1);
}
}
}
@@ -1361,25 +1376,28 @@ int MicroView::readSerial(void)
The MicroViewWidget class is the parent class for child widget like MicroViewSlider and MicroViewGauge.
*/
MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max) {
setX(newx);
setY(newy);
value=0;
setMinValue(min);
setMaxValue(max);
MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
posX(newx),
posY(newy),
minValue(min),
maxValue(max),
value(min)
{
valLen=getInt16PrintLen(value);
setMaxValLen();
}
/** \brief Get widget x position. */
uint8_t MicroViewWidget::getX() { return x; }
uint8_t MicroViewWidget::getX() { return posX; }
/** \brief Get widget y position. */
uint8_t MicroViewWidget::getY() { return y; }
uint8_t MicroViewWidget::getY() { return posY; }
/** \brief Set widget x position. */
void MicroViewWidget::setX(uint8_t newx) { x = newx; }
void MicroViewWidget::setX(uint8_t newx) { posX = newx; }
/** \brief Set widget y position. */
void MicroViewWidget::setY(uint8_t newy) { y = newy; }
void MicroViewWidget::setY(uint8_t newy) { posY = newy; }
/** \brief Get minimum value.
@@ -1403,44 +1421,61 @@ int16_t MicroViewWidget::getValue() { return value; }
The minimum value of the widget is set to the variable passed in.
*/
void MicroViewWidget::setMinValue(int16_t min) { minValue=min; }
void MicroViewWidget::setMinValue(int16_t min) {
minValue = min;
setMaxValLen();
}
/** \brief Set maximum value.
The maximum value of the widget is set to the variable passed in.
*/
void MicroViewWidget::setMaxValue(int16_t max) { maxValue=max; }
/** \brief Get the maximum possible print lenth of the value
Return the maximum number of characters that would be printed using printf("%d", value) for the current value range.
*/
uint8_t MicroViewWidget::getMaxValLen() {
uint8_t minLen, maxLen;
maxLen = getInt16PrintLen(maxValue);
minLen = getInt16PrintLen(minValue);
return maxLen >= minLen ? maxLen : minLen;
void MicroViewWidget::setMaxValue(int16_t max) {
maxValue = max;
setMaxValLen();
}
/** \brief Set current value.
/** \brief Get the maximum possible print length of the value
The current value of the widget is set to the variable passed in.
Return the maximum number of characters that would be printed using uView.print(value) for the current value range.
*/
void MicroViewWidget::setValue(int16_t val) {
if ((val<=maxValue) && (val>=minValue)){
value=val;
this->draw();
uint8_t MicroViewWidget::getMaxValLen() { return maxValLen; }
/** \brief Set current value and update widget.
The current value of the widget is set to the variable passed in and the widget is drawn with the new value.
*/
void MicroViewWidget::setValue(int16_t val) {
setValue(val, true);
}
/** \brief Set current value with optional update.
The current value of the widget is set to the variable passed in. The widget is drawn with the new value if the doDraw argument is true.
*/
void MicroViewWidget::setValue(int16_t val, boolean doDraw) {
if ((val<=maxValue) && (val>=minValue)) {
value = val;
valLen = getInt16PrintLen(val);
if (doDraw) {
this->draw();
}
}
}
/** \brief Get the print length of the value.
Return the number of characters that would be printed using uView.print(value) for the current value.
*/
uint8_t MicroViewWidget::getValLen() { return valLen; }
/** \brief MicroView Widget reDraw routine.
Redraws the widget.
*/
void MicroViewWidget::reDraw() {
needFirstDraw=true;
this->drawFace();
this->drawPointer(); // initial pointer (will be erased)
this->draw();
}
@@ -1449,12 +1484,22 @@ void MicroViewWidget::reDraw() {
The value is right justified with leading spaces, within a field the length of the maximum posible for the widget's value range.
*/
void MicroViewWidget::drawNumValue(int16_t value) {
char strBuffer[7];
char formatStr[] = "%1d";
formatStr[1] = '0' + getMaxValLen(); // Set the field width for the value range
sprintf(strBuffer, formatStr, value);
uView.print(strBuffer);
for (uint8_t i = maxValLen - getInt16PrintLen(value); i > 0; i--) {
uView.print(" ");
}
uView.print(value);
}
/* Set the maximum number of characters that would be printed
using uView.print(value) for the current value range.
*/
void MicroViewWidget::setMaxValLen() {
uint8_t minLen, maxLen;
maxLen = getInt16PrintLen(maxValue);
minLen = getInt16PrintLen(minValue);
maxValLen = maxLen >= minLen ? maxLen : minLen;
}
// -------------------------------------------------------------------------------------
@@ -1469,13 +1514,15 @@ void MicroViewWidget::drawNumValue(int16_t value) {
Initialise the MicroViewSlider widget with default style.
*/
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max):MicroViewWidget(newx, newy, min, max) {
style=0;
totalTicks=30;
noValDraw=false;
prevValue=getMinValue();
needFirstDraw=true;
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
MicroViewWidget(newx, newy, min, max),
style(0),
totalTicks(30),
noValDraw(false),
prevValue(value)
{
drawFace();
drawPointer(); // Initial pointer (will be erased)
draw();
}
@@ -1484,7 +1531,10 @@ MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_
Initialise the MicroViewSlider widget with style WIDGETSTYLE0 or WIDGETSTYLE1 or WIDGETSTYLE2 (like 0, but vertical) or WIDGETSTYLE3 (like 1, but vertical).
Add WIDGETNOVALUE to the style to suppress displaying the numeric value. E.g. WIDGETSTYLE0 + WIDGETNOVALUE
*/
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty):MicroViewWidget(newx, newy, min, max) {
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty):
MicroViewWidget(newx, newy, min, max),
prevValue(value)
{
noValDraw = sty & WIDGETNOVALUE; // set "no value draw" flag as specified
switch(sty & ~WIDGETNOVALUE) {
@@ -1506,9 +1556,8 @@ MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_
break;
}
prevValue=getMinValue();
needFirstDraw=true;
drawFace();
drawPointer(); // Initial pointer (will be erased)
draw();
}
@@ -1517,32 +1566,30 @@ MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_
Draw image/diagram representing the widget's face.
*/
void MicroViewSlider::drawFace() {
uint8_t offsetX, offsetY, endOffset;
offsetX=getX();
offsetY=getY();
uint8_t endOffset;
//Horizontal styles, style 0 or 1
if (style==0 || style==1) {
endOffset = offsetX + totalTicks + 2;
endOffset = posX + totalTicks + 2;
// Draw minor ticks
for (uint8_t i=offsetX+1; i<endOffset; i+=2) {
uView.lineV(i, offsetY+5, 3);
for (uint8_t i=posX+1; i<endOffset; i+=2) {
uView.lineV(i, posY+5, 3);
}
// Draw extensions for major ticks
for (uint8_t i=offsetX+1; i<endOffset; i+=10) {
uView.lineV(i, offsetY+3, 2);
for (uint8_t i=posX+1; i<endOffset; i+=10) {
uView.lineV(i, posY+3, 2);
}
}
//Vertical styles, style 2 or 3
else {
endOffset = offsetY + totalTicks + 2;
endOffset = posY + totalTicks + 2;
// Draw minor ticks
for (uint8_t i=offsetY+1; i<=endOffset; i+=2) {
uView.lineH(offsetX, i, 3);
for (uint8_t i=posY+1; i<=endOffset; i+=2) {
uView.lineH(posX, i, 3);
}
// Draw extensions for major ticks
for (uint8_t i=offsetY+1; i<=endOffset; i+=10) {
uView.lineH(offsetX+3, i, 2);
for (uint8_t i=posY+1; i<=endOffset; i+=10) {
uView.lineH(posX+3, i, 2);
}
}
}
@@ -1552,35 +1599,24 @@ void MicroViewSlider::drawFace() {
Convert the current value of the widget and draw the ticker representing the value.
*/
void MicroViewSlider::draw() {
// Draw the initial pointer or erase the previous pointer
drawPointer();
if (needFirstDraw) {
needFirstDraw=false;
}
else {
prevValue=getValue();
// Draw current pointer
drawPointer();
}
drawPointer(); // Erase the previous pointer
prevValue=value;
drawPointer(); // Draw the current pointer
// Draw numeric value if required
if (!noValDraw) {
uint8_t offsetX = getX();
uint8_t offsetY = getY();
switch(style) {
case 0:
uView.setCursor(offsetX+totalTicks+4, offsetY+1);
uView.setCursor(posX+totalTicks+4, posY+1);
break;
case 1:
uView.setCursor(offsetX, offsetY+10);
uView.setCursor(posX, posY+10);
break;
case 2:
uView.setCursor(offsetX+1, offsetY+totalTicks+4);
uView.setCursor(posX+1, posY+totalTicks+4);
break;
default:
uView.setCursor(offsetX+9, offsetY);
uView.setCursor(posX+9, posY);
break;
}
@@ -1591,18 +1627,16 @@ void MicroViewSlider::draw() {
// Use XOR mode to erase or draw the pointer for prevValue
void MicroViewSlider::drawPointer() {
uint8_t tickPosition;
uint8_t offsetX = getX();
uint8_t offsetY = getY();
if (style==0 || style==1) { // Horizontal
tickPosition = ((float)(uint16_t)(prevValue-getMinValue())/(float)(uint16_t)(getMaxValue()-getMinValue()))*totalTicks;
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
tickPosition = ((float)(uint16_t)(prevValue-minValue)/(float)(uint16_t)(maxValue-minValue))*totalTicks;
uView.lineH(posX+tickPosition, posY, 3, WHITE, XOR);
uView.pixel(posX+1+tickPosition, posY+1, WHITE, XOR);
}
else { // Vertical
tickPosition = ((float)(uint16_t)(getMaxValue()-prevValue)/(float)(uint16_t)(getMaxValue()-getMinValue()))*totalTicks;
uView.lineV(offsetX+7, offsetY+tickPosition, 3, WHITE, XOR);
uView.pixel(offsetX+6, offsetY+1+tickPosition, WHITE, XOR);
tickPosition = ((float)(uint16_t)(maxValue-prevValue)/(float)(uint16_t)(maxValue-minValue))*totalTicks;
uView.lineV(posX+7, posY+tickPosition, 3, WHITE, XOR);
uView.pixel(posX+6, posY+1+tickPosition, WHITE, XOR);
}
}
@@ -1618,13 +1652,15 @@ void MicroViewSlider::drawPointer() {
Initialise the MicroViewGauge widget with default style.
*/
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max):MicroViewWidget(newx, newy, min, max) {
style=0;
radius=15;
noValDraw=false;
prevValue=getMinValue();
needFirstDraw=true;
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
MicroViewWidget(newx, newy, min, max),
style(0),
radius(15),
noValDraw(false),
prevValue(value)
{
drawFace();
drawPointer(); // Initial pointer (will be erased)
draw();
}
@@ -1633,7 +1669,10 @@ MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t
Initialise the MicroViewGauge widget with style WIDGETSTYLE0 or WIDGETSTYLE1.
Add WIDGETNOVALUE to the style to suppress displaying the numeric value. E.g. WIDGETSTYLE0 + WIDGETNOVALUE
*/
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty):MicroViewWidget(newx, newy, min, max) {
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty):
MicroViewWidget(newx, newy, min, max),
prevValue(value)
{
noValDraw = sty & WIDGETNOVALUE; // set "no value draw" flag as specified
if ((sty & ~WIDGETNOVALUE) == WIDGETSTYLE0) {
@@ -1644,9 +1683,9 @@ MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t
style=1;
radius=23;
}
prevValue=getMinValue();
needFirstDraw=true;
drawFace();
drawPointer(); // Initial pointer (will be erased)
draw();
}
@@ -1655,12 +1694,9 @@ MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t
Draw image/diagram representing the widget's face.
*/
void MicroViewGauge::drawFace() {
uint8_t offsetX, offsetY;
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
offsetX=getX();
offsetY=getY();
uView.circle(offsetX,offsetY,radius);
uView.circle(posX, posY, radius);
for (int i=150;i<=390;i+=30) { // Major tick from 150 degree to 390 degree
degreeSec=i*(PI/180);
@@ -1668,7 +1704,7 @@ void MicroViewGauge::drawFace() {
fromSecY = sin(degreeSec) * (radius / 1.5);
toSecX = cos(degreeSec) * radius;
toSecY = sin(degreeSec) * radius;
uView.line(1+offsetX+fromSecX,1+offsetY+fromSecY,1+offsetX+toSecX,1+offsetY+toSecY);
uView.line(1+posX+fromSecX, 1+posY+fromSecY, 1+posX+toSecX, 1+posY+toSecY);
}
if (radius>15) {
@@ -1678,7 +1714,7 @@ void MicroViewGauge::drawFace() {
fromSecY = sin(degreeSec) * (radius / 1.3);
toSecX = cos(degreeSec) * radius;
toSecY = sin(degreeSec) * radius;
uView.line(1+offsetX+fromSecX,1+offsetY+fromSecY,1+offsetX+toSecX,1+offsetY+toSecY);
uView.line(1+posX+fromSecX, 1+posY+fromSecY, 1+posX+toSecX, 1+posY+toSecY);
}
}
}
@@ -1688,27 +1724,18 @@ void MicroViewGauge::drawFace() {
Convert the current value of the widget and draw the ticker representing the value.
*/
void MicroViewGauge::draw() {
// Draw the initial pointer or erase the previous pointer
drawPointer();
if (needFirstDraw) {
needFirstDraw=false;
}
else {
prevValue=getValue();
// Draw current pointer
drawPointer();
}
drawPointer(); // Erase the previous pointer
prevValue=value;
drawPointer(); // Draw the current pointer
// Draw numeric value if required
if (!noValDraw) {
uint8_t offsetY = getY();
uint8_t offsetX = getX() - (getMaxValLen() * 3 - 1); // Offset left of centre to print the value
uint8_t offsetX = posX - (maxValLen * 3 - 1); // Offset left of centre to print the value
if (style > 0)
uView.setCursor(offsetX, offsetY+10);
uView.setCursor(offsetX, posY+10);
else
uView.setCursor(offsetX, offsetY+11);
uView.setCursor(offsetX, posY+11);
drawNumValue(prevValue);
}
@@ -1716,19 +1743,15 @@ void MicroViewGauge::draw() {
// Use XOR mode to erase or draw the pointer for prevValue
void MicroViewGauge::drawPointer() {
uint8_t offsetX, offsetY;
float degreeSec, toSecX, toSecY;
offsetX = getX();
offsetY = getY();
// total 240 degree in the widget with 150 degree starting point
degreeSec = (((float)(uint16_t)(prevValue-getMinValue()) / (float)(uint16_t)(getMaxValue()-getMinValue())
degreeSec = (((float)(uint16_t)(prevValue-minValue) / (float)(uint16_t)(maxValue-minValue)
* 240) + 150) * (PI / 180);
toSecX = cos(degreeSec) * (radius / 1.2);
toSecY = sin(degreeSec) * (radius / 1.2);
uView.line(offsetX,offsetY,1+offsetX+toSecX,1+offsetY+toSecY, WHITE,XOR);
uView.line(posX, posY, 1+posX+toSecX, 1+posY+toSecY, WHITE, XOR);
}
// -------------------------------------------------------------------------------------
@@ -1844,11 +1867,34 @@ MicroView uView;
/** \brief Get the number of characters for a 16 bit signed value.
Return the number of characters that would be printed using printf("%d", x) for x being a signed 16 bit integer.
Return the number of characters that would be printed using uView.print(x) for x being a signed 16 bit integer.
*/
uint8_t getInt16PrintLen(int16_t val) {
char sbuf[7];
int16_t i;
uint8_t count;
return sprintf(sbuf, "%d", val);
if (val >= 10000) {
return 5;
}
if (val <= -10000) {
return 6;
}
if (val >= 0) {
count = 1;
}
else {
count = 2;
val = abs(val);
}
i = 10;
while (val >= i) {
count++;
i *= 10;
}
return count;
}

View File

@@ -230,33 +230,39 @@ private:
class MicroViewWidget {
public:
bool needFirstDraw;
MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max);
uint8_t getX();
uint8_t getY();
void setX(uint8_t newx);
void setY(uint8_t newy);
int16_t getMinValue();
int16_t getMaxValue();
int16_t getValue();
void setMinValue(int16_t min);
void setMaxValue(int16_t max);
void setValue(int16_t val);
void setValue(int16_t val, boolean doDraw);
uint8_t getValLen();
uint8_t getMaxValLen();
/** \brief Draw widget value overridden by child class. */
virtual void draw(){};
/** \brief Draw widget face overridden by child class. */
virtual void draw(){};
/** \brief Draw widget face overridden by child class. */
virtual void drawFace(){};
void reDraw();
void drawNumValue(int16_t value);
virtual ~MicroViewWidget(){};
private:
uint8_t x;
uint8_t y;
int16_t maxValue;
protected:
uint8_t posX;
uint8_t posY;
int16_t minValue;
int16_t maxValue;
int16_t value;
uint8_t valLen;
uint8_t maxValLen;
private:
/** \brief Draw or erase the widget pointer. Overridden by child class. */
virtual void drawPointer(){};
void setMaxValLen();
};
class MicroViewSlider: public MicroViewWidget{
@@ -267,8 +273,8 @@ public:
void drawFace();
private:
void drawPointer();
uint8_t totalTicks, style;
bool noValDraw;
uint8_t style, totalTicks;
boolean noValDraw;
int16_t prevValue;
};
@@ -280,8 +286,8 @@ public:
void drawFace();
private:
void drawPointer();
uint8_t radius, style;
bool noValDraw;
uint8_t style, radius;
boolean noValDraw;
int16_t prevValue;
};

View File

@@ -92,6 +92,17 @@ void loop() {
</code></pre>
## History
**v1.23b: 29th March 2015 by Scott Allen
* added overloaded setValue() function to add a boolean argument doDraw which controls whether the display buffer is updated.
**v1.22b: 4th October 2014 by Scott Allen and Ben Lewis**
* replaced circleFill() with a faster algorithm, better looking circle - Ben Lewis
* replaced sprintf with dedicated code, reduced program size - Scott Allen
* added getValLen method for widgets to return length of current value - Scott Allen
* initialised widget with minimum value instead of 0 - Scott Allen
* added getValLen and getMaxValLen keywords
* modified MicroViewDemo example to use getValLen method - Scott Allen
**v1.21b: 22nd September 2014 by Esmit Pérez and Scott Allen**
* re-factored code if/else with switch - Esmit Pérez
* simplified draw() to remove redundant code - Esmit Pérez

View File

@@ -0,0 +1,90 @@
/*
MicroView Arduino Library
Copyright (C) 2015 GeekAmmo
This program 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.
This program 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 <http://www.gnu.org/licenses/>.
*/
/*
An example of using the optional second argument of the widget
setVal() function to update a widget without drawing the changes
to the screen buffer.
This, along with the widget reDraw() function, allows widgets to be
maintained in the "background" while other things are being displayed.
In this example,
a guage and a slider are both continually updated with the same
incrementing value. The widgets are alternately switched between the
"background" and being displayed, at random intervals.
*/
#include <MicroView.h>
const int highVal = 100; // high value for widget range
int wValue = 0; // value for widgets
MicroViewWidget *guage1, *slider1;
boolean guage1On, slider1On; // true if widget is being displayed
void setup() {
uView.begin();
guage1 = new MicroViewGauge(32, 20, 0, highVal);
guage1On = false; // begin with guage1 off screen
uView.clear(PAGE);
slider1 = new MicroViewSlider(8, 16, 0, highVal);
slider1On = true; // begin with slider1 on screen
// Init the random number generator using an
// unconnected analog pin.
randomSeed(analogRead(A0));
}
void loop() {
// Display a widget for a random number of value increments
for (int c = random(5, 16); c > 0; c--) {
uView.display();
delay(500);
wValue++;
if (wValue > highVal) {
wValue = 0;
}
// If the second setValue() argument is false, then
// the display buffer is not updated.
//
// In a practical application, the widgets would be set with
// the values that are being monitored.
guage1->setValue(wValue, guage1On);
slider1->setValue(wValue, slider1On);
}
// Switch which widget is being displayed
uView.clear(PAGE);
guage1On = !guage1On;
slider1On = !slider1On;
if (guage1On) {
guage1->reDraw();
}
if (slider1On) {
slider1->reDraw();
}
}

View File

@@ -208,7 +208,7 @@ void loop() {
/* ==================== Demo 13 ====================
Gauge style 1, with no numeric value.
Value manually displayed beneath, as a letter.
Value manually displayed as a letter.
Range 1 to 26 (A to Z).
================================================ */
demoNumber(13);
@@ -246,15 +246,15 @@ void customSlider0(int16_t val) {
// Update function for Demo 9
void customSlider1(int16_t val) {
widget1->setValue(val);
uint8_t offsetY = widget1->getY() - 10;
uint8_t offsetX = widget1->getX() + 14;
uView.setCursor(offsetX, offsetY);
uView.print(" "); // erase the previous value in case it's longer
// calculate the offset to centre the value
offsetX += ((widget1->getMaxValLen() - getInt16PrintLen(val)) * 3);
offsetX += ((widget1->getMaxValLen() - widget1->getValLen()) * 3);
uView.setCursor(offsetX, offsetY);
uView.print(val);
widget1->setValue(val);
}
// Update function for Demo 10
@@ -324,6 +324,7 @@ void spin(int16_t lowVal, int16_t highVal, int16_t stepSize,
unsigned long stepDelay, void (*drawFunction)(int16_t val)) {
drawFunction(lowVal);
uView.display();
prevVal = lowVal;
delay(1500);
for (int16_t i = lowVal + stepSize; i <= highVal; i += stepSize) {

View File

@@ -63,6 +63,8 @@ getMaxValue KEYWORD2
setMaxValue KEYWORD2
setMinValue KEYWORD2
setValue KEYWORD2
getValLen KEYWORD2
getMaxValLen KEYWORD2
draw KEYWORD2
reDraw KEYWORD2
drawFace KEYWORD2