// This file was generated by SquareLine Studio // SquareLine Studio version: SquareLine Studio 1.6.0 // LVGL version: 8.3.11 // Project name: Lcd_Pro #include "../ui.h" #include "ui_ScreenImg.h" // 用于调用 ui_ScreenImg_show_delete_container #include "../../pages/include/pages.h" #include "../../sleep_mgr/include/sleep_mgr.h" #include "esp_lvgl_port.h" // LVGL锁机制 #include "esp_timer.h" #include "esp_log.h" #include "dzbj_button.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" lv_obj_t *ui_ScreenSet = NULL;lv_obj_t *ui_GlobalContainer = NULL;lv_obj_t *ui_ContainerTop = NULL;lv_obj_t *ui_ImgLowPower = NULL;lv_obj_t *ui_ImgFlashlight = NULL;lv_obj_t *ui_ImgDelete = NULL;lv_obj_t *ui_ContainerCentral = NULL;lv_obj_t *ui_SliderBrightness = NULL;lv_obj_t *ui_ImgSun = NULL;lv_obj_t *ui_LabelBrightness = NULL;lv_obj_t *ui_ArcPowerLevel = NULL;lv_obj_t *ui_ImgLightning = NULL;lv_obj_t *ui_LabelPowerLevel = NULL; // 记录从哪个界面进入ScreenSet(用于返回) static lv_obj_t **previous_screen = NULL; static void (*previous_screen_init)(void) = NULL; // 设置前一个界面(在切换到ScreenSet前调用) void ui_ScreenSet_set_previous(lv_obj_t **screen, void (*init_func)(void)) { previous_screen = screen; previous_screen_init = init_func; } // ==================== 应援灯功能 ==================== // 行为:进入时高亮常亮 → 点击屏幕切换闪烁/常亮 → 下滑切换颜色 // 颜色切换使用直接 DMA 填充 GRAM(绕过 LVGL),约 27ms 瞬间完成 #include "lcd.h" #include "esp_heap_caps.h" static lv_obj_t *flashlight_overlay = NULL; // 全屏遮罩层 static lv_timer_t *flashlight_timer = NULL; // 闪烁定时器 static uint8_t flashlight_color_index = 0; // 当前颜色索引 static bool flashlight_bright = true; // 当前亮度状态(true=亮,false=暗) static bool flashlight_blinking = false; // 是否处于闪烁状态 static uint8_t saved_brightness = 50; // 进入前保存的亮度 // DMA 缓冲区(应援灯生命周期内常驻,避免反复 malloc/free) // 条带越大,条数越少,总传输时间越短,撕裂概率越低 // 72行 × 5条 = 360行,~15ms 完成(< 1帧 16.67ms),基本消除撕裂 #define FL_STRIP_H 72 // 每条带高度 static uint16_t *fl_dma_buf = NULL; // DMA 缓冲区指针 static size_t fl_dma_buf_size = 0; // 缓冲区像素数 // 颜色数组(RGB888,可扩展) static const uint32_t flashlight_color_values[] = { 0xFF0000, // 红色 0x00FF00, // 绿色 0x0000FF, // 蓝色 0xFFFF00, // 黄色 0xFF00FF, // 品红 0x00FFFF, // 青色 0xFFFFFF, // 白色 }; #define FLASHLIGHT_COLOR_COUNT (sizeof(flashlight_color_values) / sizeof(flashlight_color_values[0])) // RGB888 转 RGB565(大端字节序,匹配 LCD GRAM 格式) static uint16_t rgb888_to_rgb565(uint32_t rgb888) { uint8_t r = (rgb888 >> 16) & 0xFF; uint8_t g = (rgb888 >> 8) & 0xFF; uint8_t b = rgb888 & 0xFF; uint16_t rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); // ESP32 SPI LCD 使用大端字节序 return (rgb565 >> 8) | (rgb565 << 8); } // 用指定颜色填充 DMA 缓冲区 static void fl_fill_buf_color(uint32_t rgb888) { if (!fl_dma_buf) return; uint16_t color565 = rgb888_to_rgb565(rgb888); for (size_t i = 0; i < fl_dma_buf_size; i++) { fl_dma_buf[i] = color565; } } // 分配 DMA 缓冲区(应援灯进入时调用) static bool fl_alloc_dma_buf(void) { if (fl_dma_buf) return true; // 已分配 fl_dma_buf_size = LCD_WID * FL_STRIP_H; fl_dma_buf = heap_caps_malloc(fl_dma_buf_size * sizeof(uint16_t), MALLOC_CAP_DMA); if (!fl_dma_buf) { fl_dma_buf_size = 0; return false; } return true; } // 释放 DMA 缓冲区(应援灯退出时调用) static void fl_free_dma_buf(void) { if (fl_dma_buf) { heap_caps_free(fl_dma_buf); fl_dma_buf = NULL; fl_dma_buf_size = 0; } } // ---- LVGL flush 拦截:应援灯模式下阻止 LVGL 向 LCD 写入任何数据 ---- // 仅暂停 refr timer 不够可靠(其他模块可能恢复它), // 替换 flush 回调为空操作是最彻底的方案。 static void (*fl_original_flush_cb)(struct _lv_disp_drv_t *, const lv_area_t *, lv_color_t *) = NULL; // 空 flush 回调:不写入 LCD,仅通知 LVGL 完成(防止 LVGL 挂起) static void fl_dummy_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) { lv_disp_flush_ready(drv); } // 禁用 LVGL LCD 输出(进入应援灯时调用) static void fl_disable_lvgl_flush(void) { lv_disp_t *disp = lv_disp_get_default(); if (disp && disp->driver) { fl_original_flush_cb = disp->driver->flush_cb; disp->driver->flush_cb = fl_dummy_flush_cb; } } // 恢复 LVGL LCD 输出 + 强制全屏重绘(退出应援灯时调用) static void fl_enable_lvgl_flush(void) { lv_disp_t *disp = lv_disp_get_default(); if (disp && disp->driver && fl_original_flush_cb) { disp->driver->flush_cb = fl_original_flush_cb; fl_original_flush_cb = NULL; // GRAM 已被 DMA 覆写,强制 LVGL 全屏重绘恢复正常界面 lv_obj_invalidate(lv_scr_act()); } } // 直接 DMA 切换颜色(独占 GRAM,LVGL flush 已禁用,无竞争) // QSPI 模式下 TESLRD 读取无效(始终返回0xFFFF),无法软件同步 VSYNC // 采用 PWM 微降方案:DMA 期间亮度降至极低,人眼不可见撕裂,完成后恢复 static void fl_switch_color_direct(uint32_t rgb888) { fl_fill_buf_color(rgb888); // 持有 LVGL 锁,确保 DMA 期间不会与 indev 等其他 SPI 操作冲突 if (lvgl_port_lock(100)) { uint8_t restore_brightness = flashlight_bright ? 100 : 20; // 完全关闭背光(PWM=0),DMA期间屏幕全黑,撕裂不可见 pwm_set_brightness(0); // 等待1个PWM周期(200μs@5kHz)确保背光完全熄灭 esp_rom_delay_us(200); lcd_fill_color_with_buf(fl_dma_buf, FL_STRIP_H); // DMA 完成后恢复亮度,显示新颜色 pwm_set_brightness(restore_brightness); lvgl_port_unlock(); } } // 闪烁定时器回调(每 500ms 切换亮暗) static void flashlight_blink_timer_cb(lv_timer_t *timer) { if (!flashlight_overlay) return; flashlight_bright = !flashlight_bright; pwm_set_brightness(flashlight_bright ? 100 : 20); } // 手动滑动检测(layer_top 上 LVGL 手势检测不可靠,改用坐标位移判定) // 仅影响 overlay 对象,其他界面的 LV_EVENT_GESTURE 不受影响 static lv_coord_t fl_press_y = 0; // 按下时的 Y 坐标 static bool fl_press_valid = false; // 是否有有效的按下记录 #define FL_SWIPE_THRESHOLD 50 // 下滑判定阈值(像素) // 切换颜色(下滑时调用) // 无需 PWM=0 黑屏:纯色→纯色直接 DMA 覆写,~15ms 完成 static void fl_do_switch_color(void) { bool was_blinking = flashlight_blinking; if (flashlight_timer) { lv_timer_pause(flashlight_timer); } flashlight_color_index = (flashlight_color_index + 1) % FLASHLIGHT_COLOR_COUNT; fl_switch_color_direct(flashlight_color_values[flashlight_color_index]); flashlight_bright = true; if (was_blinking && flashlight_timer) { lv_timer_resume(flashlight_timer); } } // 切换闪烁状态(点击时调用) static void fl_do_toggle_blink(void) { flashlight_blinking = !flashlight_blinking; if (flashlight_blinking) { flashlight_bright = true; pwm_set_brightness(100); if (!flashlight_timer) { flashlight_timer = lv_timer_create(flashlight_blink_timer_cb, 500, NULL); } } else { if (flashlight_timer) { lv_timer_del(flashlight_timer); flashlight_timer = NULL; } flashlight_bright = true; pwm_set_brightness(100); } } // 遮罩层事件处理:按下记录坐标,释放时判定点击 vs 下滑 static void flashlight_overlay_event_cb(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_PRESSED) { lv_indev_t *indev = lv_indev_get_act(); lv_point_t point; lv_indev_get_point(indev, &point); fl_press_y = point.y; fl_press_valid = true; } else if (code == LV_EVENT_RELEASED) { if (!fl_press_valid) return; fl_press_valid = false; lv_indev_t *indev = lv_indev_get_act(); lv_point_t point; lv_indev_get_point(indev, &point); lv_coord_t dy = point.y - fl_press_y; if (dy > FL_SWIPE_THRESHOLD) { // 下滑:切换颜色 fl_do_switch_color(); } else if (dy > -FL_SWIPE_THRESHOLD) { // 位移小:视为点击,切换闪烁/常亮 fl_do_toggle_blink(); } // 上滑(dy < -threshold):忽略 } } // 退出应援灯模式(外部调用,不恢复亮度) void flashlight_exit(void) { pwm_set_brightness(0); if (lvgl_port_lock(100)) { if (flashlight_timer) { lv_timer_del(flashlight_timer); flashlight_timer = NULL; } if (flashlight_overlay) { lv_obj_del(flashlight_overlay); flashlight_overlay = NULL; } lvgl_port_unlock(); } flashlight_blinking = false; fl_free_dma_buf(); // 恢复 LVGL 显示刷新(退出应援灯后 LVGL 重新接管屏幕渲染) fl_enable_lvgl_flush(); } // 查询应援灯是否激活 bool flashlight_is_active(void) { return (flashlight_overlay != NULL); } // 获取进入应援灯前保存的亮度值 uint8_t flashlight_get_saved_brightness(void) { return saved_brightness; } // 进入应援灯模式 static void show_flashlight(void) { if (flashlight_overlay) return; // 分配 DMA 缓冲区 if (!fl_alloc_dma_buf()) { ESP_LOGE("Flashlight", "DMA缓冲区分配失败"); return; } saved_brightness = pwm_get_brightness(); // 创建全屏遮罩层 flashlight_overlay = lv_obj_create(lv_layer_top()); lv_obj_remove_style_all(flashlight_overlay); lv_obj_set_size(flashlight_overlay, LV_HOR_RES, LV_VER_RES); lv_obj_set_pos(flashlight_overlay, 0, 0); // 启用滚动手势识别 + 点击 // 只需 CLICKABLE 接收触摸事件,手动检测滑动不依赖 SCROLLABLE lv_obj_add_flag(flashlight_overlay, LV_OBJ_FLAG_CLICKABLE); // 设置初始颜色(红色) flashlight_color_index = 0; lv_obj_set_style_bg_color(flashlight_overlay, lv_color_hex(flashlight_color_values[0]), 0); lv_obj_set_style_bg_opa(flashlight_overlay, LV_OPA_COVER, 0); // 注册事件回调(点击 + 手势) lv_obj_add_event_cb(flashlight_overlay, flashlight_overlay_event_cb, LV_EVENT_ALL, NULL); // 暂停 LVGL 显示刷新,应援灯模式由 DMA 独占 GRAM // 必须在创建 overlay 后暂停,避免 LVGL 渲染 overlay 与 DMA 竞争 fl_disable_lvgl_flush(); // DMA 填充初始颜色到 GRAM fl_switch_color_direct(flashlight_color_values[0]); // 进入时:高亮常亮,不闪烁 flashlight_blinking = false; flashlight_bright = true; flashlight_timer = NULL; pwm_set_brightness(100); } // ImgFlashlight点击事件:显示手电筒 static void ui_event_ImgFlashlight(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_CLICKED) { show_flashlight(); } } // ImgDelete 点击事件:跳转到 ScreenImg 并显示删除容器 static void ui_event_ImgDelete(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_CLICKED) { // 跳转到 ScreenImg 界面 _ui_screen_change(&ui_ScreenImg, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenImg_screen_init); // 显示删除容器 ui_ScreenImg_show_delete_container(); } } // event funtions void ui_event_ScreenSet( lv_event_t * e) { lv_event_code_t event_code = lv_event_get_code(e); if ( event_code == LV_EVENT_GESTURE && lv_indev_get_gesture_dir(lv_indev_get_act()) == LV_DIR_TOP ) { lv_indev_wait_release(lv_indev_get_act()); // 返回到之前的界面,如果没有记录则默认返回Home if (previous_screen && previous_screen_init) { _ui_screen_change(previous_screen, LV_SCR_LOAD_ANIM_NONE, 0, 0, previous_screen_init); // 根据返回目标同步按键上下文 if (previous_screen == &ui_ScreenImg) { dzbj_button_set_context(BTN_CTX_IMG); } else { dzbj_button_set_context(BTN_CTX_HOME); } } else { _ui_screen_change(&ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init); dzbj_button_set_context(BTN_CTX_HOME); } } } // 滑块交互锁定:拖动期间禁用其他按钮,防止坐标跳变导致误触 static void slider_lock_other_buttons(bool lock) { if (lock) { lv_obj_clear_flag(ui_ImgDelete, LV_OBJ_FLAG_CLICKABLE); lv_obj_clear_flag(ui_ImgFlashlight, LV_OBJ_FLAG_CLICKABLE); lv_obj_clear_flag(ui_ImgLowPower, LV_OBJ_FLAG_CLICKABLE); } else { lv_obj_add_flag(ui_ImgDelete, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_add_flag(ui_ImgFlashlight, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_add_flag(ui_ImgLowPower, LV_OBJ_FLAG_CLICKABLE); } } // PWM节流:最小更新间隔50ms,避免频繁调用 static int64_t last_brightness_update_us = 0; void ui_event_SliderBrightness( lv_event_t * e) { lv_event_code_t event_code = lv_event_get_code(e); if (event_code == LV_EVENT_PRESSED) { slider_lock_other_buttons(true); } else if (event_code == LV_EVENT_RELEASED || event_code == LV_EVENT_PRESS_LOST) { slider_lock_other_buttons(false); // 松手时确保最终值写入 lv_obj_t *target = lv_event_get_target(e); int32_t val = lv_slider_get_value(target); if (val < 10) { val = 10; lv_slider_set_value(target, 10, LV_ANIM_OFF); } pwm_set_brightness((uint8_t)val); _ui_slider_set_text_value(ui_LabelBrightness, target, "", "%"); last_brightness_update_us = 0; } else if (event_code == LV_EVENT_VALUE_CHANGED) { lv_obj_t *target = lv_event_get_target(e); int32_t val = lv_slider_get_value(target); if (val < 10) { val = 10; lv_slider_set_value(target, 10, LV_ANIM_OFF); } // 文本始终更新(轻量操作) _ui_slider_set_text_value(ui_LabelBrightness, target, "", "%"); // PWM节流:50ms内不重复调用 int64_t now = esp_timer_get_time(); if (now - last_brightness_update_us >= 50000) { pwm_set_brightness((uint8_t)val); last_brightness_update_us = now; } } } // ImgLowPower点击事件:切换休眠模式 void ui_event_ImgLowPower( lv_event_t * e) { lv_event_code_t event_code = lv_event_get_code(e); if ( event_code == LV_EVENT_VALUE_CHANGED) { lv_obj_t * target = lv_event_get_target(e); // checked=true时显示s12(休眠模式),false时显示s11(正常模式) bool checked = lv_obj_has_state(target, LV_STATE_CHECKED); sleep_mgr_set_enabled(checked); } } // build funtions void ui_ScreenSet_screen_init(void) { ui_ScreenSet = lv_obj_create(NULL); lv_obj_clear_flag( ui_ScreenSet, LV_OBJ_FLAG_SCROLLABLE ); /// Flags lv_obj_set_style_bg_color(ui_ScreenSet, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT ); lv_obj_set_style_bg_opa(ui_ScreenSet, 255, LV_PART_MAIN| LV_STATE_DEFAULT); ui_GlobalContainer = lv_obj_create(ui_ScreenSet); lv_obj_remove_style_all(ui_GlobalContainer); lv_obj_set_width( ui_GlobalContainer, 360); lv_obj_set_height( ui_GlobalContainer, 360); lv_obj_set_align( ui_GlobalContainer, LV_ALIGN_CENTER ); lv_obj_clear_flag( ui_GlobalContainer, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_ContainerTop = lv_obj_create(ui_GlobalContainer); lv_obj_remove_style_all(ui_ContainerTop); lv_obj_set_width( ui_ContainerTop, 240); lv_obj_set_height( ui_ContainerTop, 80); lv_obj_set_x( ui_ContainerTop, 0 ); lv_obj_set_y( ui_ContainerTop, -40 ); lv_obj_set_align( ui_ContainerTop, LV_ALIGN_CENTER ); lv_obj_clear_flag( ui_ContainerTop, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_ImgLowPower = lv_imgbtn_create(ui_ContainerTop); lv_imgbtn_set_src(ui_ImgLowPower, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_s11_png, NULL); lv_imgbtn_set_src(ui_ImgLowPower, LV_IMGBTN_STATE_PRESSED, NULL, &ui_img_s11_png, NULL); lv_imgbtn_set_src(ui_ImgLowPower, LV_IMGBTN_STATE_DISABLED, NULL, &ui_img_s12_png, NULL); lv_imgbtn_set_src(ui_ImgLowPower, LV_IMGBTN_STATE_CHECKED_PRESSED, NULL, &ui_img_s12_png, NULL); lv_imgbtn_set_src(ui_ImgLowPower, LV_IMGBTN_STATE_CHECKED_RELEASED, NULL, &ui_img_s12_png, NULL); lv_obj_set_width( ui_ImgLowPower, 64); lv_obj_set_height( ui_ImgLowPower, 64); lv_obj_set_x( ui_ImgLowPower, -86 ); lv_obj_set_y( ui_ImgLowPower, -1 ); lv_obj_set_align( ui_ImgLowPower, LV_ALIGN_CENTER ); lv_obj_add_flag( ui_ImgLowPower, LV_OBJ_FLAG_CHECKABLE ); /// Flags ui_ImgFlashlight = lv_img_create(ui_ContainerTop); lv_img_set_src(ui_ImgFlashlight, &ui_img_s9_png); lv_obj_set_width( ui_ImgFlashlight, LV_SIZE_CONTENT); /// 1 lv_obj_set_height( ui_ImgFlashlight, LV_SIZE_CONTENT); /// 1 lv_obj_set_x( ui_ImgFlashlight, -2 ); lv_obj_set_y( ui_ImgFlashlight, -1 ); lv_obj_set_align( ui_ImgFlashlight, LV_ALIGN_CENTER ); lv_obj_add_flag( ui_ImgFlashlight, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_CLICKABLE ); /// Flags lv_obj_clear_flag( ui_ImgFlashlight, LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_ImgDelete = lv_img_create(ui_ContainerTop); lv_img_set_src(ui_ImgDelete, &ui_img_s6_png); lv_obj_set_width( ui_ImgDelete, LV_SIZE_CONTENT); /// 1 lv_obj_set_height( ui_ImgDelete, LV_SIZE_CONTENT); /// 1 lv_obj_set_x( ui_ImgDelete, 82 ); lv_obj_set_y( ui_ImgDelete, -1 ); lv_obj_set_align( ui_ImgDelete, LV_ALIGN_CENTER ); lv_obj_add_flag( ui_ImgDelete, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_CLICKABLE ); /// Flags lv_obj_clear_flag( ui_ImgDelete, LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_ContainerCentral = lv_obj_create(ui_GlobalContainer); lv_obj_remove_style_all(ui_ContainerCentral); lv_obj_set_width( ui_ContainerCentral, 230); lv_obj_set_height( ui_ContainerCentral, 70); lv_obj_set_x( ui_ContainerCentral, 6 ); lv_obj_set_y( ui_ContainerCentral, 44 ); lv_obj_set_align( ui_ContainerCentral, LV_ALIGN_CENTER ); lv_obj_clear_flag( ui_ContainerCentral, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_SliderBrightness = lv_slider_create(ui_ContainerCentral); lv_slider_set_value( ui_SliderBrightness, 50, LV_ANIM_OFF); if (lv_slider_get_mode(ui_SliderBrightness)==LV_SLIDER_MODE_RANGE ) lv_slider_set_left_value( ui_SliderBrightness, 0, LV_ANIM_OFF); lv_obj_set_width( ui_SliderBrightness, 220); lv_obj_set_height( ui_SliderBrightness, 60); lv_obj_set_x( ui_SliderBrightness, -3 ); lv_obj_set_y( ui_SliderBrightness, 0 ); lv_obj_set_align( ui_SliderBrightness, LV_ALIGN_CENTER ); lv_obj_set_style_radius(ui_SliderBrightness, 50, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_dir(ui_SliderBrightness, LV_GRAD_DIR_NONE, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_blend_mode(ui_SliderBrightness, LV_BLEND_MODE_NORMAL, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_radius(ui_SliderBrightness, 0, LV_PART_INDICATOR| LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_SliderBrightness, lv_color_hex(0x64A8EB), LV_PART_INDICATOR | LV_STATE_DEFAULT ); lv_obj_set_style_bg_opa(ui_SliderBrightness, 255, LV_PART_INDICATOR| LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_SliderBrightness, lv_color_hex(0xFFFFFF), LV_PART_KNOB | LV_STATE_DEFAULT ); lv_obj_set_style_bg_opa(ui_SliderBrightness, 0, LV_PART_KNOB| LV_STATE_DEFAULT); ui_ImgSun = lv_img_create(ui_ContainerCentral); lv_img_set_src(ui_ImgSun, &ui_img_s10_png); lv_obj_set_width( ui_ImgSun, LV_SIZE_CONTENT); /// 1 lv_obj_set_height( ui_ImgSun, LV_SIZE_CONTENT); /// 1 lv_obj_set_x( ui_ImgSun, -78 ); lv_obj_set_y( ui_ImgSun, 0 ); lv_obj_set_align( ui_ImgSun, LV_ALIGN_CENTER ); lv_obj_add_flag( ui_ImgSun, LV_OBJ_FLAG_ADV_HITTEST ); /// Flags lv_obj_clear_flag( ui_ImgSun, LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_LabelBrightness = lv_label_create(ui_ContainerCentral); lv_obj_set_width( ui_LabelBrightness, LV_SIZE_CONTENT); /// 1 lv_obj_set_height( ui_LabelBrightness, LV_SIZE_CONTENT); /// 1 lv_obj_set_x( ui_LabelBrightness, 6 ); lv_obj_set_y( ui_LabelBrightness, 0 ); lv_obj_set_align( ui_LabelBrightness, LV_ALIGN_CENTER ); lv_label_set_text(ui_LabelBrightness,"50%"); lv_obj_set_style_text_color(ui_LabelBrightness, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT ); lv_obj_set_style_text_opa(ui_LabelBrightness, 255, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LabelBrightness, &lv_font_montserrat_18, LV_PART_MAIN| LV_STATE_DEFAULT); ui_ArcPowerLevel = lv_arc_create(ui_GlobalContainer); lv_obj_set_width( ui_ArcPowerLevel, 320); lv_obj_set_height( ui_ArcPowerLevel, 320); lv_obj_set_align( ui_ArcPowerLevel, LV_ALIGN_CENTER ); lv_obj_clear_flag( ui_ArcPowerLevel, LV_OBJ_FLAG_CLICKABLE ); /// Flags lv_arc_set_value(ui_ArcPowerLevel, 50); lv_obj_set_style_arc_color(ui_ArcPowerLevel, lv_color_hex(0x39393E), LV_PART_MAIN | LV_STATE_DEFAULT ); lv_obj_set_style_arc_opa(ui_ArcPowerLevel, 255, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_arc_width(ui_ArcPowerLevel, 16, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_arc_color(ui_ArcPowerLevel, lv_color_hex(0x19FA29), LV_PART_INDICATOR | LV_STATE_DEFAULT ); lv_obj_set_style_arc_opa(ui_ArcPowerLevel, 255, LV_PART_INDICATOR| LV_STATE_DEFAULT); lv_obj_set_style_arc_width(ui_ArcPowerLevel, 16, LV_PART_INDICATOR| LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_ArcPowerLevel, lv_color_hex(0x19FA29), LV_PART_KNOB | LV_STATE_DEFAULT ); lv_obj_set_style_bg_opa(ui_ArcPowerLevel, 255, LV_PART_KNOB| LV_STATE_DEFAULT); ui_ImgLightning = lv_img_create(ui_GlobalContainer); lv_img_set_src(ui_ImgLightning, &ui_img_s8_png); lv_obj_set_width( ui_ImgLightning, LV_SIZE_CONTENT); /// 20 lv_obj_set_height( ui_ImgLightning, LV_SIZE_CONTENT); /// 20 lv_obj_set_x( ui_ImgLightning, -23 ); lv_obj_set_y( ui_ImgLightning, 121 ); lv_obj_set_align( ui_ImgLightning, LV_ALIGN_CENTER ); lv_obj_add_flag( ui_ImgLightning, LV_OBJ_FLAG_ADV_HITTEST ); /// Flags lv_obj_clear_flag( ui_ImgLightning, LV_OBJ_FLAG_SCROLLABLE ); /// Flags ui_LabelPowerLevel = lv_label_create(ui_GlobalContainer); lv_obj_set_width( ui_LabelPowerLevel, LV_SIZE_CONTENT); /// 1 lv_obj_set_height( ui_LabelPowerLevel, LV_SIZE_CONTENT); /// 1 lv_obj_set_x( ui_LabelPowerLevel, 26 ); lv_obj_set_y( ui_LabelPowerLevel, 121 ); lv_obj_set_align( ui_LabelPowerLevel, LV_ALIGN_CENTER ); lv_label_set_text(ui_LabelPowerLevel,"70%"); lv_obj_set_style_text_color(ui_LabelPowerLevel, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT ); lv_obj_set_style_text_opa(ui_LabelPowerLevel, 255, LV_PART_MAIN| LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_LabelPowerLevel, &lv_font_montserrat_20, LV_PART_MAIN| LV_STATE_DEFAULT); // 按钮只注册需要的事件,减少无效回调调用 lv_obj_add_event_cb(ui_ImgLowPower, ui_event_ImgLowPower, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_add_event_cb(ui_ImgFlashlight, ui_event_ImgFlashlight, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(ui_ImgDelete, ui_event_ImgDelete, LV_EVENT_CLICKED, NULL); // 滑块需要 PRESSED/RELEASED/PRESS_LOST/VALUE_CHANGED,保留 ALL lv_obj_add_event_cb(ui_SliderBrightness, ui_event_SliderBrightness, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(ui_ScreenSet, ui_event_ScreenSet, LV_EVENT_ALL, NULL); } void ui_ScreenSet_screen_destroy(void) { if (ui_ScreenSet) lv_obj_del(ui_ScreenSet); // NULL screen variables ui_ScreenSet= NULL; ui_GlobalContainer= NULL; ui_ContainerTop= NULL; ui_ImgLowPower= NULL; ui_ImgFlashlight= NULL; ui_ImgDelete= NULL; ui_ContainerCentral= NULL; ui_SliderBrightness= NULL; ui_ImgSun= NULL; ui_LabelBrightness= NULL; ui_ArcPowerLevel= NULL; ui_ImgLightning= NULL; ui_LabelPowerLevel= NULL; }