mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 22:48:10 +01:00
[display] filled_ring and filled_gauge methods added (#7420)
This commit is contained in:
parent
fb002ac3b0
commit
3ef31e55ca
3 changed files with 153 additions and 0 deletions
|
@ -156,6 +156,148 @@ void Display::filled_circle(int center_x, int center_y, int radius, Color color)
|
||||||
}
|
}
|
||||||
} while (dx <= 0);
|
} while (dx <= 0);
|
||||||
}
|
}
|
||||||
|
void Display::filled_ring(int center_x, int center_y, int radius1, int radius2, Color color) {
|
||||||
|
int rmax = radius1 > radius2 ? radius1 : radius2;
|
||||||
|
int rmin = radius1 < radius2 ? radius1 : radius2;
|
||||||
|
int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin);
|
||||||
|
int dymax = 0, dymin = 0;
|
||||||
|
int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
|
||||||
|
int e2max, e2min;
|
||||||
|
do {
|
||||||
|
// 8 dots for borders
|
||||||
|
this->draw_pixel_at(center_x - dxmax, center_y + dymax, color);
|
||||||
|
this->draw_pixel_at(center_x + dxmax, center_y + dymax, color);
|
||||||
|
this->draw_pixel_at(center_x - dxmin, center_y + dymin, color);
|
||||||
|
this->draw_pixel_at(center_x + dxmin, center_y + dymin, color);
|
||||||
|
this->draw_pixel_at(center_x + dxmax, center_y - dymax, color);
|
||||||
|
this->draw_pixel_at(center_x - dxmax, center_y - dymax, color);
|
||||||
|
this->draw_pixel_at(center_x + dxmin, center_y - dymin, color);
|
||||||
|
this->draw_pixel_at(center_x - dxmin, center_y - dymin, color);
|
||||||
|
if (dymin < rmin) {
|
||||||
|
// two parts - four lines
|
||||||
|
int hline_width = -(dxmax - dxmin) + 1;
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
|
||||||
|
this->horizontal_line(center_x - dxmin, center_y + dymax, hline_width, color);
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
|
||||||
|
this->horizontal_line(center_x - dxmin, center_y - dymax, hline_width, color);
|
||||||
|
} else {
|
||||||
|
// one part - top and bottom
|
||||||
|
int hline_width = 2 * (-dxmax) + 1;
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
|
||||||
|
}
|
||||||
|
e2max = errmax;
|
||||||
|
// tune external
|
||||||
|
if (e2max < dymax) {
|
||||||
|
errmax += ++dymax * 2 + 1;
|
||||||
|
if (-dxmax == dymax && e2max <= dxmax) {
|
||||||
|
e2max = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e2max > dxmax) {
|
||||||
|
errmax += ++dxmax * 2 + 1;
|
||||||
|
}
|
||||||
|
// tune internal
|
||||||
|
while (dymin < dymax && dymin < rmin) {
|
||||||
|
e2min = errmin;
|
||||||
|
if (e2min < dymin) {
|
||||||
|
errmin += ++dymin * 2 + 1;
|
||||||
|
if (-dxmin == dymin && e2min <= dxmin) {
|
||||||
|
e2min = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e2min > dxmin) {
|
||||||
|
errmin += ++dxmin * 2 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (dxmax <= 0);
|
||||||
|
}
|
||||||
|
void Display::filled_gauge(int center_x, int center_y, int radius1, int radius2, int progress, Color color) {
|
||||||
|
int rmax = radius1 > radius2 ? radius1 : radius2;
|
||||||
|
int rmin = radius1 < radius2 ? radius1 : radius2;
|
||||||
|
int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin), upd_dxmax, upd_dxmin;
|
||||||
|
int dymax = 0, dymin = 0;
|
||||||
|
int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
|
||||||
|
int e2max, e2min;
|
||||||
|
progress = std::max(0, std::min(progress, 100)); // 0..100
|
||||||
|
int draw_progress = progress > 50 ? (100 - progress) : progress;
|
||||||
|
float tan_a = (progress == 50) ? 65535 : tan(float(draw_progress) * M_PI / 100); // slope
|
||||||
|
|
||||||
|
do {
|
||||||
|
// outer dots
|
||||||
|
this->draw_pixel_at(center_x + dxmax, center_y - dymax, color);
|
||||||
|
this->draw_pixel_at(center_x - dxmax, center_y - dymax, color);
|
||||||
|
if (dymin < rmin) { // side parts
|
||||||
|
int lhline_width = -(dxmax - dxmin) + 1;
|
||||||
|
if (progress >= 50) {
|
||||||
|
if (float(dymax) < float(-dxmax) * tan_a) {
|
||||||
|
upd_dxmax = ceil(float(dymax) / tan_a);
|
||||||
|
} else {
|
||||||
|
upd_dxmax = -dxmax;
|
||||||
|
}
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color); // left
|
||||||
|
if (!dymax)
|
||||||
|
this->horizontal_line(center_x - dxmin, center_y, lhline_width, color); // right horizontal border
|
||||||
|
if (upd_dxmax > -dxmin) { // right
|
||||||
|
int rhline_width = (upd_dxmax + dxmin) + 1;
|
||||||
|
this->horizontal_line(center_x - dxmin, center_y - dymax,
|
||||||
|
rhline_width > lhline_width ? lhline_width : rhline_width, color);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (float(dymin) > float(-dxmin) * tan_a) {
|
||||||
|
upd_dxmin = ceil(float(dymin) / tan_a);
|
||||||
|
} else {
|
||||||
|
upd_dxmin = -dxmin;
|
||||||
|
}
|
||||||
|
lhline_width = -(dxmax + upd_dxmin) + 1;
|
||||||
|
if (!dymax)
|
||||||
|
this->horizontal_line(center_x - dxmin, center_y, lhline_width, color); // right horizontal border
|
||||||
|
if (lhline_width > 0)
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color);
|
||||||
|
}
|
||||||
|
} else { // top part
|
||||||
|
int hline_width = 2 * (-dxmax) + 1;
|
||||||
|
if (progress >= 50) {
|
||||||
|
if (dymax < float(-dxmax) * tan_a) {
|
||||||
|
upd_dxmax = ceil(float(dymax) / tan_a);
|
||||||
|
hline_width = -dxmax + upd_dxmax + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dymax < float(-dxmax) * tan_a) {
|
||||||
|
upd_dxmax = ceil(float(dymax) / tan_a);
|
||||||
|
hline_width = -dxmax - upd_dxmax + 1;
|
||||||
|
} else
|
||||||
|
hline_width = 0;
|
||||||
|
}
|
||||||
|
if (hline_width > 0)
|
||||||
|
this->horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
|
||||||
|
}
|
||||||
|
e2max = errmax;
|
||||||
|
if (e2max < dymax) {
|
||||||
|
errmax += ++dymax * 2 + 1;
|
||||||
|
if (-dxmax == dymax && e2max <= dxmax) {
|
||||||
|
e2max = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e2max > dxmax) {
|
||||||
|
errmax += ++dxmax * 2 + 1;
|
||||||
|
}
|
||||||
|
while (dymin <= dymax && dymin <= rmin && dxmin <= 0) {
|
||||||
|
this->draw_pixel_at(center_x + dxmin, center_y - dymin, color);
|
||||||
|
this->draw_pixel_at(center_x - dxmin, center_y - dymin, color);
|
||||||
|
e2min = errmin;
|
||||||
|
if (e2min < dymin) {
|
||||||
|
errmin += ++dymin * 2 + 1;
|
||||||
|
if (-dxmin == dymin && e2min <= dxmin) {
|
||||||
|
e2min = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e2min > dxmin) {
|
||||||
|
errmin += ++dxmin * 2 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (dxmax <= 0);
|
||||||
|
}
|
||||||
void HOT Display::triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color) {
|
void HOT Display::triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color) {
|
||||||
this->line(x1, y1, x2, y2, color);
|
this->line(x1, y1, x2, y2, color);
|
||||||
this->line(x1, y1, x3, y3, color);
|
this->line(x1, y1, x3, y3, color);
|
||||||
|
|
|
@ -285,6 +285,13 @@ class Display : public PollingComponent {
|
||||||
/// Fill a circle centered around [center_x,center_y] with the radius radius with the given color.
|
/// Fill a circle centered around [center_x,center_y] with the radius radius with the given color.
|
||||||
void filled_circle(int center_x, int center_y, int radius, Color color = COLOR_ON);
|
void filled_circle(int center_x, int center_y, int radius, Color color = COLOR_ON);
|
||||||
|
|
||||||
|
/// Fill a ring centered around [center_x,center_y] between two circles with the radius1 and radius2 with the given
|
||||||
|
/// color.
|
||||||
|
void filled_ring(int center_x, int center_y, int radius1, int radius2, Color color = COLOR_ON);
|
||||||
|
/// Fill a half-ring "gauge" centered around [center_x,center_y] between two circles with the radius1 and radius2
|
||||||
|
/// with he given color and filled up to 'progress' percent
|
||||||
|
void filled_gauge(int center_x, int center_y, int radius1, int radius2, int progress, Color color = COLOR_ON);
|
||||||
|
|
||||||
/// Draw the outline of a triangle contained between the points [x1,y1], [x2,y2] and [x3,y3] with the given color.
|
/// Draw the outline of a triangle contained between the points [x1,y1], [x2,y2] and [x3,y3] with the given color.
|
||||||
void triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color = COLOR_ON);
|
void triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color = COLOR_ON);
|
||||||
|
|
||||||
|
|
|
@ -34,3 +34,7 @@ display:
|
||||||
|
|
||||||
it.line_at_angle(centerX, centerY, minuteAngle, radius - 5, radius);
|
it.line_at_angle(centerX, centerY, minuteAngle, radius - 5, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nice ring around and some gauge
|
||||||
|
it.filled_ring(centerX, centerY, radius+5, radius+8);
|
||||||
|
it.filled_gauge(centerX, centerY, radius/2, radius/2-5, 66);
|
||||||
|
|
Loading…
Reference in a new issue