#include "ui.h" #include "pir.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_ACCENT = 0x4FC3F7; static constexpr uint32_t COL_HOT = 0xFF7043; static lv_obj_t *lbl_title; static lv_obj_t *lbl_pin; static lv_obj_t *lbl_count; static lv_obj_t *lbl_hint; static lv_obj_t *lbl_state; static lv_obj_t *lbl_hold; static lv_obj_t *lbl_raw; static lv_obj_t *bar_hold; static lv_obj_t *btn_reset; static lv_obj_t *lbl_reset; 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); } void ui_refresh() { if (lbl_count) { lv_label_set_text_fmt(lbl_count, "%lu", (unsigned long)pir_count()); } const bool active = pir_is_active(); const uint32_t hold = pir_hold_ms(); if (lbl_state) { lv_label_set_text(lbl_state, active ? "MOTION" : "IDLE"); lv_obj_set_style_text_color(lbl_state, lv_color_hex(active ? COL_HOT : COL_MUTED), 0); } if (lbl_hold) { if (active) { lv_label_set_text_fmt(lbl_hold, "hold %lu ms", (unsigned long)hold); } else { lv_label_set_text(lbl_hold, "hold --"); } } if (bar_hold) { // 条:0~5s 映射到 0~100,便于看保持时间 uint32_t pct = hold / 50; if (pct > 100) { pct = 100; } lv_bar_set_value(bar_hold, (int32_t)pct, LV_ANIM_OFF); lv_obj_set_style_bg_color(bar_hold, lv_color_hex(active ? COL_HOT : 0x1A2430), LV_PART_INDICATOR); } if (lbl_raw) { const int lv = pir_raw_level(); lv_label_set_text_fmt(lbl_raw, "OUT %s act=%s", lv ? "HIGH" : "LOW", pir_active_level() ? "HIGH" : "LOW"); lv_obj_set_style_text_color(lbl_raw, lv_color_hex(lv ? 0x3DDC97 : COL_MUTED), 0); } } static void on_reset(lv_event_t *e) { if (lv_event_get_code(e) != LV_EVENT_CLICKED) { return; } pir_reset_count(); ui_refresh(); } 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, "Human IR"); 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, "OUT->GPIO%d VCC 3.3V", PIR_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_count = lv_label_create(scr); lv_label_set_text(lbl_count, "0"); lv_obj_set_style_text_color(lbl_count, lv_color_hex(COL_ACCENT), 0); lv_obj_set_style_text_font(lbl_count, &lv_font_montserrat_28, 0); lv_obj_align(lbl_count, LV_ALIGN_TOP_MID, 0, 54); lbl_hint = lv_label_create(scr); lv_label_set_text(lbl_hint, "detects"); lv_obj_set_style_text_color(lbl_hint, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_hint, &lv_font_montserrat_14, 0); lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, 0, 88); lbl_state = lv_label_create(scr); lv_label_set_text(lbl_state, "IDLE"); lv_obj_set_style_text_color(lbl_state, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_state, &lv_font_montserrat_20, 0); lv_obj_align(lbl_state, LV_ALIGN_TOP_MID, 0, 108); lbl_hold = lv_label_create(scr); lv_label_set_text(lbl_hold, "hold --"); lv_obj_set_style_text_color(lbl_hold, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_hold, &lv_font_montserrat_14, 0); lv_obj_align(lbl_hold, LV_ALIGN_TOP_MID, 0, 132); bar_hold = lv_bar_create(scr); lv_obj_set_size(bar_hold, UI_HOR_RES - 48, 10); lv_obj_align(bar_hold, LV_ALIGN_TOP_MID, 0, 152); lv_bar_set_range(bar_hold, 0, 100); lv_bar_set_value(bar_hold, 0, LV_ANIM_OFF); lv_obj_set_style_bg_color(bar_hold, lv_color_hex(0x1A2430), LV_PART_MAIN); lv_obj_set_style_bg_opa(bar_hold, LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_radius(bar_hold, 4, LV_PART_MAIN); lv_obj_set_style_bg_color(bar_hold, lv_color_hex(COL_HOT), LV_PART_INDICATOR); lv_obj_set_style_radius(bar_hold, 4, LV_PART_INDICATOR); lbl_raw = lv_label_create(scr); lv_label_set_text(lbl_raw, "OUT --"); lv_obj_set_style_text_color(lbl_raw, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_raw, &lv_font_montserrat_14, 0); lv_obj_align(lbl_raw, LV_ALIGN_TOP_MID, 0, 168); btn_reset = lv_button_create(scr); lv_obj_set_size(btn_reset, UI_HOR_RES - 48, 40); lv_obj_align(btn_reset, LV_ALIGN_TOP_MID, 0, 192); style_btn(btn_reset, COL_BTN); lv_obj_add_event_cb(btn_reset, on_reset, LV_EVENT_CLICKED, nullptr); lbl_reset = lv_label_create(btn_reset); lv_label_set_text(lbl_reset, "Reset"); lv_obj_set_style_text_color(lbl_reset, lv_color_hex(COL_INK), 0); lv_obj_set_style_text_font(lbl_reset, &lv_font_montserrat_20, 0); lv_obj_center(lbl_reset); ui_refresh(); }