mirror of
https://github.com/geekammo/MicroView-Arduino-Library.git
synced 2026-02-27 06:51:24 +01:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfc8b5cb68 | ||
|
|
a4a45b7e6d | ||
|
|
601881997d | ||
|
|
2a7b01cfbc | ||
|
|
b35e3f2e01 | ||
|
|
66405a0972 | ||
|
|
82f3863036 | ||
|
|
301bd6acf5 | ||
|
|
80a0c70c34 | ||
|
|
c75d14abff | ||
|
|
1aa32fb0c2 | ||
|
|
5e24583c31 | ||
|
|
b05451f4c6 | ||
|
|
0d8545d6f8 | ||
|
|
8ae691c4c2 | ||
|
|
12a9c5c2ac | ||
|
|
68f0c20fd5 | ||
|
|
38be4163c0 |
364
MicroView.cpp
364
MicroView.cpp
@@ -604,47 +604,62 @@ void MicroView::circleFill(uint8_t x0, uint8_t y0, uint8_t radius) {
|
|||||||
|
|
||||||
/** \brief Draw filled circle with color and mode.
|
/** \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) {
|
void MicroView::circleFill(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t
|
||||||
// Don't bother trying to draw something totally offscreen
|
color, uint8_t mode) {
|
||||||
if (x0 - radius >= LCDWIDTH || y0 - radius >= LCDHEIGHT) {
|
int8_t x = radius;
|
||||||
return;
|
int8_t y = 0;
|
||||||
}
|
int8_t radiusError = 1 - x;
|
||||||
|
int8_t y_last = y0 + x;
|
||||||
// High-level algorithm overview:
|
int8_t y_low;
|
||||||
// Scan horizontally from left to right, then top to bottom, checking if each pixel
|
int8_t x_alt;
|
||||||
// is within the circle. We use uint16_t's because even the small screen squares beyond 8 bits.
|
int8_t x_alt_max;
|
||||||
uint16_t radiusSq = radius * radius;
|
while (x >= y) {
|
||||||
|
pixel(x + x0, y + y0, color, mode);
|
||||||
// Optimization: define the start and end onscreen
|
x_alt = (x0 - x);
|
||||||
uint16_t xStart = max(0, x0-radius);
|
x_alt_max = x0 + x;
|
||||||
uint16_t xEnd = min(LCDWIDTH-1, x0+radius);
|
while (x_alt < x_alt_max) {
|
||||||
uint16_t yStart = max(0, y0-radius);
|
pixel(x_alt, y + y0, color, mode);
|
||||||
uint16_t yEnd = min(LCDHEIGHT-1, y0+radius);
|
x_alt++;
|
||||||
|
}
|
||||||
// scan horizontally...
|
if (y != x) {
|
||||||
for (uint16_t x = xStart; x <= xEnd; ++x) {
|
pixel(y + x0, x + y0, color, mode);
|
||||||
// Optimization: Record where if we have intersected the circle on this vertical
|
pixel(y + x0, y0 - x, color, mode);
|
||||||
// scan. Once we have intersected, then don't intersect anymore, don't bother
|
}
|
||||||
// drawing; we've exited the circle.
|
if (y != 0) {
|
||||||
bool intersected = false;
|
pixel(x + x0, y0 - y, color, mode);
|
||||||
|
x_alt = (x0 - x);
|
||||||
// Optimization: relative x squared only changes with the outer loop/the horizontal scan.
|
x_alt_max = x0 + x;
|
||||||
uint16_t rx2 = (x-x0) * (x-x0);
|
while (x_alt < x_alt_max) {
|
||||||
|
pixel(x_alt, y0 - y, color, mode);
|
||||||
// Scan vertically...
|
x_alt++;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else if (intersected) {
|
if (y != x) {
|
||||||
// We've left the circle. Move on to the next horizontal scan line.
|
pixel(x0 - y, x + y0, color, mode);
|
||||||
break;
|
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.
|
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) {
|
MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
|
||||||
setX(newx);
|
posX(newx),
|
||||||
setY(newy);
|
posY(newy),
|
||||||
value=0;
|
minValue(min),
|
||||||
setMinValue(min);
|
maxValue(max),
|
||||||
setMaxValue(max);
|
value(min)
|
||||||
|
{
|
||||||
|
valLen=getInt16PrintLen(value);
|
||||||
|
setMaxValLen();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Get widget x position. */
|
/** \brief Get widget x position. */
|
||||||
uint8_t MicroViewWidget::getX() { return x; }
|
uint8_t MicroViewWidget::getX() { return posX; }
|
||||||
|
|
||||||
/** \brief Get widget y position. */
|
/** \brief Get widget y position. */
|
||||||
uint8_t MicroViewWidget::getY() { return y; }
|
uint8_t MicroViewWidget::getY() { return posY; }
|
||||||
|
|
||||||
/** \brief Set widget x position. */
|
/** \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. */
|
/** \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.
|
/** \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.
|
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.
|
/** \brief Set maximum value.
|
||||||
|
|
||||||
The maximum value of the widget is set to the variable passed in.
|
The maximum value of the widget is set to the variable passed in.
|
||||||
*/
|
*/
|
||||||
void MicroViewWidget::setMaxValue(int16_t max) { maxValue=max; }
|
void MicroViewWidget::setMaxValue(int16_t max) {
|
||||||
|
maxValue = max;
|
||||||
/** \brief Get the maximum possible print lenth of the value
|
setMaxValLen();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \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) {
|
uint8_t MicroViewWidget::getMaxValLen() { return maxValLen; }
|
||||||
if ((val<=maxValue) && (val>=minValue)){
|
|
||||||
value=val;
|
/** \brief Set current value and update widget.
|
||||||
this->draw();
|
|
||||||
|
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.
|
/** \brief MicroView Widget reDraw routine.
|
||||||
|
|
||||||
Redraws the widget.
|
Redraws the widget.
|
||||||
*/
|
*/
|
||||||
void MicroViewWidget::reDraw() {
|
void MicroViewWidget::reDraw() {
|
||||||
needFirstDraw=true;
|
|
||||||
this->drawFace();
|
this->drawFace();
|
||||||
|
this->drawPointer(); // initial pointer (will be erased)
|
||||||
this->draw();
|
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.
|
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) {
|
void MicroViewWidget::drawNumValue(int16_t value) {
|
||||||
char strBuffer[7];
|
|
||||||
char formatStr[] = "%1d";
|
|
||||||
|
|
||||||
formatStr[1] = '0' + getMaxValLen(); // Set the field width for the value range
|
for (uint8_t i = maxValLen - getInt16PrintLen(value); i > 0; i--) {
|
||||||
sprintf(strBuffer, formatStr, value);
|
uView.print(" ");
|
||||||
uView.print(strBuffer);
|
}
|
||||||
|
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.
|
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) {
|
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
|
||||||
style=0;
|
MicroViewWidget(newx, newy, min, max),
|
||||||
totalTicks=30;
|
style(0),
|
||||||
noValDraw=false;
|
totalTicks(30),
|
||||||
prevValue=getMinValue();
|
noValDraw(false),
|
||||||
needFirstDraw=true;
|
prevValue(value)
|
||||||
|
{
|
||||||
drawFace();
|
drawFace();
|
||||||
|
drawPointer(); // Initial pointer (will be erased)
|
||||||
draw();
|
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).
|
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
|
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
|
noValDraw = sty & WIDGETNOVALUE; // set "no value draw" flag as specified
|
||||||
|
|
||||||
switch(sty & ~WIDGETNOVALUE) {
|
switch(sty & ~WIDGETNOVALUE) {
|
||||||
@@ -1506,9 +1556,8 @@ MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevValue=getMinValue();
|
|
||||||
needFirstDraw=true;
|
|
||||||
drawFace();
|
drawFace();
|
||||||
|
drawPointer(); // Initial pointer (will be erased)
|
||||||
draw();
|
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.
|
Draw image/diagram representing the widget's face.
|
||||||
*/
|
*/
|
||||||
void MicroViewSlider::drawFace() {
|
void MicroViewSlider::drawFace() {
|
||||||
uint8_t offsetX, offsetY, endOffset;
|
uint8_t endOffset;
|
||||||
offsetX=getX();
|
|
||||||
offsetY=getY();
|
|
||||||
|
|
||||||
//Horizontal styles, style 0 or 1
|
//Horizontal styles, style 0 or 1
|
||||||
if (style==0 || style==1) {
|
if (style==0 || style==1) {
|
||||||
endOffset = offsetX + totalTicks + 2;
|
endOffset = posX + totalTicks + 2;
|
||||||
// Draw minor ticks
|
// Draw minor ticks
|
||||||
for (uint8_t i=offsetX+1; i<endOffset; i+=2) {
|
for (uint8_t i=posX+1; i<endOffset; i+=2) {
|
||||||
uView.lineV(i, offsetY+5, 3);
|
uView.lineV(i, posY+5, 3);
|
||||||
}
|
}
|
||||||
// Draw extensions for major ticks
|
// Draw extensions for major ticks
|
||||||
for (uint8_t i=offsetX+1; i<endOffset; i+=10) {
|
for (uint8_t i=posX+1; i<endOffset; i+=10) {
|
||||||
uView.lineV(i, offsetY+3, 2);
|
uView.lineV(i, posY+3, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Vertical styles, style 2 or 3
|
//Vertical styles, style 2 or 3
|
||||||
else {
|
else {
|
||||||
endOffset = offsetY + totalTicks + 2;
|
endOffset = posY + totalTicks + 2;
|
||||||
// Draw minor ticks
|
// Draw minor ticks
|
||||||
for (uint8_t i=offsetY+1; i<=endOffset; i+=2) {
|
for (uint8_t i=posY+1; i<=endOffset; i+=2) {
|
||||||
uView.lineH(offsetX, i, 3);
|
uView.lineH(posX, i, 3);
|
||||||
}
|
}
|
||||||
// Draw extensions for major ticks
|
// Draw extensions for major ticks
|
||||||
for (uint8_t i=offsetY+1; i<=endOffset; i+=10) {
|
for (uint8_t i=posY+1; i<=endOffset; i+=10) {
|
||||||
uView.lineH(offsetX+3, i, 2);
|
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.
|
Convert the current value of the widget and draw the ticker representing the value.
|
||||||
*/
|
*/
|
||||||
void MicroViewSlider::draw() {
|
void MicroViewSlider::draw() {
|
||||||
// Draw the initial pointer or erase the previous pointer
|
drawPointer(); // Erase the previous pointer
|
||||||
drawPointer();
|
prevValue=value;
|
||||||
|
drawPointer(); // Draw the current pointer
|
||||||
if (needFirstDraw) {
|
|
||||||
needFirstDraw=false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prevValue=getValue();
|
|
||||||
// Draw current pointer
|
|
||||||
drawPointer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw numeric value if required
|
// Draw numeric value if required
|
||||||
if (!noValDraw) {
|
if (!noValDraw) {
|
||||||
uint8_t offsetX = getX();
|
|
||||||
uint8_t offsetY = getY();
|
|
||||||
|
|
||||||
switch(style) {
|
switch(style) {
|
||||||
case 0:
|
case 0:
|
||||||
uView.setCursor(offsetX+totalTicks+4, offsetY+1);
|
uView.setCursor(posX+totalTicks+4, posY+1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
uView.setCursor(offsetX, offsetY+10);
|
uView.setCursor(posX, posY+10);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
uView.setCursor(offsetX+1, offsetY+totalTicks+4);
|
uView.setCursor(posX+1, posY+totalTicks+4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
uView.setCursor(offsetX+9, offsetY);
|
uView.setCursor(posX+9, posY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1591,18 +1627,16 @@ void MicroViewSlider::draw() {
|
|||||||
// Use XOR mode to erase or draw the pointer for prevValue
|
// Use XOR mode to erase or draw the pointer for prevValue
|
||||||
void MicroViewSlider::drawPointer() {
|
void MicroViewSlider::drawPointer() {
|
||||||
uint8_t tickPosition;
|
uint8_t tickPosition;
|
||||||
uint8_t offsetX = getX();
|
|
||||||
uint8_t offsetY = getY();
|
|
||||||
|
|
||||||
if (style==0 || style==1) { // Horizontal
|
if (style==0 || style==1) { // Horizontal
|
||||||
tickPosition = ((float)(uint16_t)(prevValue-getMinValue())/(float)(uint16_t)(getMaxValue()-getMinValue()))*totalTicks;
|
tickPosition = ((float)(uint16_t)(prevValue-minValue)/(float)(uint16_t)(maxValue-minValue))*totalTicks;
|
||||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
uView.lineH(posX+tickPosition, posY, 3, WHITE, XOR);
|
||||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
uView.pixel(posX+1+tickPosition, posY+1, WHITE, XOR);
|
||||||
}
|
}
|
||||||
else { // Vertical
|
else { // Vertical
|
||||||
tickPosition = ((float)(uint16_t)(getMaxValue()-prevValue)/(float)(uint16_t)(getMaxValue()-getMinValue()))*totalTicks;
|
tickPosition = ((float)(uint16_t)(maxValue-prevValue)/(float)(uint16_t)(maxValue-minValue))*totalTicks;
|
||||||
uView.lineV(offsetX+7, offsetY+tickPosition, 3, WHITE, XOR);
|
uView.lineV(posX+7, posY+tickPosition, 3, WHITE, XOR);
|
||||||
uView.pixel(offsetX+6, offsetY+1+tickPosition, 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.
|
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) {
|
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max):
|
||||||
style=0;
|
MicroViewWidget(newx, newy, min, max),
|
||||||
radius=15;
|
style(0),
|
||||||
noValDraw=false;
|
radius(15),
|
||||||
prevValue=getMinValue();
|
noValDraw(false),
|
||||||
needFirstDraw=true;
|
prevValue(value)
|
||||||
|
{
|
||||||
drawFace();
|
drawFace();
|
||||||
|
drawPointer(); // Initial pointer (will be erased)
|
||||||
draw();
|
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.
|
Initialise the MicroViewGauge widget with style WIDGETSTYLE0 or WIDGETSTYLE1.
|
||||||
Add WIDGETNOVALUE to the style to suppress displaying the numeric value. E.g. WIDGETSTYLE0 + WIDGETNOVALUE
|
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
|
noValDraw = sty & WIDGETNOVALUE; // set "no value draw" flag as specified
|
||||||
|
|
||||||
if ((sty & ~WIDGETNOVALUE) == WIDGETSTYLE0) {
|
if ((sty & ~WIDGETNOVALUE) == WIDGETSTYLE0) {
|
||||||
@@ -1644,9 +1683,9 @@ MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t
|
|||||||
style=1;
|
style=1;
|
||||||
radius=23;
|
radius=23;
|
||||||
}
|
}
|
||||||
prevValue=getMinValue();
|
|
||||||
needFirstDraw=true;
|
|
||||||
drawFace();
|
drawFace();
|
||||||
|
drawPointer(); // Initial pointer (will be erased)
|
||||||
draw();
|
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.
|
Draw image/diagram representing the widget's face.
|
||||||
*/
|
*/
|
||||||
void MicroViewGauge::drawFace() {
|
void MicroViewGauge::drawFace() {
|
||||||
uint8_t offsetX, offsetY;
|
|
||||||
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
|
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
|
for (int i=150;i<=390;i+=30) { // Major tick from 150 degree to 390 degree
|
||||||
degreeSec=i*(PI/180);
|
degreeSec=i*(PI/180);
|
||||||
@@ -1668,7 +1704,7 @@ void MicroViewGauge::drawFace() {
|
|||||||
fromSecY = sin(degreeSec) * (radius / 1.5);
|
fromSecY = sin(degreeSec) * (radius / 1.5);
|
||||||
toSecX = cos(degreeSec) * radius;
|
toSecX = cos(degreeSec) * radius;
|
||||||
toSecY = sin(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) {
|
if (radius>15) {
|
||||||
@@ -1678,7 +1714,7 @@ void MicroViewGauge::drawFace() {
|
|||||||
fromSecY = sin(degreeSec) * (radius / 1.3);
|
fromSecY = sin(degreeSec) * (radius / 1.3);
|
||||||
toSecX = cos(degreeSec) * radius;
|
toSecX = cos(degreeSec) * radius;
|
||||||
toSecY = sin(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.
|
Convert the current value of the widget and draw the ticker representing the value.
|
||||||
*/
|
*/
|
||||||
void MicroViewGauge::draw() {
|
void MicroViewGauge::draw() {
|
||||||
// Draw the initial pointer or erase the previous pointer
|
drawPointer(); // Erase the previous pointer
|
||||||
drawPointer();
|
prevValue=value;
|
||||||
|
drawPointer(); // Draw the current pointer
|
||||||
if (needFirstDraw) {
|
|
||||||
needFirstDraw=false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prevValue=getValue();
|
|
||||||
// Draw current pointer
|
|
||||||
drawPointer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw numeric value if required
|
// Draw numeric value if required
|
||||||
if (!noValDraw) {
|
if (!noValDraw) {
|
||||||
uint8_t offsetY = getY();
|
uint8_t offsetX = posX - (maxValLen * 3 - 1); // Offset left of centre to print the value
|
||||||
uint8_t offsetX = getX() - (getMaxValLen() * 3 - 1); // Offset left of centre to print the value
|
|
||||||
|
|
||||||
if (style > 0)
|
if (style > 0)
|
||||||
uView.setCursor(offsetX, offsetY+10);
|
uView.setCursor(offsetX, posY+10);
|
||||||
else
|
else
|
||||||
uView.setCursor(offsetX, offsetY+11);
|
uView.setCursor(offsetX, posY+11);
|
||||||
|
|
||||||
drawNumValue(prevValue);
|
drawNumValue(prevValue);
|
||||||
}
|
}
|
||||||
@@ -1716,19 +1743,15 @@ void MicroViewGauge::draw() {
|
|||||||
|
|
||||||
// Use XOR mode to erase or draw the pointer for prevValue
|
// Use XOR mode to erase or draw the pointer for prevValue
|
||||||
void MicroViewGauge::drawPointer() {
|
void MicroViewGauge::drawPointer() {
|
||||||
uint8_t offsetX, offsetY;
|
|
||||||
float degreeSec, toSecX, toSecY;
|
float degreeSec, toSecX, toSecY;
|
||||||
|
|
||||||
offsetX = getX();
|
|
||||||
offsetY = getY();
|
|
||||||
|
|
||||||
// total 240 degree in the widget with 150 degree starting point
|
// 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);
|
* 240) + 150) * (PI / 180);
|
||||||
|
|
||||||
toSecX = cos(degreeSec) * (radius / 1.2);
|
toSecX = cos(degreeSec) * (radius / 1.2);
|
||||||
toSecY = sin(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.
|
/** \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) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
MicroView.h
30
MicroView.h
@@ -230,33 +230,39 @@ private:
|
|||||||
|
|
||||||
class MicroViewWidget {
|
class MicroViewWidget {
|
||||||
public:
|
public:
|
||||||
bool needFirstDraw;
|
|
||||||
MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max);
|
MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max);
|
||||||
uint8_t getX();
|
uint8_t getX();
|
||||||
uint8_t getY();
|
uint8_t getY();
|
||||||
void setX(uint8_t newx);
|
void setX(uint8_t newx);
|
||||||
void setY(uint8_t newy);
|
void setY(uint8_t newy);
|
||||||
|
|
||||||
int16_t getMinValue();
|
int16_t getMinValue();
|
||||||
int16_t getMaxValue();
|
int16_t getMaxValue();
|
||||||
int16_t getValue();
|
int16_t getValue();
|
||||||
void setMinValue(int16_t min);
|
void setMinValue(int16_t min);
|
||||||
void setMaxValue(int16_t max);
|
void setMaxValue(int16_t max);
|
||||||
void setValue(int16_t val);
|
void setValue(int16_t val);
|
||||||
|
void setValue(int16_t val, boolean doDraw);
|
||||||
|
uint8_t getValLen();
|
||||||
uint8_t getMaxValLen();
|
uint8_t getMaxValLen();
|
||||||
/** \brief Draw widget value overridden by child class. */
|
/** \brief Draw widget value overridden by child class. */
|
||||||
virtual void draw(){};
|
virtual void draw(){};
|
||||||
/** \brief Draw widget face overridden by child class. */
|
/** \brief Draw widget face overridden by child class. */
|
||||||
virtual void drawFace(){};
|
virtual void drawFace(){};
|
||||||
void reDraw();
|
void reDraw();
|
||||||
void drawNumValue(int16_t value);
|
void drawNumValue(int16_t value);
|
||||||
virtual ~MicroViewWidget(){};
|
virtual ~MicroViewWidget(){};
|
||||||
private:
|
protected:
|
||||||
uint8_t x;
|
uint8_t posX;
|
||||||
uint8_t y;
|
uint8_t posY;
|
||||||
int16_t maxValue;
|
|
||||||
int16_t minValue;
|
int16_t minValue;
|
||||||
|
int16_t maxValue;
|
||||||
int16_t value;
|
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{
|
class MicroViewSlider: public MicroViewWidget{
|
||||||
@@ -267,8 +273,8 @@ public:
|
|||||||
void drawFace();
|
void drawFace();
|
||||||
private:
|
private:
|
||||||
void drawPointer();
|
void drawPointer();
|
||||||
uint8_t totalTicks, style;
|
uint8_t style, totalTicks;
|
||||||
bool noValDraw;
|
boolean noValDraw;
|
||||||
int16_t prevValue;
|
int16_t prevValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -280,8 +286,8 @@ public:
|
|||||||
void drawFace();
|
void drawFace();
|
||||||
private:
|
private:
|
||||||
void drawPointer();
|
void drawPointer();
|
||||||
uint8_t radius, style;
|
uint8_t style, radius;
|
||||||
bool noValDraw;
|
boolean noValDraw;
|
||||||
int16_t prevValue;
|
int16_t prevValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -92,6 +92,17 @@ void loop() {
|
|||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
## History
|
## 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**
|
**v1.21b: 22nd September 2014 by Esmit Pérez and Scott Allen**
|
||||||
* re-factored code if/else with switch - Esmit Pérez
|
* re-factored code if/else with switch - Esmit Pérez
|
||||||
* simplified draw() to remove redundant code - Esmit Pérez
|
* simplified draw() to remove redundant code - Esmit Pérez
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -208,7 +208,7 @@ void loop() {
|
|||||||
|
|
||||||
/* ==================== Demo 13 ====================
|
/* ==================== Demo 13 ====================
|
||||||
Gauge style 1, with no numeric value.
|
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).
|
Range 1 to 26 (A to Z).
|
||||||
================================================ */
|
================================================ */
|
||||||
demoNumber(13);
|
demoNumber(13);
|
||||||
@@ -246,15 +246,15 @@ void customSlider0(int16_t val) {
|
|||||||
|
|
||||||
// Update function for Demo 9
|
// Update function for Demo 9
|
||||||
void customSlider1(int16_t val) {
|
void customSlider1(int16_t val) {
|
||||||
|
widget1->setValue(val);
|
||||||
uint8_t offsetY = widget1->getY() - 10;
|
uint8_t offsetY = widget1->getY() - 10;
|
||||||
uint8_t offsetX = widget1->getX() + 14;
|
uint8_t offsetX = widget1->getX() + 14;
|
||||||
uView.setCursor(offsetX, offsetY);
|
uView.setCursor(offsetX, offsetY);
|
||||||
uView.print(" "); // erase the previous value in case it's longer
|
uView.print(" "); // erase the previous value in case it's longer
|
||||||
// calculate the offset to centre the value
|
// calculate the offset to centre the value
|
||||||
offsetX += ((widget1->getMaxValLen() - getInt16PrintLen(val)) * 3);
|
offsetX += ((widget1->getMaxValLen() - widget1->getValLen()) * 3);
|
||||||
uView.setCursor(offsetX, offsetY);
|
uView.setCursor(offsetX, offsetY);
|
||||||
uView.print(val);
|
uView.print(val);
|
||||||
widget1->setValue(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update function for Demo 10
|
// 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)) {
|
unsigned long stepDelay, void (*drawFunction)(int16_t val)) {
|
||||||
drawFunction(lowVal);
|
drawFunction(lowVal);
|
||||||
uView.display();
|
uView.display();
|
||||||
|
prevVal = lowVal;
|
||||||
delay(1500);
|
delay(1500);
|
||||||
|
|
||||||
for (int16_t i = lowVal + stepSize; i <= highVal; i += stepSize) {
|
for (int16_t i = lowVal + stepSize; i <= highVal; i += stepSize) {
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ getMaxValue KEYWORD2
|
|||||||
setMaxValue KEYWORD2
|
setMaxValue KEYWORD2
|
||||||
setMinValue KEYWORD2
|
setMinValue KEYWORD2
|
||||||
setValue KEYWORD2
|
setValue KEYWORD2
|
||||||
|
getValLen KEYWORD2
|
||||||
|
getMaxValLen KEYWORD2
|
||||||
draw KEYWORD2
|
draw KEYWORD2
|
||||||
reDraw KEYWORD2
|
reDraw KEYWORD2
|
||||||
drawFace KEYWORD2
|
drawFace KEYWORD2
|
||||||
|
|||||||
Reference in New Issue
Block a user