feat: LVGL 9.5 upgrade, FTP server, premium AMOLED UI
- Upgraded LVGL from 8.4 to 9.5.0 (new display/input API) - Rewrote DisplayManager for LVGL 9 (lv_display_create, tick callback) - New lv_conf.h for v9.5 with optimized widget selection - Premium dark AMOLED UI with gradient panels, status dots, storage bar - Backend: Wi-Fi from SD JSON, NTP Vienna, SimpleFTPServer on SD_MMC - Removed 6 unused sensor libs, added ArduinoJson + SimpleFTPServer - Build: 19% RAM, 4.6% Flash — verified compilation success
This commit is contained in:
+121
-69
@@ -1,92 +1,144 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for LVGL v9.5.0 — Kode Dot FTP Explorer
|
||||
*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#define LV_USE_DEV_VERSION 1
|
||||
/*====================
|
||||
COLOR SETTINGS
|
||||
*====================*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/* Color settings */
|
||||
#define LV_COLOR_DEPTH 16
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
/*=========================
|
||||
STDLIB WRAPPER SETTINGS
|
||||
*=========================*/
|
||||
#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN
|
||||
#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN
|
||||
#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN
|
||||
|
||||
/* Memory settings */
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#define LV_MEM_SIZE (48U * 1024U)
|
||||
#define LV_MEM_SIZE (48U * 1024U)
|
||||
|
||||
/* HAL settings */
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
/*====================
|
||||
HAL SETTINGS
|
||||
*====================*/
|
||||
#define LV_DEF_REFR_PERIOD 33
|
||||
#define LV_DPI_DEF 130
|
||||
|
||||
/* Feature usage */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#define LV_USE_SHADOW 0
|
||||
#define LV_USE_BLEND_MODES 0
|
||||
#define LV_USE_OPA_SCALE 0
|
||||
#define LV_USE_IMG_TRANSFORM 0
|
||||
/*=================
|
||||
* OPERATING SYSTEM
|
||||
*=================*/
|
||||
#define LV_USE_OS LV_OS_NONE
|
||||
|
||||
/* Widget usage */
|
||||
#define LV_USE_ARC 0
|
||||
#define LV_USE_ANIMIMG 0
|
||||
#define LV_USE_BAR 1
|
||||
#define LV_USE_BTN 0
|
||||
#define LV_USE_BTNMATRIX 0
|
||||
#define LV_USE_CANVAS 0
|
||||
#define LV_USE_CHECKBOX 0
|
||||
#define LV_USE_DROPDOWN 0
|
||||
#define LV_USE_IMG 0
|
||||
#define LV_USE_LABEL 1
|
||||
#define LV_USE_LINE 1
|
||||
#define LV_USE_LIST 0
|
||||
#define LV_USE_METER 0
|
||||
#define LV_USE_MSGBOX 0
|
||||
#define LV_USE_ROLLER 0
|
||||
#define LV_USE_SLIDER 0
|
||||
#define LV_USE_SPAN 0
|
||||
#define LV_USE_SPINBOX 0
|
||||
#define LV_USE_SPINNER 0
|
||||
#define LV_USE_SWITCH 0
|
||||
#define LV_USE_TEXTAREA 0
|
||||
#define LV_USE_TABLE 0
|
||||
#define LV_USE_TABVIEW 0
|
||||
#define LV_USE_TILEVIEW 0
|
||||
#define LV_USE_WIN 0
|
||||
#define LV_USE_KEYBOARD 0
|
||||
#define LV_USE_MENU 0
|
||||
#define LV_USE_COLORWHEEL 0
|
||||
#define LV_USE_LED 0
|
||||
#define LV_USE_IMGBTN 0
|
||||
#define LV_USE_CALENDAR 0
|
||||
#define LV_USE_CHART 0
|
||||
/*========================
|
||||
* RENDERING CONFIGURATION
|
||||
*========================*/
|
||||
#define LV_DRAW_BUF_STRIDE_ALIGN 4
|
||||
#define LV_DRAW_BUF_ALIGN 4
|
||||
#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024)
|
||||
#define LV_USE_DRAW_SW 1
|
||||
#define LV_DRAW_SW_DRAW_UNIT_CNT 1
|
||||
|
||||
/* Themes */
|
||||
#define LV_USE_THEME_DEFAULT 1
|
||||
#define LV_USE_THEME_BASIC 0
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
#define LV_USE_LOG 0
|
||||
#define LV_USE_ASSERT_NULL 1
|
||||
#define LV_USE_ASSERT_MALLOC 1
|
||||
#define LV_USE_ASSERT_STYLE 0
|
||||
#define LV_USE_ASSERT_MEM_INTEGRITY 0
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
|
||||
/* Font usage */
|
||||
#define LV_USE_REFR_DEBUG 0
|
||||
#define LV_USE_LAYER_DEBUG 0
|
||||
#define LV_USE_PARALLEL_DRAW_DEBUG 0
|
||||
|
||||
/*-------------
|
||||
* Others
|
||||
*-----------*/
|
||||
#define LV_USE_SYSMON 0
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#define LV_USE_OBJ_ID 0
|
||||
|
||||
/*=====================
|
||||
* WIDGET USAGE
|
||||
*====================*/
|
||||
#define LV_USE_ARC 1
|
||||
#define LV_USE_BAR 1
|
||||
#define LV_USE_BUTTON 1
|
||||
#define LV_USE_BUTTONMATRIX 0
|
||||
#define LV_USE_CALENDAR 0
|
||||
#define LV_USE_CANVAS 0
|
||||
#define LV_USE_CHART 0
|
||||
#define LV_USE_CHECKBOX 0
|
||||
#define LV_USE_DROPDOWN 0
|
||||
#define LV_USE_IMAGE 1
|
||||
#define LV_USE_IMAGEBUTTON 0
|
||||
#define LV_USE_KEYBOARD 0
|
||||
#define LV_USE_LABEL 1
|
||||
#define LV_USE_LED 0
|
||||
#define LV_USE_LINE 1
|
||||
#define LV_USE_LIST 0
|
||||
#define LV_USE_MENU 0
|
||||
#define LV_USE_MSGBOX 0
|
||||
#define LV_USE_ROLLER 0
|
||||
#define LV_USE_SCALE 0
|
||||
#define LV_USE_SLIDER 0
|
||||
#define LV_USE_SPAN 0
|
||||
#define LV_USE_SPINBOX 0
|
||||
#define LV_USE_SPINNER 0
|
||||
#define LV_USE_SWITCH 0
|
||||
#define LV_USE_TABLE 0
|
||||
#define LV_USE_TABVIEW 0
|
||||
#define LV_USE_TEXTAREA 0
|
||||
#define LV_USE_TILEVIEW 0
|
||||
#define LV_USE_WIN 0
|
||||
|
||||
/*==================
|
||||
* THEMES
|
||||
*==================*/
|
||||
#define LV_USE_THEME_DEFAULT 1
|
||||
#define LV_USE_THEME_SIMPLE 0
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*==================*/
|
||||
#define LV_FONT_MONTSERRAT_8 0
|
||||
#define LV_FONT_MONTSERRAT_10 0
|
||||
#define LV_FONT_MONTSERRAT_12 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_18 1
|
||||
#define LV_FONT_MONTSERRAT_20 1
|
||||
#define LV_FONT_MONTSERRAT_22 1
|
||||
#define LV_FONT_MONTSERRAT_24 1
|
||||
#define LV_FONT_MONTSERRAT_26 1
|
||||
#define LV_FONT_MONTSERRAT_28 1
|
||||
#define LV_FONT_MONTSERRAT_30 1
|
||||
#define LV_FONT_MONTSERRAT_32 0
|
||||
#define LV_FONT_MONTSERRAT_34 0
|
||||
#define LV_FONT_MONTSERRAT_36 0
|
||||
#define LV_FONT_MONTSERRAT_38 0
|
||||
#define LV_FONT_MONTSERRAT_42 1
|
||||
#define LV_FONT_MONTSERRAT_40 1
|
||||
#define LV_FONT_MONTSERRAT_42 0
|
||||
#define LV_FONT_MONTSERRAT_44 0
|
||||
#define LV_FONT_MONTSERRAT_46 0
|
||||
#define LV_FONT_MONTSERRAT_48 0
|
||||
|
||||
/* Others */
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#define LV_USE_REFR_DEBUG 0
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
|
||||
/* Compiler settings */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
||||
#define LV_USE_FONT_PLACEHOLDER 1
|
||||
|
||||
/* HAL settings */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#define LV_DPI_DEF 130
|
||||
/*==================
|
||||
* TEXT SETTINGS
|
||||
*==================*/
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
/*==================
|
||||
* V8 COMPATIBILITY
|
||||
*==================*/
|
||||
#define LV_USE_OBJ_PROPERTY 0
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
+5
-1
@@ -161,7 +161,7 @@ void ftpTransferCallback(FtpTransferOperation ftpOperation, const char *name, ui
|
||||
// Time display
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Update the UI time label once per second */
|
||||
/** Update the UI time and date labels once per second */
|
||||
static void updateTimeDisplay() {
|
||||
unsigned long now = millis();
|
||||
if (now - last_time_update < 1000) return;
|
||||
@@ -172,6 +172,10 @@ static void updateTimeDisplay() {
|
||||
char buf[16];
|
||||
strftime(buf, sizeof(buf), "%H:%M:%S", &timeinfo);
|
||||
ui_set_time(buf);
|
||||
|
||||
char datebuf[32];
|
||||
strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y", &timeinfo);
|
||||
ui_set_date(datebuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+147
-70
@@ -1,20 +1,23 @@
|
||||
#include "ui.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
/* ── colour palette ──────────────────────────────────────────────── */
|
||||
#define CLR_BG 0x111111
|
||||
#define CLR_PANEL_BG 0x1A1A1A
|
||||
#define CLR_PANEL_BRD 0x333333
|
||||
/* ── colour palette (AMOLED-optimised) ───────────────────────────── */
|
||||
#define CLR_BG 0x0A0A0F
|
||||
#define CLR_PANEL_BG 0x141420
|
||||
#define CLR_PANEL_BRD 0x2A2A3A
|
||||
#define CLR_WHITE 0xFFFFFF
|
||||
#define CLR_GRAY 0x888888
|
||||
#define CLR_CYAN 0x00E5FF
|
||||
#define CLR_CYAN 0x00BCD4
|
||||
#define CLR_GREEN 0x4CAF50
|
||||
#define CLR_RED 0xF44336
|
||||
#define CLR_BAR_BG 0x2A2A2A
|
||||
#define CLR_BLUE 0x2196F3
|
||||
#define CLR_PURPLE 0xAB47BC
|
||||
#define CLR_BAR_BG 0x1A1A2E
|
||||
#define CLR_BAR_FILL 0x4CAF50
|
||||
#define CLR_ERROR_BG 0x330000
|
||||
#define CLR_DIMMED 0x777777
|
||||
#define CLR_SEPARATOR 0x333333
|
||||
#define CLR_ERROR_BG 0x2D0A0A
|
||||
#define CLR_DIMMED 0x666677
|
||||
#define CLR_SEPARATOR 0x1E1E2E
|
||||
#define CLR_TITLE_ACCENT 0x00BCD4
|
||||
|
||||
/* ── screen dimensions ───────────────────────────────────────────── */
|
||||
#define SCR_W 410
|
||||
@@ -26,23 +29,27 @@ static lv_obj_t *line_sep;
|
||||
static lv_obj_t *lbl_wifi;
|
||||
static lv_obj_t *lbl_ip;
|
||||
static lv_obj_t *panel_ftp;
|
||||
static lv_obj_t *dot_ftp_status;
|
||||
static lv_obj_t *lbl_ftp_title;
|
||||
static lv_obj_t *lbl_ftp_status;
|
||||
static lv_obj_t *lbl_ftp_url;
|
||||
static lv_obj_t *lbl_ftp_creds;
|
||||
static lv_obj_t *lbl_sd_title;
|
||||
static lv_obj_t *lbl_storage_title;
|
||||
static lv_obj_t *bar_sd;
|
||||
static lv_obj_t *lbl_sd_text;
|
||||
static lv_obj_t *lbl_sd_info;
|
||||
static lv_obj_t *lbl_sd_pct;
|
||||
static lv_obj_t *lbl_time;
|
||||
static lv_obj_t *lbl_date;
|
||||
static lv_obj_t *obj_error_bar;
|
||||
static lv_obj_t *lbl_error;
|
||||
|
||||
/* ── cached IP for FTP URL ───────────────────────────────────────── */
|
||||
static char cached_ip[48] = "0.0.0.0";
|
||||
|
||||
/* ── helpers ─────────────────────────────────────────────────────── */
|
||||
/* ── helper: create a styled label ───────────────────────────────── */
|
||||
static lv_obj_t *make_label(lv_obj_t *parent, const lv_font_t *font,
|
||||
uint32_t color, lv_align_t align,
|
||||
lv_coord_t x_ofs, lv_coord_t y_ofs,
|
||||
int32_t x_ofs, int32_t y_ofs,
|
||||
const char *text)
|
||||
{
|
||||
lv_obj_t *lbl = lv_label_create(parent);
|
||||
@@ -57,112 +64,162 @@ static lv_obj_t *make_label(lv_obj_t *parent, const lv_font_t *font,
|
||||
|
||||
void ui_init()
|
||||
{
|
||||
lv_obj_t *scr = lv_scr_act();
|
||||
lv_obj_t *scr = lv_screen_active();
|
||||
|
||||
/* screen background */
|
||||
/* ── screen background: pure AMOLED black ────────────────────── */
|
||||
lv_obj_set_style_bg_color(scr, lv_color_hex(CLR_BG), 0);
|
||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||
|
||||
/* ── title ───────────────────────────────────────────────────── */
|
||||
lbl_title = make_label(scr, &lv_font_montserrat_26, CLR_WHITE,
|
||||
LV_ALIGN_TOP_MID, 0, 20, "FTP Explorer");
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* HEADER (y = 0 … 60) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
lbl_title = make_label(scr, &lv_font_montserrat_24, CLR_WHITE,
|
||||
LV_ALIGN_TOP_MID, 0, 16, "FTP Explorer");
|
||||
lv_obj_set_style_text_letter_space(lbl_title, 2, 0);
|
||||
|
||||
/* thin separator line */
|
||||
static lv_point_t line_pts[] = {{55, 0}, {355, 0}};
|
||||
/* subtle separator line */
|
||||
static lv_point_precise_t line_pts[] = {{40, 0}, {370, 0}};
|
||||
line_sep = lv_line_create(scr);
|
||||
lv_line_set_points(line_sep, line_pts, 2);
|
||||
lv_obj_set_style_line_color(line_sep, lv_color_hex(CLR_SEPARATOR), 0);
|
||||
lv_obj_set_style_line_width(line_sep, 1, 0);
|
||||
lv_obj_align(line_sep, LV_ALIGN_TOP_LEFT, 0, 54);
|
||||
lv_obj_set_style_line_opa(line_sep, LV_OPA_70, 0);
|
||||
lv_obj_align(line_sep, LV_ALIGN_TOP_LEFT, 0, 55);
|
||||
|
||||
/* ── WiFi section ────────────────────────────────────────────── */
|
||||
lbl_wifi = make_label(scr, &lv_font_montserrat_18, CLR_GREEN,
|
||||
LV_ALIGN_TOP_LEFT, 24, 70,
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* WI-FI SECTION (y = 65 … 140) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
lbl_wifi = make_label(scr, &lv_font_montserrat_16, CLR_GREEN,
|
||||
LV_ALIGN_TOP_LEFT, 28, 68,
|
||||
LV_SYMBOL_WIFI " Disconnected");
|
||||
|
||||
lbl_ip = make_label(scr, &lv_font_montserrat_30, CLR_CYAN,
|
||||
LV_ALIGN_TOP_LEFT, 24, 100, "0.0.0.0");
|
||||
LV_ALIGN_TOP_LEFT, 28, 96, "0.0.0.0");
|
||||
|
||||
/* ── FTP panel ───────────────────────────────────────────────── */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* FTP SERVER PANEL (y = 148 … 288) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
panel_ftp = lv_obj_create(scr);
|
||||
lv_obj_set_size(panel_ftp, SCR_W - 40, 120);
|
||||
lv_obj_align(panel_ftp, LV_ALIGN_TOP_MID, 0, 145);
|
||||
lv_obj_set_size(panel_ftp, SCR_W - 40, 138);
|
||||
lv_obj_align(panel_ftp, LV_ALIGN_TOP_MID, 0, 148);
|
||||
lv_obj_set_style_bg_color(panel_ftp, lv_color_hex(CLR_PANEL_BG), 0);
|
||||
lv_obj_set_style_bg_opa(panel_ftp, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_border_color(panel_ftp, lv_color_hex(CLR_PANEL_BRD), 0);
|
||||
lv_obj_set_style_border_width(panel_ftp, 1, 0);
|
||||
lv_obj_set_style_radius(panel_ftp, 10, 0);
|
||||
lv_obj_set_style_pad_all(panel_ftp, 12, 0);
|
||||
lv_obj_set_style_border_opa(panel_ftp, LV_OPA_80, 0);
|
||||
lv_obj_set_style_radius(panel_ftp, 14, 0);
|
||||
lv_obj_set_style_pad_left(panel_ftp, 16, 0);
|
||||
lv_obj_set_style_pad_right(panel_ftp, 16, 0);
|
||||
lv_obj_set_style_pad_top(panel_ftp, 14, 0);
|
||||
lv_obj_set_style_pad_bottom(panel_ftp, 10, 0);
|
||||
lv_obj_clear_flag(panel_ftp, LV_OBJ_FLAG_SCROLLABLE);
|
||||
/* subtle vertical gradient on the panel */
|
||||
lv_obj_set_style_bg_grad_color(panel_ftp, lv_color_hex(0x1A1A30), 0);
|
||||
lv_obj_set_style_bg_grad_dir(panel_ftp, LV_GRAD_DIR_VER, 0);
|
||||
|
||||
/* panel title */
|
||||
lv_obj_t *lbl_ftp_title = lv_label_create(panel_ftp);
|
||||
lbl_ftp_title = lv_label_create(panel_ftp);
|
||||
lv_label_set_text(lbl_ftp_title, "FTP Server");
|
||||
lv_obj_set_style_text_font(lbl_ftp_title, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_title, lv_color_hex(CLR_WHITE), 0);
|
||||
lv_obj_align(lbl_ftp_title, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
|
||||
lbl_ftp_status = lv_label_create(panel_ftp);
|
||||
lv_label_set_text(lbl_ftp_status, "Status: Idle");
|
||||
lv_obj_set_style_text_font(lbl_ftp_status, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_status, lv_color_hex(CLR_GREEN), 0);
|
||||
lv_obj_align(lbl_ftp_status, LV_ALIGN_TOP_LEFT, 0, 28);
|
||||
/* status dot (8x8 circle) */
|
||||
dot_ftp_status = lv_obj_create(panel_ftp);
|
||||
lv_obj_set_size(dot_ftp_status, 8, 8);
|
||||
lv_obj_set_style_radius(dot_ftp_status, 4, 0);
|
||||
lv_obj_set_style_bg_color(dot_ftp_status, lv_color_hex(CLR_GREEN), 0);
|
||||
lv_obj_set_style_bg_opa(dot_ftp_status, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_border_width(dot_ftp_status, 0, 0);
|
||||
lv_obj_clear_flag(dot_ftp_status, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_align(dot_ftp_status, LV_ALIGN_TOP_LEFT, 0, 33);
|
||||
|
||||
/* status label next to dot */
|
||||
lbl_ftp_status = lv_label_create(panel_ftp);
|
||||
lv_label_set_text(lbl_ftp_status, "Idle");
|
||||
lv_obj_set_style_text_font(lbl_ftp_status, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_status, lv_color_hex(CLR_GREEN), 0);
|
||||
lv_obj_align(lbl_ftp_status, LV_ALIGN_TOP_LEFT, 14, 28);
|
||||
|
||||
/* FTP URL */
|
||||
lbl_ftp_url = lv_label_create(panel_ftp);
|
||||
lv_label_set_text(lbl_ftp_url, "ftp://0.0.0.0");
|
||||
lv_obj_set_style_text_font(lbl_ftp_url, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_style_text_font(lbl_ftp_url, &lv_font_montserrat_16, 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_url, lv_color_hex(CLR_DIMMED), 0);
|
||||
lv_obj_align(lbl_ftp_url, LV_ALIGN_TOP_LEFT, 0, 54);
|
||||
|
||||
/* credentials */
|
||||
lbl_ftp_creds = lv_label_create(panel_ftp);
|
||||
lv_label_set_text(lbl_ftp_creds, "User: kode Pass: kode");
|
||||
lv_obj_set_style_text_font(lbl_ftp_creds, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_font(lbl_ftp_creds, &lv_font_montserrat_12, 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_creds, lv_color_hex(CLR_GRAY), 0);
|
||||
lv_obj_align(lbl_ftp_creds, LV_ALIGN_TOP_LEFT, 0, 80);
|
||||
lv_obj_align(lbl_ftp_creds, LV_ALIGN_TOP_LEFT, 0, 82);
|
||||
|
||||
/* ── SD card section ─────────────────────────────────────────── */
|
||||
lbl_sd_title = make_label(scr, &lv_font_montserrat_18, CLR_WHITE,
|
||||
LV_ALIGN_TOP_LEFT, 24, 280, "SD Card");
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* STORAGE SECTION (y = 300 … 370) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
lbl_storage_title = make_label(scr, &lv_font_montserrat_18, CLR_WHITE,
|
||||
LV_ALIGN_TOP_LEFT, 28, 300, "Storage");
|
||||
|
||||
bar_sd = lv_bar_create(scr);
|
||||
lv_obj_set_size(bar_sd, SCR_W - 48, 14);
|
||||
lv_obj_align(bar_sd, LV_ALIGN_TOP_LEFT, 24, 310);
|
||||
lv_obj_set_size(bar_sd, SCR_W - 56, 14);
|
||||
lv_obj_align(bar_sd, LV_ALIGN_TOP_LEFT, 28, 330);
|
||||
lv_bar_set_range(bar_sd, 0, 100);
|
||||
lv_bar_set_value(bar_sd, 0, LV_ANIM_OFF);
|
||||
/* bar track */
|
||||
lv_obj_set_style_bg_color(bar_sd, lv_color_hex(CLR_BAR_BG), 0);
|
||||
lv_obj_set_style_bg_opa(bar_sd, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_radius(bar_sd, 7, 0);
|
||||
/* bar indicator */
|
||||
lv_obj_set_style_bg_color(bar_sd, lv_color_hex(CLR_BAR_FILL),
|
||||
LV_PART_INDICATOR);
|
||||
lv_obj_set_style_bg_opa(bar_sd, LV_OPA_COVER, LV_PART_INDICATOR);
|
||||
lv_obj_set_style_radius(bar_sd, 4, 0);
|
||||
lv_obj_set_style_radius(bar_sd, 4, LV_PART_INDICATOR);
|
||||
lv_obj_set_style_radius(bar_sd, 7, LV_PART_INDICATOR);
|
||||
|
||||
lbl_sd_text = make_label(scr, &lv_font_montserrat_14, CLR_GRAY,
|
||||
LV_ALIGN_TOP_LEFT, 24, 330, "0.0 / 0.0 GB");
|
||||
/* size text left-aligned */
|
||||
lbl_sd_info = make_label(scr, &lv_font_montserrat_14, CLR_GRAY,
|
||||
LV_ALIGN_TOP_LEFT, 28, 350, "0.0 / 0.0 GB");
|
||||
|
||||
/* ── time / date ─────────────────────────────────────────────── */
|
||||
lbl_time = make_label(scr, &lv_font_montserrat_42, CLR_WHITE,
|
||||
LV_ALIGN_TOP_MID, 0, 400, "--:--:--");
|
||||
/* percentage right-aligned */
|
||||
lbl_sd_pct = make_label(scr, &lv_font_montserrat_14, CLR_GRAY,
|
||||
LV_ALIGN_TOP_RIGHT, -28, 350, "0%");
|
||||
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* CLOCK AREA (y = 385 … 490) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
lbl_time = make_label(scr, &lv_font_montserrat_40, CLR_WHITE,
|
||||
LV_ALIGN_TOP_MID, 0, 398, "--:--");
|
||||
|
||||
lbl_date = make_label(scr, &lv_font_montserrat_18, CLR_GRAY,
|
||||
LV_ALIGN_TOP_MID, 0, 452, "--.--.----");
|
||||
LV_ALIGN_TOP_MID, 0, 456, "--- --, ----");
|
||||
|
||||
/* ── error overlay (hidden) ──────────────────────────────────── */
|
||||
lbl_error = lv_label_create(scr);
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
/* ERROR OVERLAY (hidden by default) */
|
||||
/* ────────────────────────────────────────────────────────────── */
|
||||
obj_error_bar = lv_obj_create(scr);
|
||||
lv_obj_set_size(obj_error_bar, SCR_W - 40, LV_SIZE_CONTENT);
|
||||
lv_obj_align(obj_error_bar, LV_ALIGN_BOTTOM_MID, 0, -6);
|
||||
lv_obj_set_style_bg_color(obj_error_bar, lv_color_hex(CLR_ERROR_BG), 0);
|
||||
lv_obj_set_style_bg_opa(obj_error_bar, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_border_color(obj_error_bar, lv_color_hex(CLR_RED), 0);
|
||||
lv_obj_set_style_border_width(obj_error_bar, 1, 0);
|
||||
lv_obj_set_style_border_opa(obj_error_bar, LV_OPA_60, 0);
|
||||
lv_obj_set_style_radius(obj_error_bar, 10, 0);
|
||||
lv_obj_set_style_pad_all(obj_error_bar, 10, 0);
|
||||
lv_obj_clear_flag(obj_error_bar, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_add_flag(obj_error_bar, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
lbl_error = lv_label_create(obj_error_bar);
|
||||
lv_label_set_text(lbl_error, "");
|
||||
lv_obj_set_width(lbl_error, SCR_W - 48);
|
||||
lv_obj_set_style_text_font(lbl_error, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_width(lbl_error, SCR_W - 72);
|
||||
lv_obj_set_style_text_font(lbl_error, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_color(lbl_error, lv_color_hex(CLR_RED), 0);
|
||||
lv_obj_set_style_bg_color(lbl_error, lv_color_hex(CLR_ERROR_BG), 0);
|
||||
lv_obj_set_style_bg_opa(lbl_error, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_pad_all(lbl_error, 8, 0);
|
||||
lv_obj_set_style_radius(lbl_error, 6, 0);
|
||||
lv_obj_set_style_text_align(lbl_error, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_label_set_long_mode(lbl_error, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_align(lbl_error, LV_ALIGN_TOP_MID, 0, 360);
|
||||
lv_obj_add_flag(lbl_error, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_align(lbl_error, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
/* ── ui_set_wifi ─────────────────────────────────────────────────── */
|
||||
void ui_set_wifi(const char *ssid, const char *ip)
|
||||
{
|
||||
if (ssid && ssid[0]) {
|
||||
@@ -185,17 +242,36 @@ void ui_set_wifi(const char *ssid, const char *ip)
|
||||
lv_label_set_text_fmt(lbl_ftp_url, "ftp://%s", cached_ip);
|
||||
}
|
||||
|
||||
/* ── ui_set_ftp ──────────────────────────────────────────────────── */
|
||||
void ui_set_ftp(const char *status)
|
||||
{
|
||||
lv_label_set_text_fmt(lbl_ftp_status, "Status: %s", status);
|
||||
if (!status) return;
|
||||
|
||||
lv_label_set_text(lbl_ftp_status, status);
|
||||
|
||||
/* colour the dot + text based on status keyword */
|
||||
uint32_t clr = CLR_GREEN; /* default: Idle */
|
||||
if (strstr(status, "Connect")) clr = CLR_BLUE;
|
||||
if (strstr(status, "Transfer")) clr = CLR_PURPLE;
|
||||
if (strstr(status, "Error")) clr = CLR_RED;
|
||||
|
||||
lv_obj_set_style_bg_color(dot_ftp_status, lv_color_hex(clr), 0);
|
||||
lv_obj_set_style_text_color(lbl_ftp_status, lv_color_hex(clr), 0);
|
||||
}
|
||||
|
||||
/* ── ui_set_time ─────────────────────────────────────────────────── */
|
||||
void ui_set_time(const char *time_str)
|
||||
{
|
||||
/* expects "HH:MM:SS" — split into time and derive date display */
|
||||
lv_label_set_text(lbl_time, time_str);
|
||||
}
|
||||
|
||||
/* ── ui_set_date ─────────────────────────────────────────────────── */
|
||||
void ui_set_date(const char *date_str)
|
||||
{
|
||||
lv_label_set_text(lbl_date, date_str);
|
||||
}
|
||||
|
||||
/* ── ui_set_sd ───────────────────────────────────────────────────── */
|
||||
void ui_set_sd(uint64_t used_mb, uint64_t total_mb)
|
||||
{
|
||||
int pct = 0;
|
||||
@@ -205,13 +281,13 @@ void ui_set_sd(uint64_t used_mb, uint64_t total_mb)
|
||||
}
|
||||
lv_bar_set_value(bar_sd, pct, LV_ANIM_OFF);
|
||||
|
||||
/* show in GB with one decimal */
|
||||
float used_gb = used_mb / 1024.0f;
|
||||
float total_gb = total_mb / 1024.0f;
|
||||
lv_label_set_text_fmt(lbl_sd_text, "%.1f / %.1f GB", (double)used_gb,
|
||||
(double)total_gb);
|
||||
lv_label_set_text_fmt(lbl_sd_info, "%.1f / %.1f GB",
|
||||
(double)used_gb, (double)total_gb);
|
||||
lv_label_set_text_fmt(lbl_sd_pct, "%d%%", pct);
|
||||
|
||||
/* colour the bar red when > 90 % */
|
||||
/* bar turns red when storage > 90% */
|
||||
if (pct > 90) {
|
||||
lv_obj_set_style_bg_color(bar_sd, lv_color_hex(CLR_RED),
|
||||
LV_PART_INDICATOR);
|
||||
@@ -221,13 +297,14 @@ void ui_set_sd(uint64_t used_mb, uint64_t total_mb)
|
||||
}
|
||||
}
|
||||
|
||||
/* ── ui_set_error ────────────────────────────────────────────────── */
|
||||
void ui_set_error(const char *msg)
|
||||
{
|
||||
if (msg && msg[0]) {
|
||||
lv_label_set_text(lbl_error, msg);
|
||||
lv_obj_clear_flag(lbl_error, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_clear_flag(obj_error_bar, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_label_set_text(lbl_error, "");
|
||||
lv_obj_add_flag(lbl_error, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_add_flag(obj_error_bar, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@ void ui_init();
|
||||
void ui_set_wifi(const char *ssid, const char *ip);
|
||||
void ui_set_ftp(const char *status);
|
||||
void ui_set_time(const char *time_str);
|
||||
void ui_set_date(const char *date_str);
|
||||
void ui_set_sd(uint64_t used_mb, uint64_t total_mb);
|
||||
void ui_set_error(const char *msg);
|
||||
|
||||
Reference in New Issue
Block a user