diff --git a/lv_conf.h b/lv_conf.h index 8c94a2c..cd9a733 100644 --- a/lv_conf.h +++ b/lv_conf.h @@ -654,11 +654,11 @@ #define LV_FONT_MONTSERRAT_10 0 #define LV_FONT_MONTSERRAT_12 0 #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_20 0 +#define LV_FONT_MONTSERRAT_20 1 #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_28 0 #define LV_FONT_MONTSERRAT_30 0 diff --git a/src/ui/screen_base.h b/src/ui/screen_base.h new file mode 100644 index 0000000..b704685 --- /dev/null +++ b/src/ui/screen_base.h @@ -0,0 +1,53 @@ +#pragma once +#include + +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); + } +}; diff --git a/src/ui/widgets/back_button.cpp b/src/ui/widgets/back_button.cpp new file mode 100644 index 0000000..d8a89e9 --- /dev/null +++ b/src/ui/widgets/back_button.cpp @@ -0,0 +1,24 @@ +#include "back_button.h" +#include + +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; +} diff --git a/src/ui/widgets/back_button.h b/src/ui/widgets/back_button.h new file mode 100644 index 0000000..c230b01 --- /dev/null +++ b/src/ui/widgets/back_button.h @@ -0,0 +1,7 @@ +#pragma once +#include + +// 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); diff --git a/src/ui/widgets/tile_button.cpp b/src/ui/widgets/tile_button.cpp new file mode 100644 index 0000000..87366ca --- /dev/null +++ b/src/ui/widgets/tile_button.cpp @@ -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); +} diff --git a/src/ui/widgets/tile_button.h b/src/ui/widgets/tile_button.h new file mode 100644 index 0000000..566f942 --- /dev/null +++ b/src/ui/widgets/tile_button.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +// 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);