|
|
|
|
@@ -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,51 @@ 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 Get the maximum possible print length of the value
|
|
|
|
|
|
|
|
|
|
Return the maximum number of characters that would be printed using uView.print(value) for the current value range.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t MicroViewWidget::getMaxValLen() { return maxValLen; }
|
|
|
|
|
|
|
|
|
|
/** \brief Set current value.
|
|
|
|
|
|
|
|
|
|
The current value of the widget is set to the variable passed in.
|
|
|
|
|
*/
|
|
|
|
|
void MicroViewWidget::setValue(int16_t val) {
|
|
|
|
|
if ((val<=maxValue) && (val>=minValue)){
|
|
|
|
|
value=val;
|
|
|
|
|
void MicroViewWidget::setValue(int16_t val) {
|
|
|
|
|
if ((val<=maxValue) && (val>=minValue)) {
|
|
|
|
|
value = val;
|
|
|
|
|
valLen = getInt16PrintLen(val);
|
|
|
|
|
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 +1474,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 +1504,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 +1521,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 +1546,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 +1556,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 +1589,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 +1617,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 +1642,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 +1659,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 +1673,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 +1684,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 +1694,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 +1704,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 +1714,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 +1733,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 +1857,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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|