/* * 模块名称:UI Deco (顶部装饰层) * 模块功能:顶部"浅 V"装饰(左腿/水平线/右腿 3 段线)共享自绘—— * 菜单根框与内容页共用的几何点集、线宽与 culling 区在本模块唯一定义, * 各页面经 ui_deco_draw 调用绘制(无 LVGL 对象,DRAW_MAIN 自绘) * 适用平台:STM32F407ZGTx / PC 模拟器(两端共用) * 作者:王建锋 * 创建日期:2026-09-09 * 修改记录: * 2026-09-09 王建锋 创建:提取 ui_menu_view.c / ui_content_page.c 重复的"浅 V"几何 */ /* 头文件包含区 */ #include #include "ui_deco.h" #include "ui_tokens.h" /* 私有宏定义区 */ #define DECO_LEG_W 3 /* "浅 V"两腿线宽(1bpp 下斜线边缘易被阈值吃掉,需加粗) */ #define DECO_HORIZ_W 2 /* "浅 V"水平线宽 */ /* 静态变量定义区 */ static const lv_point_precise_t s_leg_l[2] = { {7, 7}, {16, 17} }; /* 左腿:自顶端斜下 */ static const lv_point_precise_t s_hoz[2] = { {16, 17}, {145, 17} }; /* 水平线:接两腿底端 */ static const lv_point_precise_t s_leg_r[2] = { {158, 7}, {145, 17} }; /* 右腿 */ /* 绘制次序 = 原对象创建序(左腿、右腿、水平线),重叠像素与原渲染一致 */ static const lv_point_precise_t *const s_segs[3] = {s_leg_l, s_leg_r, s_hoz}; static const int32_t s_seg_w[3] = {DECO_LEG_W, DECO_LEG_W, DECO_HORIZ_W}; static const lv_area_t s_band = {0, 0, UI_SCREEN_W - 1, 19}; /* "浅 V" culling 区(与原线段对象范围一致) */ /* 函数定义区 */ /* * 函数功能:判断两区域是否相交(等价 lv_area_intersect 非空判断;避免依赖 LVGL 私有头) * 入口参数:a - 区域 1 const lv_area_t * * b - 区域 2 const lv_area_t * * 返回值:true - 相交;false - 不相交 * 限定条件:无 * 函数说明:四边取 min/max 成交集,任一边为空即不相交(与 ui_menu_view.c 同实现) */ static bool deco_areas_intersect(const lv_area_t *a, const lv_area_t *b) { int32_t x1 = (a->x1 > b->x1) ? a->x1 : b->x1; int32_t y1 = (a->y1 > b->y1) ? a->y1 : b->y1; int32_t x2 = (a->x2 < b->x2) ? a->x2 : b->x2; int32_t y2 = (a->y2 < b->y2) ? a->y2 : b->y2; return (x1 <= x2 && y1 <= y2); } /* * 函数功能:绘制顶部"浅 V"装饰(3 段线,线宽各异,白色) * 入口参数:layer - 绘制层 lv_layer_t * * clip - 重绘裁剪区 const lv_area_t * * 返回值:无 * 限定条件:layer/clip 有效(调用方自 LV_EVENT_DRAW_MAIN 事件取得) * 函数说明:1. 几何共享:两腿 3px 粗、水平线 2px 细(1bpp 斜线边缘易被阈值吃掉,腿须加粗) * 2. 绘制次序固定(左腿、右腿、水平线),重叠像素与原渲染一致 * 3. 重绘区未覆盖 culling 区(屏顶 20px 带)则整体跳过 */ void ui_deco_draw(lv_layer_t *layer, const lv_area_t *clip) { if (!deco_areas_intersect(&s_band, clip)) { return; } for (uint8_t i = 0; i < 3; i++) { lv_draw_line_dsc_t ld; lv_draw_line_dsc_init(&ld); ld.base.layer = layer; ld.color = UI_COL_FG; ld.width = s_seg_w[i]; ld.p1 = s_segs[i][0]; ld.p2 = s_segs[i][1]; lv_draw_line(layer, &ld); } }