Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5defbe362c | ||
|
|
749f50097f | ||
|
|
95373dc619 | ||
|
|
a1c047e1ef | ||
|
|
52391c46c9 | ||
|
|
5d47228eed |
@@ -1,3 +1,39 @@
|
||||
Version 1.7.1:
|
||||
- Cold Extraction ist auf dem 7-Zoll-Panel dreispaltig: oben die drei Karten mit
|
||||
Erklaerungstext (Modus, Vorbenetzung, Bezugsende), darunter die knappen (Grundeinstellung,
|
||||
Hauptbezug, Pumpenschutz), der Speichern-Knopf frei unter allen sechs. Drei statt zwei
|
||||
Spalten, weil die Erklaerungstexte keine volle Zeilenbreite brauchen und so am Ende keine
|
||||
halbleere Reihe stehen bleibt.
|
||||
- Der Warnhinweis stand bisher als eigene Zeile am Seitenende, weit entfernt von dem
|
||||
Schalter, auf den er sich bezieht. Er sitzt jetzt in der Modus-Karte.
|
||||
- Reinigung & Wartung ist zweispaltig und besteht aus vier Karten: Wartungszaehler,
|
||||
Flush-Zeiten, Display-Helligkeit sowie Reinigung & Entkalkung. Bisher standen dort lose
|
||||
Zeilen unter blossen Zwischenueberschriften, dazwischen freistehende Knoepfe.
|
||||
- Anders als bei Bruehen und Cold Extraction sitzt der Speichern-Knopf hier IN der Karte:
|
||||
Jede Karte speichert etwas anderes, deshalb gehoert der Knopf zur Karte statt unter die
|
||||
Seite.
|
||||
- Alle drei umgestellten Seiten passen jetzt vollstaendig auf den Bildschirm. Die JC-Panels
|
||||
behalten ihr einspaltiges Layout.
|
||||
|
||||
Version 1.7.0:
|
||||
- Brew-Control ist auf dem 7-Zoll-Panel zweispaltig: Pre-Infusion und Brew-by-Weight oben,
|
||||
Brew-by-Time und Dampf-Timer darunter, der Speichern-Knopf frei unter allen Karten.
|
||||
Damit passt die Seite vollstaendig auf den Bildschirm und muss nicht mehr gescrollt
|
||||
werden - der teuerste Vorgang der Oberflaeche entfaellt dort ersatzlos.
|
||||
- Die Anordnung folgt der Bedeutung: links steht, was den Bezug startet, rechts, was ihn
|
||||
beendet.
|
||||
- Der Speichern-Knopf sitzt bewusst nicht in einer der Karten. Er speichert die ganze Seite
|
||||
und wuerde in einer einzelnen Karte so wirken, als gaelte er nur fuer diese.
|
||||
- Die JC-Panels bleiben einspaltig - dort ist der Platz knapp, nicht ueppig.
|
||||
- Cold Extraction und Reinigung/Wartung folgen als naechstes.
|
||||
|
||||
Version 1.6.27:
|
||||
- Beim Waveshare-Panel rollen scrollbare Listen nach dem Loslassen nicht mehr aus, sondern
|
||||
folgen nur dem Finger. Ohne Doppelpufferung entsteht beim Scrollen jedes Bild komplett
|
||||
neu; am staerksten faellt das beim Ausrollen auf, wo sich das Bild ohne fuehrenden Finger
|
||||
weiterbewegt und jedes Stocken unmittelbar sichtbar ist.
|
||||
- Die JC-Panels sind ausgenommen, ihr Bediengefuehl bleibt unveraendert.
|
||||
|
||||
Version 1.6.26:
|
||||
- Fehlerbehebung: Beim Bildlauf blitzten blaue Zwischenbilder auf. Ursache war der zweite
|
||||
Zeichenpuffer aus 1.6.25. Der Panel-Treiber lehnt eine Uebertragung ab, solange die
|
||||
|
||||
+135
-7
@@ -449,6 +449,65 @@ static void add_save_button(lv_obj_t* parent, const char* txt, lv_event_cb_t cb)
|
||||
lv_obj_add_event_cb(b, cb, LV_EVENT_CLICKED, nullptr);
|
||||
}
|
||||
// Eine Seite (Vollflaeche im Content-Bereich, scrollbar, Spalten-Layout)
|
||||
// Nachlauf beim Scrollen abschalten.
|
||||
//
|
||||
// Ohne Doppelpufferung entsteht beim Scrollen jedes Bild komplett neu - 1280x676 Pixel in
|
||||
// 24 Bit, per Software. Am staerksten faellt das beim Ausrollen nach dem Loslassen auf:
|
||||
// Dort bewegt sich das Bild weiter, ohne dass ein Finger es fuehrt, und jedes Stocken ist
|
||||
// unmittelbar zu sehen. Folgt die Liste dagegen nur dem Finger, entstehen weniger Bilder,
|
||||
// und die verbleibenden fallen kaum auf.
|
||||
//
|
||||
// Nur fuer das Waveshare-Panel: Die JC-Panels haben das Tempoproblem nicht, ihr
|
||||
// Bediengefuehl soll unveraendert bleiben.
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Mehrspaltige Seiten fuer das grosse Panel
|
||||
//
|
||||
// Die Seiten sind als einspaltige Stapel entstanden - entworfen fuer 800x480, wo eine
|
||||
// Spalte alles ist, was hineinpasst. Auf 1280x720 bleibt daneben rund 40 % der Flaeche
|
||||
// leer, waehrend unten Karten aus dem Bild fallen und gescrollt werden muss. Und Scrollen
|
||||
// ist auf diesem Panel teuer: Ohne Doppelpufferung entsteht dabei jedes Bild komplett neu.
|
||||
//
|
||||
// Deshalb hier ein Raster statt eines Stapels. Passt eine Seite vollstaendig auf den
|
||||
// Bildschirm, entfaellt der teuerste Vorgang der Oberflaeche ersatzlos.
|
||||
//
|
||||
// Die JC-Panels bleiben einspaltig: Dort ist der Platz knapp, nicht ueppig.
|
||||
// ------------------------------------------------------------------------------------
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
static const int32_t PAGE_COLS_2[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST };
|
||||
// Zwei Kartenreihen, darunter eine Reihe fuer den Speichern-Knopf.
|
||||
static const int32_t PAGE_ROWS_2C[] = { LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST };
|
||||
// Drei Spalten fuer Seiten mit sechs Karten: Die Erklaerungstexte brauchen keine volle
|
||||
// Zeilenbreite, und in drei Spalten bleibt am Ende keine halbleere Reihe stehen.
|
||||
static const int32_t PAGE_COLS_3[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST };
|
||||
|
||||
static void page_grid(lv_obj_t* p, const int32_t* cols, const int32_t* rows) {
|
||||
lv_obj_set_layout(p, LV_LAYOUT_GRID);
|
||||
lv_obj_set_grid_dsc_array(p, cols, rows);
|
||||
lv_obj_set_style_pad_column(p, 12, 0);
|
||||
lv_obj_set_style_pad_row(p, 12, 0);
|
||||
}
|
||||
|
||||
// Karte in eine Rasterzelle setzen. Die Breite kommt ab jetzt aus der Spalte, deshalb muss
|
||||
// die Prozentbreite aus group_card() zurueckgenommen werden - sie bezoege sich sonst auf
|
||||
// die ganze Seite statt auf die Zelle.
|
||||
static void grid_at(lv_obj_t* c, uint8_t col, uint8_t row, uint8_t col_span = 1) {
|
||||
lv_obj_set_width(c, LV_SIZE_CONTENT);
|
||||
lv_obj_set_grid_cell(c, LV_GRID_ALIGN_STRETCH, col, col_span,
|
||||
LV_GRID_ALIGN_START, row, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void scroll_ohne_nachlauf(lv_obj_t* o) {
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
lv_obj_clear_flag(o, LV_OBJ_FLAG_SCROLL_MOMENTUM);
|
||||
#else
|
||||
(void)o;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lv_obj_t* make_page(lv_obj_t* parent) {
|
||||
lv_obj_t* p = lv_obj_create(parent);
|
||||
lv_obj_set_size(p, LV_PCT(100), LV_PCT(100));
|
||||
@@ -462,6 +521,7 @@ static lv_obj_t* make_page(lv_obj_t* parent) {
|
||||
lv_obj_set_style_pad_all(p, 8, 0);
|
||||
lv_obj_set_style_pad_row(p, 6, 0);
|
||||
lv_obj_set_flex_flow(p, LV_FLEX_FLOW_COLUMN);
|
||||
scroll_ohne_nachlauf(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -2083,7 +2143,23 @@ static void build_brew(lv_obj_t* p) {
|
||||
swSBT = add_switch(cSBT, "Aktiv");
|
||||
taSbtSecs = add_num(cSBT, "Zielzeit (s)");
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Zwei Spalten: links, was den Bezug startet, rechts, was ihn beendet.
|
||||
page_grid(p, PAGE_COLS_2, PAGE_ROWS_2C);
|
||||
grid_at(cPI, 0, 0);
|
||||
grid_at(cBBW, 1, 0);
|
||||
grid_at(cBBT, 0, 1);
|
||||
grid_at(cSBT, 1, 1);
|
||||
|
||||
// Speichern frei unter den Karten, nicht in einer davon: Der Knopf speichert die ganze
|
||||
// Seite und wuerde in einer einzelnen Karte so wirken, als gaelte er nur fuer diese.
|
||||
lv_obj_t* sb = th_accent_button(p, "Brühen speichern");
|
||||
lv_obj_add_event_cb(sb, send_save_brew, LV_EVENT_CLICKED, nullptr);
|
||||
lv_obj_set_width(sb, LV_SIZE_CONTENT);
|
||||
lv_obj_set_grid_cell(sb, LV_GRID_ALIGN_END, 0, 2, LV_GRID_ALIGN_START, 2, 1);
|
||||
#else
|
||||
add_save_button(p, "Brühen speichern", send_save_brew);
|
||||
#endif
|
||||
}
|
||||
|
||||
// =====================================================================================
|
||||
@@ -2145,14 +2221,28 @@ static void build_coldex(lv_obj_t* p) {
|
||||
taCxPumpMaxRun = add_num(cPump, "Max. Laufzeit (s)");
|
||||
taCxPumpRest = add_num(cPump, "Zwangspause (s)");
|
||||
|
||||
lblCxPageHint = lv_label_create(p);
|
||||
// Der Warnhinweis stand frueher als eigene Zeile am Seitenende - weit entfernt von dem
|
||||
// Schalter, auf den er sich bezieht. Er gehoert in die Modus-Karte.
|
||||
lblCxPageHint = lv_label_create(cMode);
|
||||
lv_label_set_long_mode(lblCxPageHint, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_set_width(lblCxPageHint, LV_PCT(100));
|
||||
lv_obj_set_style_text_color(lblCxPageHint, COL_WARN, 0);
|
||||
lv_label_set_text(lblCxPageHint, "");
|
||||
lv_obj_add_flag(lblCxPageHint, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Drei Spalten, oben die Karten mit Erklaerungstext, darunter die knappen.
|
||||
page_grid(p, PAGE_COLS_3, PAGE_ROWS_2C);
|
||||
grid_at(cMode, 0, 0); grid_at(cPre, 1, 0); grid_at(cEnd, 2, 0);
|
||||
grid_at(cBase, 0, 1); grid_at(cMain, 1, 1); grid_at(cPump, 2, 1);
|
||||
|
||||
lv_obj_t* sbCx = th_accent_button(p, "Cold Extraction speichern");
|
||||
lv_obj_add_event_cb(sbCx, send_save_coldex, LV_EVENT_CLICKED, nullptr);
|
||||
lv_obj_set_width(sbCx, LV_SIZE_CONTENT);
|
||||
lv_obj_set_grid_cell(sbCx, LV_GRID_ALIGN_END, 0, 3, LV_GRID_ALIGN_START, 2, 1);
|
||||
#else
|
||||
add_save_button(p, "Cold Extraction speichern", send_save_coldex);
|
||||
#endif
|
||||
}
|
||||
// Felder nur beim Oeffnen der Seite fuellen - laufende State-Pushes duerfen eine
|
||||
// begonnene Eingabe nicht ueberschreiben (gleiches Muster wie populate_brew).
|
||||
@@ -2304,6 +2394,7 @@ static void build_cleaning_screen() {
|
||||
lv_obj_set_style_pad_all(g_clnCfg, 0, 0); lv_obj_set_style_pad_row(g_clnCfg, 8, 0);
|
||||
lv_obj_set_flex_flow(g_clnCfg, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_scroll_dir(g_clnCfg, LV_DIR_VER);
|
||||
scroll_ohne_nachlauf(g_clnCfg);
|
||||
lv_obj_set_scrollbar_mode(g_clnCfg, LV_SCROLLBAR_MODE_AUTO);
|
||||
|
||||
lv_obj_t* hint = lv_label_create(g_clnCfg);
|
||||
@@ -2383,6 +2474,47 @@ static void send_reset_maint(lv_event_t*) {
|
||||
showToast("Wartungszähler zurückgesetzt", false);
|
||||
}
|
||||
static void build_service(lv_obj_t* p) {
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Vier Karten in zwei Spalten. Frueher standen hier lose Zeilen unter blossen
|
||||
// Zwischenueberschriften, dazwischen freistehende Knoepfe - schwer auseinanderzuhalten
|
||||
// und laenger als der Bildschirm. Jede Funktion ist jetzt eine Karte, und der
|
||||
// zugehoerige Speichern-Knopf sitzt darin: Anders als bei Bruehen und Cold Extraction
|
||||
// speichert hier jede Karte etwas anderes, deshalb gehoert der Knopf zur Karte.
|
||||
lv_obj_t* cMaint = group_card(p, "Wartungszähler");
|
||||
lblMaintStatus = lv_label_create(cMaint);
|
||||
lv_label_set_long_mode(lblMaintStatus, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_set_width(lblMaintStatus, LV_PCT(100));
|
||||
lv_label_set_text(lblMaintStatus, "Bezüge seit Reset: --");
|
||||
lv_obj_set_style_text_color(lblMaintStatus, COL_TEXT, 0);
|
||||
taMaintInterval = add_num(cMaint, "Intervall (Bezüge)");
|
||||
lv_obj_t* rowM = row(cMaint, nullptr);
|
||||
lv_obj_t* rb = th_button(rowM, "Zähler zurücksetzen", COL_WARN, lv_color_hex(0x000000));
|
||||
lv_obj_add_event_cb(rb, send_reset_maint, LV_EVENT_CLICKED, nullptr);
|
||||
lv_obj_t* sbM = th_accent_button(rowM, "Speichern");
|
||||
lv_obj_add_event_cb(sbM, send_save_maint, LV_EVENT_CLICKED, nullptr);
|
||||
|
||||
lv_obj_t* cFlush = group_card(p, "Flush-Zeiten", "Spüldauer für Wasser- und Dampfkreislauf");
|
||||
taFlushDur = add_num(cFlush, "Wasser-Flush (s)");
|
||||
taSteamFlushDur = add_num(cFlush, "Dampf-Flush (s)");
|
||||
add_save_button(cFlush, "Speichern", send_save_flush);
|
||||
|
||||
lv_obj_t* cLight = group_card(p, "Display-Helligkeit", "Gilt für dieses Touch-Display");
|
||||
taBacklightActive = add_num(cLight, "Aktiv (%)");
|
||||
taBacklightStandby = add_num(cLight, "Standby-Uhr (%)");
|
||||
add_save_button(cLight, "Speichern", send_save_display);
|
||||
|
||||
lv_obj_t* cCln = group_card(p, "Reinigung & Entkalkung",
|
||||
"Der Assistent führt Schritt für Schritt durch den Vorgang");
|
||||
swMaint2 = add_switch(cCln, "Wartungsmodus");
|
||||
lv_obj_add_event_cb(swMaint2, maint_cb, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
lv_obj_t* cb = th_accent_button(cCln, "Reinigungsassistent öffnen");
|
||||
lv_obj_set_width(cb, LV_PCT(100));
|
||||
lv_obj_add_event_cb(cb, cln_open, LV_EVENT_CLICKED, nullptr);
|
||||
|
||||
page_grid(p, PAGE_COLS_2, PAGE_ROWS_2C);
|
||||
grid_at(cMaint, 0, 0); grid_at(cFlush, 1, 0);
|
||||
grid_at(cLight, 0, 1); grid_at(cCln, 1, 1);
|
||||
#else
|
||||
section_title(p, "Reinigung & Wartung");
|
||||
|
||||
// Live-Status (Zaehler / Intervall / Faelligkeit) - aktualisiert ui_update
|
||||
@@ -2397,37 +2529,32 @@ static void build_service(lv_obj_t* p) {
|
||||
lv_label_set_text(lblMaintStatus, "Bezüge seit Reset: --");
|
||||
lv_obj_set_style_text_color(lblMaintStatus, COL_TEXT, 0);
|
||||
|
||||
// Intervall einstellen + speichern
|
||||
taMaintInterval = add_num(p, "Intervall (Bezüge)");
|
||||
add_save_button(p, "Intervall speichern", send_save_maint);
|
||||
|
||||
// Zaehler zuruecksetzen
|
||||
lv_obj_t* rb = th_button(p, "Wartungszähler zurücksetzen", COL_WARN, lv_color_hex(0x000000));
|
||||
lv_obj_set_width(rb, LV_PCT(100));
|
||||
lv_obj_add_event_cb(rb, send_reset_maint, LV_EVENT_CLICKED, nullptr);
|
||||
|
||||
// Flush-Zeiten (Wasser- und Dampfkreislauf), 1..30 s - wie in der Web-UI der S3
|
||||
section_title(p, "Flush-Zeiten");
|
||||
taFlushDur = add_num(p, "Wasser-Flush (s)");
|
||||
taSteamFlushDur = add_num(p, "Dampf-Flush (s)");
|
||||
add_save_button(p, "Flush-Zeiten speichern", send_save_flush);
|
||||
|
||||
// Display-Helligkeit dieses Touch-Displays (aktiv 5..100 %, Standby-Uhr 0..100 %)
|
||||
section_title(p, "Display-Helligkeit");
|
||||
taBacklightActive = add_num(p, "Aktiv (%)");
|
||||
taBacklightStandby = add_num(p, "Standby-Uhr (%)");
|
||||
add_save_button(p, "Helligkeit speichern", send_save_display);
|
||||
|
||||
// Reinigungsassistent (eigener Sub-Screen mit Parametern + Live-Fortschritt)
|
||||
section_title(p, "Reinigungsassistent");
|
||||
lv_obj_t* cb = th_accent_button(p, "Reinigungsassistent öffnen");
|
||||
lv_obj_set_width(cb, LV_PCT(100));
|
||||
lv_obj_add_event_cb(cb, cln_open, LV_EVENT_CLICKED, nullptr);
|
||||
|
||||
// Wartungsmodus-Toggle (gleiche Aktion wie auf der Temperatur-Seite)
|
||||
section_title(p, "Wartungsmodus (Entkalkung)");
|
||||
swMaint2 = add_switch(p, "Wartungsmodus");
|
||||
lv_obj_add_event_cb(swMaint2, maint_cb, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// =====================================================================================
|
||||
@@ -3289,6 +3416,7 @@ void ui_init(ProtocolClient* client) {
|
||||
lv_obj_set_style_pad_row(menu, 6, 0);
|
||||
lv_obj_set_flex_flow(menu, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_scroll_dir(menu, LV_DIR_VER); // bei vielen Eintraegen vertikal scrollbar
|
||||
scroll_ohne_nachlauf(menu);
|
||||
lv_obj_set_scrollbar_mode(menu, LV_SCROLLBAR_MODE_AUTO);
|
||||
for (int i = 0; i < PG_COUNT; i++) {
|
||||
lv_obj_t* mb = th_button(menu, PAGE_NAMES[i], COL_CARD, COL_TEXT);
|
||||
|
||||
Reference in New Issue
Block a user