feat(P4): Bezugsanzeige für alle vier Darstellungen (1.8.1)

Sobald ein Bezug oder Dampfbezug läuft, schrumpft der Temperaturbereich
(flex-grow 3 -> 1) und die untere Zeile wächst (2 -> 3); Shot-Timer und
Gewicht wechseln auf 96 px. Während eines Bezugs zählen Zeit und Gewicht,
die Kesseltemperaturen sind dann Nebensache.

Keine zweite Ansicht: Die Seite verschiebt nur das Gewicht zwischen ihren
beiden Bereichen. Nichts doppelt zu pflegen, nichts springt an eine andere
Stelle.

Der Wechsel hält nach dem Bezug noch vier Sekunden an - ohne dieses
Nachhalten würde die Seite bei jeder kurzen Unterbrechung hin- und
herspringen.

Beide Panel-Varianten mit arduino-cli gegengebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
raw-designs
2026-09-02 19:40:51 +02:00
co-authored by Claude Opus 5
parent 40aabe48bc
commit 785f64331d
2 changed files with 58 additions and 0 deletions
+11
View File
@@ -1,3 +1,14 @@
Version 1.8.1:
- Die Bezugsanzeige ist da, und zwar für alle vier Darstellungen gemeinsam: Sobald ein
Bezug oder Dampfbezug läuft, schrumpft der Temperaturbereich und die untere Zeile wächst.
Shot-Timer und Gewicht werden dabei auf 96 Pixel vergrößert - während eines Bezugs zählen
Zeit und Gewicht, die Kesseltemperaturen sind dann Nebensache.
- Es gibt keine zweite Ansicht: Die Seite verschiebt nur das Gewicht zwischen ihren beiden
Bereichen. Damit bleibt alles an seinem Platz, und es gibt nichts doppelt zu pflegen.
- Der Wechsel hält nach dem Bezug noch vier Sekunden an. Ohne dieses Nachhalten würde die
Seite bei jeder kurzen Unterbrechung hin- und herspringen - das wäre unruhiger als gar
kein Wechsel.
Version 1.8.0:
- Das Dashboard hat vier neue Darstellungen, die die bisherigen fünf ersetzen. Sie sind
keine Varianten desselben Bildes, sondern vier Antworten auf die Frage, was die große
+47
View File
@@ -189,6 +189,10 @@ static lv_obj_t* g_profChip = nullptr;
static lv_obj_t* g_profPicker = nullptr; // Schnellwahl-Overlay (Vollbild-Abdunkelung)
static lv_obj_t* g_profPickerList = nullptr; // Button-Liste im Overlay
static lv_obj_t* g_profPickerInfo = nullptr; // "Lade Profile..."-Hinweis im Overlay
static lv_obj_t* g_infoRow = nullptr; // untere Zeile; waechst waehrend eines Bezugs
static bool g_dashBrewMode = false;
static const lv_font_t* g_shotFontNormal = nullptr;
static const lv_font_t* g_bezugFontNormal = nullptr;
static lv_obj_t* cellShot; static lv_obj_t* lblShotTimer; static lv_obj_t* g_bbtBar = nullptr;
static lv_obj_t* cellSteam; static lv_obj_t* lblSteamTimer; static lv_obj_t* g_sbtBar = nullptr;
static lv_obj_t* cellBezug; static lv_obj_t* lblBezug; static lv_obj_t* g_bbwBar = nullptr;
@@ -1075,6 +1079,7 @@ static void build_dashboard(lv_obj_t* p) {
// Info-Zeile: Timer / Bezug / Eco-Countdown / Gehaeuse (teilen sich die Breite)
lv_obj_t* ir = lv_obj_create(p);
g_infoRow = ir;
lv_obj_set_width(ir, LV_PCT(100));
lv_obj_set_flex_grow(ir, 2);
lv_obj_set_style_bg_opa(ir, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(ir, 0, 0);
@@ -1110,6 +1115,10 @@ static void build_dashboard(lv_obj_t* p) {
lv_bar_set_range(g_bbwBar, 0, 100);
lv_bar_set_value(g_bbwBar, 0, LV_ANIM_OFF);
lv_obj_add_flag(g_bbwBar, LV_OBJ_FLAG_HIDDEN);
// Normalschriften merken, damit der Bezugsmodus sie wieder herstellen kann
g_shotFontNormal = lv_obj_get_style_text_font(lblShotTimer, LV_PART_MAIN);
g_bezugFontNormal = lv_obj_get_style_text_font(lblBezug, LV_PART_MAIN);
cellFlow = infoCell(ir, "FLOW", &lblFlow, lv_color_hex(0x64b5f6));
lv_obj_add_flag(cellFlow, LV_OBJ_FLAG_CLICKABLE); // antippbar -> Brew-Control
lv_obj_add_event_cb(cellFlow, brew_cell_cb, LV_EVENT_CLICKED, nullptr);
@@ -3659,6 +3668,43 @@ static void ready_band_update(const MachineState& st) {
lv_obj_set_style_bg_opa(g_readyBand, LV_OPA_COVER, 0);
}
// ------------------------------------------------------------------------------------
// Bezugsanzeige: die untere Zeile wechselt ihren Zustand
//
// Im Ruhezustand ist der Temperaturbereich das Wichtigste - die haeufigste Frage lautet
// "ist sie bereit?". Waehrend eines Bezugs kehrt sich das um: Dann zaehlen Zeit und
// Gewicht, und die Kesseltemperaturen sind Nebensache. Statt zweier getrennter Ansichten
// verschiebt die Seite nur das Gewicht zwischen ihren beiden Bereichen und vergroessert
// die beiden Zahlen, auf die es dann ankommt.
//
// Der Wechsel haelt nach dem Bezug noch kurz an. Ohne dieses Nachhalten wuerde die Seite
// bei jeder kurzen Unterbrechung hin- und herspringen - das waere unruhiger als gar kein
// Wechsel.
// ------------------------------------------------------------------------------------
#define DASH_BREW_HOLD_MS 4000
static void dash_brew_mode(bool on) {
if (on == g_dashBrewMode) return; // nur bei echtem Wechsel neu anordnen
g_dashBrewMode = on;
if (!g_tempRow || !g_infoRow) return;
lv_obj_set_flex_grow(g_tempRow, on ? 1 : 3);
lv_obj_set_flex_grow(g_infoRow, on ? 3 : 2);
if (lblShotTimer && g_shotFontNormal)
lv_obj_set_style_text_font(lblShotTimer, on ? &lv_font_maven_pro_96 : g_shotFontNormal, 0);
if (lblBezug && g_bezugFontNormal)
lv_obj_set_style_text_font(lblBezug, on ? &lv_font_maven_pro_96 : g_bezugFontNormal, 0);
}
static void dash_brew_mode_tick(const MachineState& st) {
static bool war = false; // schon einmal ein Bezug gesehen?
static uint32_t zuletzt = 0;
bool aktiv = st.shotActive || st.steamCircuitActive;
uint32_t jetzt = lv_tick_get();
if (aktiv) { war = true; zuletzt = jetzt; }
dash_brew_mode(aktiv || (war && (uint32_t)(jetzt - zuletzt) < DASH_BREW_HOLD_MS));
}
void ui_update(const MachineState& st) {
if (!g_uiReady) return;
@@ -3999,6 +4045,7 @@ void ui_update(const MachineState& st) {
temp_progress_set(barDutyD, arcTempD, bulbTempD, pctD, colD);
}
ready_band_update(st);
dash_brew_mode_tick(st);
if (false) {
}
}