Compare commits

..
Author SHA1 Message Date
raw-designsandClaude Opus 5 95373dc619 feat(P4): Brew-Control zweispaltig auf dem 7-Zoll-Panel (1.7.0)
Die Seiten sind als einspaltige Stapel für 800x480 entstanden. Auf 1280x720
bleibt daneben rund 40 % der Fläche leer, während unten Karten aus dem Bild
fallen - und Scrollen ist auf diesem Panel teuer, weil ohne Doppelpufferung
jedes Bild komplett neu entsteht.

- Neue Helfer page_grid() und grid_at() legen eine Seite als LVGL-Raster an.
- build_brew() ordnet die vier Karten in zwei Spalten: links was den Bezug
  startet (Pre-Infusion, Brew-by-Time), rechts was ihn beendet
  (Brew-by-Weight, Dampf-Timer).
- Der Speichern-Knopf steht frei unter allen Karten statt in einer davon -
  er speichert die ganze Seite.
- Nur für WS_PANEL_7H; die JC-Panels bleiben einspaltig.

Beide Panel-Varianten mit arduino-cli gegengebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 17:24:42 +02:00
thomas a1c047e1ef Merge pull request 'perf(P4): Scrollen ohne Nachlauf am Waveshare-Panel (1.6.27)' (#55) from perf/scrollen-ohne-nachlauf into main 2026-09-02 17:03:04 +02:00
raw-designsandClaude Opus 5 52391c46c9 perf(P4): Scrollen ohne Nachlauf am Waveshare-Panel (1.6.27)
Ohne Doppelpufferung entsteht beim Scrollen jedes Bild komplett neu
(1280x676 in 24 Bit, per Software). Am stärksten fällt das beim Ausrollen
nach dem Loslassen auf: Dort bewegt sich das Bild weiter, ohne dass ein
Finger es führt, und jedes Stocken ist unmittelbar zu sehen.

LV_OBJ_FLAG_SCROLL_MOMENTUM ist für die scrollbaren Container deshalb
abgeschaltet - die Liste folgt nur noch dem Finger. Nur für WS_PANEL_7H;
die JC-Panels haben das Tempoproblem nicht und bleiben unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 17:01:40 +02:00
thomas 5d47228eed Merge pull request 'fix(P4): Blaue Zwischenbilder beim Bildlauf beseitigt (1.6.26)' (#54) from fix/blaue-zwischenbilder into main 2026-09-02 03:49:23 +02:00
2 changed files with 93 additions and 0 deletions
+19
View File
@@ -1,3 +1,22 @@
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
+74
View File
@@ -449,6 +449,61 @@ 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 };
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 +517,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 +2139,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
}
// =====================================================================================
@@ -2304,6 +2376,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);
@@ -3289,6 +3362,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);