mirror of
https://github.com/skoelle/m5stack-dashboard.git
synced 2026-09-18 00:50:24 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
#include <M5Stack.h>
|
||||
#include "theme.h"
|
||||
|
||||
// Design note: instead of storing large RGB565 bitmap arrays (which would
|
||||
// bloat flash usage for a first version), icons are drawn procedurally with
|
||||
// M5Stack's canvas primitives (circles, arcs, lines). This keeps the binary
|
||||
// small while still giving a colorful, modern look. If you later want true
|
||||
// pixel-art bitmaps, replace the bodies of these functions with
|
||||
// M5.Lcd.drawBitmap(...) calls against RGB565 arrays generated from PNGs.
|
||||
|
||||
namespace Icons {
|
||||
|
||||
// Draws a sun icon centered at (cx, cy) with given radius
|
||||
inline void drawSun(int cx, int cy, int r) {
|
||||
M5.Lcd.fillCircle(cx, cy, r, Theme::ACCENT_SUN);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
float angle = i * (PI / 4.0);
|
||||
int x1 = cx + cos(angle) * (r + 4);
|
||||
int y1 = cy + sin(angle) * (r + 4);
|
||||
int x2 = cx + cos(angle) * (r + 10);
|
||||
int y2 = cy + sin(angle) * (r + 10);
|
||||
M5.Lcd.drawLine(x1, y1, x2, y2, Theme::ACCENT_SUN);
|
||||
}
|
||||
}
|
||||
|
||||
// Draws a moon icon (crescent) centered at (cx, cy)
|
||||
inline void drawMoon(int cx, int cy, int r) {
|
||||
M5.Lcd.fillCircle(cx, cy, r, Theme::TEXT_DIM);
|
||||
M5.Lcd.fillCircle(cx + r / 2, cy - r / 3, r, Theme::BG);
|
||||
}
|
||||
|
||||
// Draws a cloud icon centered at (cx, cy)
|
||||
inline void drawCloud(int cx, int cy, int scale) {
|
||||
M5.Lcd.fillCircle(cx - scale, cy, scale, Theme::TEXT_DIM);
|
||||
M5.Lcd.fillCircle(cx + scale, cy, scale, Theme::TEXT_DIM);
|
||||
M5.Lcd.fillCircle(cx, cy - scale / 2, scale + 2, Theme::TEXT_DIM);
|
||||
M5.Lcd.fillRect(cx - scale, cy, scale * 2, scale, Theme::TEXT_DIM);
|
||||
}
|
||||
|
||||
// Draws rain drops below a given y position
|
||||
inline void drawRainDrops(int cx, int cy, int count = 3) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int x = cx - (count - 1) * 5 + i * 10;
|
||||
M5.Lcd.drawLine(x, cy, x - 3, cy + 8, Theme::ACCENT_RAIN);
|
||||
}
|
||||
}
|
||||
|
||||
// Combined weather icon based on the API "symbol" field.
|
||||
// symbol examples: "mo____" (clear/moon), "mb____" (cloudy/moon),
|
||||
// "wb____" (cloudy/day). First char roughly encodes day(w)/night(m),
|
||||
// second char encodes condition (o=clear, b=cloudy, r=rain, etc).
|
||||
inline void drawWeatherIcon(const String &symbol, int cx, int cy, int r = 20) {
|
||||
bool isNight = symbol.length() > 0 && symbol.charAt(0) == 'm';
|
||||
char condition = symbol.length() > 1 ? symbol.charAt(1) : 'o';
|
||||
|
||||
switch (condition) {
|
||||
case 'o': // clear
|
||||
if (isNight) drawMoon(cx, cy, r);
|
||||
else drawSun(cx, cy, r);
|
||||
break;
|
||||
case 'b': // cloudy
|
||||
drawCloud(cx, cy, r * 2 / 3);
|
||||
break;
|
||||
case 'r': // rain
|
||||
drawCloud(cx, cy - 5, r * 2 / 3);
|
||||
drawRainDrops(cx, cy + r / 2, 3);
|
||||
break;
|
||||
default:
|
||||
drawCloud(cx, cy, r * 2 / 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Small rain-warning banner icon (drop with exclamation-ish accent)
|
||||
inline void drawRainWarning(int cx, int cy) {
|
||||
M5.Lcd.fillTriangle(cx, cy - 8, cx - 6, cy + 6, cx + 6, cy + 6, Theme::ACCENT_RAIN);
|
||||
M5.Lcd.fillCircle(cx, cy + 2, 2, Theme::BG);
|
||||
}
|
||||
|
||||
// Simple "U" badge for U-Bahn
|
||||
inline void drawUBahnBadge(int x, int y, int w, int h) {
|
||||
M5.Lcd.fillRoundRect(x, y, w, h, 4, Theme::ACCENT_UBAHN);
|
||||
M5.Lcd.setTextColor(Theme::TEXT, Theme::ACCENT_UBAHN);
|
||||
M5.Lcd.setCursor(x + w / 2 - 4, y + h / 2 - 4);
|
||||
M5.Lcd.print("U");
|
||||
}
|
||||
|
||||
// Simple "S" badge for S-Bahn
|
||||
inline void drawSBahnBadge(int x, int y, int w, int h) {
|
||||
M5.Lcd.fillRoundRect(x, y, w, h, 4, Theme::ACCENT_SBAHN);
|
||||
M5.Lcd.setTextColor(Theme::TEXT, Theme::ACCENT_SBAHN);
|
||||
M5.Lcd.setCursor(x + w / 2 - 4, y + h / 2 - 4);
|
||||
M5.Lcd.print("S");
|
||||
}
|
||||
|
||||
// Calendar icon: simple rectangle with a top bar and a page-marker dot
|
||||
inline void drawCalendarIcon(int cx, int cy, int size) {
|
||||
int x = cx - size / 2;
|
||||
int y = cy - size / 2;
|
||||
M5.Lcd.drawRoundRect(x, y, size, size, 3, Theme::ACCENT_CALENDAR);
|
||||
M5.Lcd.fillRect(x, y, size, size / 4, Theme::ACCENT_CALENDAR);
|
||||
M5.Lcd.fillCircle(cx, cy + size / 6, 2, Theme::TEXT);
|
||||
}
|
||||
|
||||
// Retry / error icon: circular arrow suggestion using arcs (approximated
|
||||
// with a broken circle) plus an exclamation mark for simplicity.
|
||||
inline void drawRetryIcon(int cx, int cy, int r) {
|
||||
M5.Lcd.drawCircle(cx, cy, r, Theme::ACCENT_ERROR);
|
||||
M5.Lcd.setTextColor(Theme::ACCENT_ERROR, Theme::BG);
|
||||
M5.Lcd.setCursor(cx - 3, cy - 8);
|
||||
M5.Lcd.print("!");
|
||||
}
|
||||
|
||||
} // namespace Icons
|
||||
Reference in New Issue
Block a user