#include "ui.h" #include "lcd.h" #include "pins.h" #include #include #include static constexpr uint32_t COL_BG = 0x0A1016; static constexpr uint32_t COL_INK = 0xEAF0F6; static constexpr uint32_t COL_MUTED = 0x7A8B9C; static constexpr uint32_t COL_BTN = 0x243140; static constexpr uint32_t COL_ON = 0x1B5E4A; static constexpr uint32_t COL_ACCENT = 0x7CDBFF; static constexpr uint32_t COL_DIM = 0x3A4656; static constexpr uint32_t COL_ERR = 0xC62828; static constexpr uint32_t COL_WARN = 0xFFB74D; static lv_obj_t *lbl_title; static lv_obj_t *lbl_pin; static lv_obj_t *lbl_status; static lv_obj_t *lbl_hint; static lv_obj_t *lbl_line0; static lv_obj_t *lbl_line1; static lv_obj_t *btn_demo; static lv_obj_t *lbl_demo; static lv_obj_t *btn_hello; static lv_obj_t *btn_map; static lv_obj_t *lbl_map; static lv_obj_t *btn_bl; static lv_obj_t *lbl_bl; static uint8_t g_demo_idx = 0; static void style_btn(lv_obj_t *btn, uint32_t bg) { lv_obj_set_style_radius(btn, 10, 0); lv_obj_set_style_bg_color(btn, lv_color_hex(bg), 0); lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0); lv_obj_set_style_shadow_width(btn, 0, 0); lv_obj_set_style_border_width(btn, 0, 0); lv_obj_set_style_pad_all(btn, 0, 0); } static lv_obj_t *make_btn(lv_obj_t *parent, const char *txt, int16_t x, int16_t y, int16_t w, int16_t h, lv_event_cb_t cb, lv_obj_t **out_lbl) { lv_obj_t *btn = lv_button_create(parent); lv_obj_set_size(btn, w, h); lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x, y); style_btn(btn, COL_BTN); lv_obj_add_event_cb(btn, cb, LV_EVENT_CLICKED, nullptr); lv_obj_t *lbl = lv_label_create(btn); lv_label_set_text(lbl, txt); lv_obj_set_style_text_color(lbl, lv_color_hex(COL_INK), 0); lv_obj_set_style_text_font(lbl, &lv_font_montserrat_16, 0); lv_obj_center(lbl); if (out_lbl) { *out_lbl = lbl; } return btn; } void ui_refresh_lcd() { char l0[LCD_COLS + 1]; char l1[LCD_COLS + 1]; lcd_get_line(0, l0, sizeof(l0)); lcd_get_line(1, l1, sizeof(l1)); if (lbl_line0) { lv_label_set_text_fmt(lbl_line0, "[%s]", l0); } if (lbl_line1) { lv_label_set_text_fmt(lbl_line1, "[%s]", l1); } if (lbl_status) { if (lcd_ok()) { lv_label_set_text_fmt(lbl_status, "OK 0x%02X map%u", lcd_addr(), (unsigned)lcd_pinmap()); lv_obj_set_style_text_color(lbl_status, lv_color_hex(COL_ON), 0); } else { lv_label_set_text(lbl_status, "FAIL no PCF8574"); lv_obj_set_style_text_color(lbl_status, lv_color_hex(COL_ERR), 0); } } if (lbl_bl) { lv_label_set_text(lbl_bl, lcd_backlight() ? "BL OFF" : "BL ON"); } if (btn_bl) { style_btn(btn_bl, lcd_backlight() ? COL_ON : COL_DIM); } if (lbl_demo) { lv_label_set_text_fmt(lbl_demo, "Demo %u/%u", (unsigned)(g_demo_idx % lcd_demo_count() + 1), (unsigned)lcd_demo_count()); } if (lbl_map) { lv_label_set_text_fmt(lbl_map, "Map %u", (unsigned)lcd_pinmap()); } } static void on_demo(lv_event_t *e) { if (lv_event_get_code(e) != LV_EVENT_CLICKED) { return; } lcd_demo(g_demo_idx); g_demo_idx = (uint8_t)((g_demo_idx + 1) % lcd_demo_count()); ui_refresh_lcd(); } static void on_hello(lv_event_t *e) { if (lv_event_get_code(e) != LV_EVENT_CLICKED) { return; } lcd_set_backlight(true); lcd_set_line(0, "Hello World!"); lcd_set_line(1, "LCD1602A"); ui_refresh_lcd(); } static void on_map(lv_event_t *e) { if (lv_event_get_code(e) != LV_EVENT_CLICKED) { return; } lcd_set_pinmap((uint8_t)(lcd_pinmap() + 1)); lcd_set_backlight(true); lcd_set_line(0, "Hello World!"); lcd_set_line(1, "try Map / pot"); ui_refresh_lcd(); } static void on_bl(lv_event_t *e) { if (lv_event_get_code(e) != LV_EVENT_CLICKED) { return; } lcd_set_backlight(!lcd_backlight()); ui_refresh_lcd(); } void ui_create() { lv_obj_t *scr = lv_screen_active(); lv_obj_set_style_bg_color(scr, lv_color_hex(COL_BG), 0); lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0); lbl_title = lv_label_create(scr); lv_label_set_text(lbl_title, "LCD1602A"); lv_obj_set_style_text_color(lbl_title, lv_color_hex(COL_INK), 0); lv_obj_set_style_text_font(lbl_title, &lv_font_montserrat_28, 0); lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 2); lbl_pin = lv_label_create(scr); lv_label_set_text_fmt(lbl_pin, "I2C SDA%d SCL%d PCF8574", LCD_I2C_SDA_PIN, LCD_I2C_SCL_PIN); lv_obj_set_style_text_color(lbl_pin, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_pin, &lv_font_montserrat_14, 0); lv_obj_align(lbl_pin, LV_ALIGN_TOP_MID, 0, 32); lbl_status = lv_label_create(scr); lv_label_set_text(lbl_status, "..."); lv_obj_set_style_text_font(lbl_status, &lv_font_montserrat_14, 0); lv_obj_align(lbl_status, LV_ALIGN_TOP_MID, 0, 50); lbl_hint = lv_label_create(scr); lv_label_set_text(lbl_hint, "Blank? turn BLUE pot on backpack"); lv_obj_set_style_text_color(lbl_hint, lv_color_hex(COL_WARN), 0); lv_obj_set_style_text_font(lbl_hint, &lv_font_montserrat_14, 0); lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, 0, 68); lbl_line0 = lv_label_create(scr); lv_label_set_text(lbl_line0, "[ ]"); lv_obj_set_style_text_color(lbl_line0, lv_color_hex(COL_ACCENT), 0); lv_obj_set_style_text_font(lbl_line0, &lv_font_montserrat_18, 0); lv_obj_align(lbl_line0, LV_ALIGN_TOP_MID, 0, 90); lbl_line1 = lv_label_create(scr); lv_label_set_text(lbl_line1, "[ ]"); lv_obj_set_style_text_color(lbl_line1, lv_color_hex(COL_ACCENT), 0); lv_obj_set_style_text_font(lbl_line1, &lv_font_montserrat_18, 0); lv_obj_align(lbl_line1, LV_ALIGN_TOP_MID, 0, 116); const int16_t gap = 8; const int16_t bw = (UI_HOR_RES - 48 - gap) / 2; const int16_t bx0 = 24; const int16_t row0 = 148; const int16_t row1 = 196; btn_demo = make_btn(scr, "Demo", bx0, row0, bw, 40, on_demo, &lbl_demo); btn_hello = make_btn(scr, "Hello", bx0 + bw + gap, row0, bw, 40, on_hello, nullptr); btn_map = make_btn(scr, "Map 0", bx0, row1, bw, 40, on_map, &lbl_map); btn_bl = make_btn(scr, "BL OFF", bx0 + bw + gap, row1, bw, 40, on_bl, &lbl_bl); (void)btn_demo; (void)btn_hello; (void)btn_map; ui_refresh_lcd(); }