mirror of
https://github.com/skoelle/wt32sc01-dashboard.git
synced 2026-09-17 17:30:25 +00:00
Phase 3: reusable UI widgets (tile_button, back_button) + screen_base lifecycle
- tile_button: large touch tile with accent bg + title + icon + value, fires LV_EVENT_CLICKED (for home screen tiles) - back_button: fixed bottom-left Zurueck button (LV_SYMBOL_LEFT), large touch target, reused on all detail screens - screen_base.h: Screen struct with create/show/hide/refresh/tick lifecycle around an lv_obj_t root (replaces old ScreenId-only header) - lv_conf.h: enable Montserrat 16/20/24 fonts used by the widgets
This commit is contained in:
@@ -654,11 +654,11 @@
|
|||||||
#define LV_FONT_MONTSERRAT_10 0
|
#define LV_FONT_MONTSERRAT_10 0
|
||||||
#define LV_FONT_MONTSERRAT_12 0
|
#define LV_FONT_MONTSERRAT_12 0
|
||||||
#define LV_FONT_MONTSERRAT_14 1
|
#define LV_FONT_MONTSERRAT_14 1
|
||||||
#define LV_FONT_MONTSERRAT_16 0
|
#define LV_FONT_MONTSERRAT_16 1
|
||||||
#define LV_FONT_MONTSERRAT_18 0
|
#define LV_FONT_MONTSERRAT_18 0
|
||||||
#define LV_FONT_MONTSERRAT_20 0
|
#define LV_FONT_MONTSERRAT_20 1
|
||||||
#define LV_FONT_MONTSERRAT_22 0
|
#define LV_FONT_MONTSERRAT_22 0
|
||||||
#define LV_FONT_MONTSERRAT_24 0
|
#define LV_FONT_MONTSERRAT_24 1
|
||||||
#define LV_FONT_MONTSERRAT_26 0
|
#define LV_FONT_MONTSERRAT_26 0
|
||||||
#define LV_FONT_MONTSERRAT_28 0
|
#define LV_FONT_MONTSERRAT_28 0
|
||||||
#define LV_FONT_MONTSERRAT_30 0
|
#define LV_FONT_MONTSERRAT_30 0
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
enum class ScreenId {
|
||||||
|
HOME,
|
||||||
|
WEATHER_DETAIL,
|
||||||
|
CALENDAR_DETAIL,
|
||||||
|
MVG
|
||||||
|
};
|
||||||
|
|
||||||
|
// Common lifecycle for all screens. Each screen owns one lv_obj_t screen
|
||||||
|
// object; create() builds the UI once, show()/hide() toggle visibility,
|
||||||
|
// refresh() re-fetches data and updates the widgets, tick() is called
|
||||||
|
// every loop iteration for periodic refresh checks.
|
||||||
|
struct Screen {
|
||||||
|
lv_obj_t *root = nullptr;
|
||||||
|
bool created = false;
|
||||||
|
|
||||||
|
// Build the screen object tree (hidden). Called once at startup.
|
||||||
|
void (*create_fn)(Screen &) = nullptr;
|
||||||
|
// Re-fetch data and update widgets.
|
||||||
|
void (*refresh_fn)(Screen &) = nullptr;
|
||||||
|
// Per-loop tick: check refresh timers / inactivity.
|
||||||
|
void (*tick_fn)(Screen &) = nullptr;
|
||||||
|
|
||||||
|
void create() {
|
||||||
|
if (created || !create_fn) return;
|
||||||
|
root = lv_obj_create(nullptr);
|
||||||
|
lv_obj_set_size(root, 320, 480);
|
||||||
|
lv_obj_set_style_bg_color(root, lv_color_hex(0x000000), 0);
|
||||||
|
lv_obj_set_style_border_width(root, 0, 0);
|
||||||
|
lv_obj_set_style_pad_all(root, 0, 0);
|
||||||
|
lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
create_fn(*this);
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
if (!created) create();
|
||||||
|
lv_screen_load(root);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void hide() {}
|
||||||
|
|
||||||
|
void refresh() {
|
||||||
|
if (created && refresh_fn) refresh_fn(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tick() {
|
||||||
|
if (created && tick_fn) tick_fn(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "back_button.h"
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
|
lv_obj_t *back_button_create(lv_obj_t *parent, lv_event_cb_t on_click,
|
||||||
|
void *user_data) {
|
||||||
|
lv_obj_t *btn = lv_button_create(parent);
|
||||||
|
// Fixed at bottom-left, large enough to be a reliable touch target.
|
||||||
|
lv_obj_set_pos(btn, 12, 480 - 12 - 60);
|
||||||
|
lv_obj_set_size(btn, 100, 60);
|
||||||
|
lv_obj_set_style_bg_color(btn, Theme::bgCard(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_border_width(btn, 0, 0);
|
||||||
|
lv_obj_set_style_radius(btn, 14, 0);
|
||||||
|
|
||||||
|
lv_obj_t *label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, LV_SYMBOL_LEFT " Zurueck");
|
||||||
|
lv_obj_set_style_text_color(label, Theme::text(), 0);
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
if (on_click) {
|
||||||
|
lv_obj_add_event_cb(btn, on_click, LV_EVENT_CLICKED, user_data);
|
||||||
|
}
|
||||||
|
return btn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
// Reusable "Zurueck" button fixed at bottom-left of a detail screen.
|
||||||
|
// Fires the given callback on tap (typically: navigate back to home).
|
||||||
|
lv_obj_t *back_button_create(lv_obj_t *parent, lv_event_cb_t on_click,
|
||||||
|
void *user_data);
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#include "tile_button.h"
|
||||||
|
|
||||||
|
TileButton tile_button_create(lv_obj_t *parent, lv_coord_t x, lv_coord_t y,
|
||||||
|
lv_coord_t w, lv_coord_t h, lv_color_t accent,
|
||||||
|
const char *title, lv_event_cb_t on_click,
|
||||||
|
void *user_data) {
|
||||||
|
TileButton t;
|
||||||
|
t.btn = lv_button_create(parent);
|
||||||
|
lv_obj_set_pos(t.btn, x, y);
|
||||||
|
lv_obj_set_size(t.btn, w, h);
|
||||||
|
lv_obj_set_style_bg_color(t.btn, accent, 0);
|
||||||
|
lv_obj_set_style_bg_opa(t.btn, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_border_width(t.btn, 0, 0);
|
||||||
|
lv_obj_set_style_radius(t.btn, 20, 0);
|
||||||
|
lv_obj_set_style_pad_all(t.btn, 16, 0);
|
||||||
|
|
||||||
|
// Title (top-left).
|
||||||
|
t.title = lv_label_create(t.btn);
|
||||||
|
lv_label_set_text(t.title, title);
|
||||||
|
lv_obj_set_style_text_color(t.title, Theme::text(), 0);
|
||||||
|
lv_obj_set_style_text_font(t.title, &lv_font_montserrat_16, 0);
|
||||||
|
lv_obj_align(t.title, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||||
|
|
||||||
|
// Icon (top-right).
|
||||||
|
t.icon = lv_label_create(t.btn);
|
||||||
|
lv_label_set_text(t.icon, "");
|
||||||
|
lv_obj_set_style_text_color(t.icon, Theme::text(), 0);
|
||||||
|
lv_obj_set_style_text_font(t.icon, &lv_font_montserrat_24, 0);
|
||||||
|
lv_obj_align(t.icon, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||||
|
|
||||||
|
// Value/preview (below title).
|
||||||
|
t.value = lv_label_create(t.btn);
|
||||||
|
lv_label_set_text(t.value, "");
|
||||||
|
lv_obj_set_style_text_color(t.value, Theme::text(), 0);
|
||||||
|
lv_obj_set_style_text_font(t.value, &lv_font_montserrat_20, 0);
|
||||||
|
lv_obj_align(t.value, LV_ALIGN_LEFT_MID, 0, 10);
|
||||||
|
|
||||||
|
if (on_click) {
|
||||||
|
lv_obj_add_event_cb(t.btn, on_click, LV_EVENT_CLICKED, user_data);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tile_button_set_value(TileButton &t, const char *text) {
|
||||||
|
if (t.value) lv_label_set_text(t.value, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tile_button_set_icon(TileButton &t, const char *text) {
|
||||||
|
if (t.icon) lv_label_set_text(t.icon, text);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <lvgl.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
|
// Reusable large touch tile for the home screen. Icon + title + optional
|
||||||
|
// value/preview lines, accent background per category. Fires a callback on tap.
|
||||||
|
struct TileButton {
|
||||||
|
lv_obj_t *btn = nullptr;
|
||||||
|
lv_obj_t *icon = nullptr;
|
||||||
|
lv_obj_t *title = nullptr;
|
||||||
|
lv_obj_t *value = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a tile button inside `parent` at (x,y) with given size and accent.
|
||||||
|
// title: heading text (e.g. "Wetter"); on_click + user_data wired to LV_EVENT_CLICKED.
|
||||||
|
TileButton tile_button_create(lv_obj_t *parent, lv_coord_t x, lv_coord_t y,
|
||||||
|
lv_coord_t w, lv_coord_t h, lv_color_t accent,
|
||||||
|
const char *title, lv_event_cb_t on_click,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
// Set the big value/preview text on the tile (may be multi-line).
|
||||||
|
void tile_button_set_value(TileButton &t, const char *text);
|
||||||
|
|
||||||
|
// Set the icon text (single glyph/symbol). Icons are rendered as text labels
|
||||||
|
// using LVGL's built-in font until bitmap icons land in Phase 6.
|
||||||
|
void tile_button_set_icon(TileButton &t, const char *text);
|
||||||
Reference in New Issue
Block a user