Public Access
Add a PC renderer for the themed pages; fix overlapping layouts
tools/render_pages.py compiles the page code natively with g++ against ESPHome's own display and font code and the font bitmaps of the last `esphome compile`, and draws pages to PNG at chosen moments with sample data (normal, empty, alert, busy), as a contact sheet, or as one example per page in docs/images/pages (now shown in the README). Fixes found with it: Cyber HUD zone names ran into the temperatures, the breach header label hit the tag and the column marker the matrix label; KonoSuba subtitle, guild weather icon, cabbage text and all-day deadline, and hills through the party; Steins;Gate D-mail recipient, the microwave display, the gadget card value and world line labels; LCARS room rows, readout bars and data cascade, warp core readouts, and the captain's log weather wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
13a499fd97
commit
d2e81a5a36
27 files changed
+627
-38
No files matched your search
+24
-17
@@ -223,7 +223,7 @@ void d_mail(EL512Display &it, const Fonts &f, const HomeData &d) {
|
||||
for (int b = 0; b < 4; b++)
|
||||
it.filled_rectangle(146 + b * 6, 26 - b * 2 - 2, 4, b * 2 + 2, COLOR_OFF);
|
||||
if (c < SEND) {
|
||||
it.print(35, 34, f.pixel, TextAlign::TOP_LEFT, "TO: ME, 1 WEEK AGO");
|
||||
it.print(35, 34, f.pixel, TextAlign::TOP_LEFT, "TO: ME, -1 WEEK");
|
||||
it.horizontal_line(34, 45, 138);
|
||||
std::string body = c < TYPE_AT ? "" : typed(msg, c - TYPE_AT, CPS);
|
||||
if ((t / 300) % 2)
|
||||
@@ -267,7 +267,11 @@ void d_mail(EL512Display &it, const Fonts &f, const HomeData &d) {
|
||||
it.draw_pixel_at(x, y, COLOR_ON);
|
||||
it.printf(MX + 209, MY + 23, f.mono, TextAlign::CENTER, "0:%02u", (unsigned) ((ZAP + 300 - c) / 1000));
|
||||
} else {
|
||||
it.print(MX + 209, MY + 23, f.mono, TextAlign::CENTER, upper(watts_text(d.house)).c_str());
|
||||
// The microwave's little display: "850W" or "12.0kW".
|
||||
const std::string lcd = std::isnan(d.house) ? "--"
|
||||
: d.house >= 1000 ? str("%.1fkW", d.house / 1000.0f)
|
||||
: str("%.0fW", d.house);
|
||||
it.print(MX + 209, MY + 23, f.mono, TextAlign::CENTER, lcd.c_str());
|
||||
}
|
||||
// Turntable with a banana on it.
|
||||
for (int a = 0; a < 360; a += 15) {
|
||||
@@ -374,17 +378,19 @@ void gadget_lab(EL512Display &it, const Fonts &f, const HomeData &d) {
|
||||
// Detail card for the selected gadget.
|
||||
const Gadget &g = gadgets[sel];
|
||||
const uint32_t since = t % STEP;
|
||||
it.rectangle(340, 38, 170, 128);
|
||||
it.rectangle(342, 40, 166, 124);
|
||||
it.printf(350, 46, f.title, TextAlign::TOP_LEFT, "NO.%s", g.no.c_str());
|
||||
it.print(502, 46, f.title, TextAlign::TOP_RIGHT, g.value.c_str());
|
||||
int y = 74;
|
||||
// Number, name, value, then the description.
|
||||
it.rectangle(340, 38, 170, 140);
|
||||
it.rectangle(342, 40, 166, 136);
|
||||
it.printf(350, 44, f.title, TextAlign::TOP_LEFT, "NO.%s", g.no.c_str());
|
||||
int y = 68;
|
||||
for (const auto &l : wrap(it, f.mono, g.name, 150, 2)) {
|
||||
it.print(350, y, f.mono, TextAlign::TOP_LEFT, l.c_str());
|
||||
y += 15;
|
||||
}
|
||||
it.horizontal_line(350, y + 2, 150);
|
||||
y += 8;
|
||||
it.print(350, y + 2, f.title, TextAlign::TOP_LEFT, g.value.c_str());
|
||||
y += 26;
|
||||
it.horizontal_line(350, y, 150);
|
||||
y += 5;
|
||||
for (const auto &l : wrap(it, f.mono, typed(g.desc, since, 40), 150, 3)) {
|
||||
it.print(350, y, f.mono, TextAlign::TOP_LEFT, l.c_str());
|
||||
y += 15;
|
||||
@@ -429,7 +435,7 @@ void world_lines(EL512Display &it, const Fonts &f, const HomeData &d, ESPTime no
|
||||
}
|
||||
for (int h = 0; h <= 24; h += 6) {
|
||||
it.vertical_line(xmap(h), PY1, 4);
|
||||
it.printf(xmap(h), PY1 + 8, f.pixel, TextAlign::TOP_CENTER, "%02d:00", h % 24);
|
||||
it.printf(xmap(h), PY1 + 8, f.pixel, h == 24 ? TextAlign::TOP_RIGHT : TextAlign::TOP_CENTER, "%02d:00", h);
|
||||
}
|
||||
|
||||
// Attractor fields.
|
||||
@@ -441,14 +447,15 @@ void world_lines(EL512Display &it, const Fonts &f, const HomeData &d, ESPTime no
|
||||
const int phase = (int) (t / 80);
|
||||
for (const auto &fl : fields) {
|
||||
const int y = ymap(fl.div);
|
||||
if (fl.div == 1.048596f) {
|
||||
// Labels on the left, where the chart stays empty until sunrise: Beta's
|
||||
// above its line, the others below theirs (Steins Gate and Beta are only a
|
||||
// few pixels apart).
|
||||
if (fl.div == 1.048596f)
|
||||
it.horizontal_line(PX0 + 1, y, PX1 - PX0);
|
||||
it.print(PX1, y - 3, f.pixel, TextAlign::BOTTOM_RIGHT, fl.name);
|
||||
} else {
|
||||
else
|
||||
dashed_hline(it, PX0 + 1, y, PX1 - PX0, 4, 4, phase);
|
||||
it.print(PX1, fl.div > 1.1f ? y - 3 : y + 3, f.pixel, fl.div > 1.1f ? TextAlign::BOTTOM_RIGHT : TextAlign::TOP_RIGHT,
|
||||
fl.name);
|
||||
}
|
||||
const bool above = fl.div > 1.1f;
|
||||
it.print(PX0 + 6, above ? y - 3 : y + 3, f.pixel, above ? TextAlign::BOTTOM_LEFT : TextAlign::TOP_LEFT, fl.name);
|
||||
}
|
||||
|
||||
// Today's world line, drawn in over the first 1.5 s.
|
||||
@@ -472,7 +479,7 @@ void world_lines(EL512Display &it, const Fonts &f, const HomeData &d, ESPTime no
|
||||
points++;
|
||||
}
|
||||
if (points == 0 && (t / 600) % 2)
|
||||
it.print((PX0 + PX1) / 2, (PY0 + PY1) / 2 + 30, f.mono, TextAlign::CENTER, "COLLECTING WORLD LINE DATA...");
|
||||
it.print((PX0 + PX1) / 2 - 40, PY1 - 10, f.mono, TextAlign::CENTER, "COLLECTING WORLD LINE DATA...");
|
||||
|
||||
// Where we are now, and the futures branching off it.
|
||||
if (now.is_valid() && t >= 1500) {
|
||||
|
||||
Reference in new issue
Block a user