增加UI 代码的注释
This commit is contained in:
+40
-32
@@ -7,24 +7,27 @@
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-08-29
|
||||
* 修改记录:
|
||||
* 2026-08-29 王建锋 创建初始版本
|
||||
* 2026-09-02 王建锋 弃用已废弃的 lv_menu 控件,改为基元控件页面导航
|
||||
* 2026-09-02 王建锋 修复选中行文字不可见(白底白字)
|
||||
* 2026-09-03 王建锋 主界面按设计稿重构(根页 7 项/装饰/状态行)
|
||||
* 2026-09-04 王建锋 重构为"横向级联框"模型(菜单页面设计.md):拆出显示层
|
||||
* ui_menu_view 与数据层 ui_menu_tab;本层只留导航状态机
|
||||
* 2026-09-08 王建锋 按代码规范 V1.0 补全分区注释与关键行注释;函数定义括号改 K&R 风格(同行)
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ui_menu.h"
|
||||
|
||||
#include "ui_menu_view.h"
|
||||
|
||||
#include "ui_menu_tab.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lvgl.h"
|
||||
|
||||
#define DBG_TAG "[UI_MENU]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/* 静态变量定义区 */
|
||||
|
||||
/*
|
||||
* 导航状态:唯一"必须持久"的导航历史(共 17 B,见设计 §7.2);
|
||||
* 条目列表/框几何均可由 g_menu_tab + 本状态随时重算,不落 RAM
|
||||
@@ -34,6 +37,8 @@ static uint8_t s_sel[MENU_PAGE_MAX]; /* 各层选中下标(返回时还原
|
||||
static uint8_t s_depth; /* 当前深度(0=根框)= 焦点所在(最右)框 */
|
||||
static uint16_t s_scroll[MENU_PAGE_MAX]; /* 各框滚动偏移(px);框销毁再进入时还原 */
|
||||
|
||||
/* 函数定义区 */
|
||||
|
||||
/*
|
||||
* 函数功能:移选后的层刷新(高亮 + 跟随滚动 + 滚动位回读持久化)
|
||||
* 入口参数:depth - 层深度 uint8_t
|
||||
@@ -41,8 +46,7 @@ static uint16_t s_scroll[MENU_PAGE_MAX]; /* 各框滚动偏移(px);框销
|
||||
* 限定条件:该层框已建
|
||||
* 函数说明:显示层跟随滚动后,滚动位写回 s_scroll 持久(框重建时还原)
|
||||
*/
|
||||
static void menu_refresh_layer(uint8_t depth)
|
||||
{
|
||||
static void menu_refresh_layer(uint8_t depth) {
|
||||
ui_menu_view_frame_refresh(depth, s_sel[depth]);
|
||||
s_scroll[depth] = ui_menu_view_get_scroll(depth);
|
||||
}
|
||||
@@ -55,8 +59,7 @@ static void menu_refresh_layer(uint8_t depth)
|
||||
* 函数说明: 1. 叶子(无子项)同样压层,生成空白终点框(占位,无条目)
|
||||
* 2. 同节点再次进入:还原上次选中与滚动位;换节点则清零
|
||||
*/
|
||||
static void menu_open(uint8_t child)
|
||||
{
|
||||
static void menu_open(uint8_t child) {
|
||||
uint8_t d = s_depth;
|
||||
bool same = (s_path[d + 1u] == child);
|
||||
|
||||
@@ -77,8 +80,7 @@ static void menu_open(uint8_t child)
|
||||
* 函数说明: 1. 销毁最右框行对象(既有屏上框不动、无需重建)
|
||||
* 2. 焦点回父框;父层选中/滚动原样保留(选中不跳)
|
||||
*/
|
||||
static void menu_back(void)
|
||||
{
|
||||
static void menu_back(void) {
|
||||
ui_menu_view_frame_destroy(s_depth);
|
||||
s_depth--;
|
||||
ui_menu_view_focus(s_depth);
|
||||
@@ -95,38 +97,40 @@ static void menu_back(void)
|
||||
* 3. ESC/LEFT:关最右框(根框不响应)
|
||||
* 4. 空框(终点页 0 条目)只响应返回
|
||||
*/
|
||||
static void menu_key_handle(uint8_t depth, lv_key_t key)
|
||||
{
|
||||
uint8_t kids[MENU_ITEM_MAX];
|
||||
uint8_t cnt = ui_menu_tab_children(s_path[depth], kids, MENU_ITEM_MAX);
|
||||
static void menu_key_handle(uint8_t depth, lv_key_t key) {
|
||||
uint8_t kids[MENU_ITEM_MAX]; /* 本框条目列表:由 g_menu_tab 按 parent 现算,不落 RAM */
|
||||
uint8_t cnt = ui_menu_tab_children(s_path[depth], kids, MENU_ITEM_MAX); /* 条目数;0 = 空白终点框(进入叶子) */
|
||||
|
||||
switch (key) {
|
||||
case LV_KEY_UP:
|
||||
if (cnt > 0u) {
|
||||
if (cnt > 0u) { /* 空框(0 条目)不移选;同时防对 0 取模 */
|
||||
/* 移选上移、首尾环绕:先加 cnt 再减 1 保证无符号下不为负,% cnt 绕回首行 */
|
||||
s_sel[depth] = (uint8_t)((s_sel[depth] + (uint8_t)cnt - 1u) % cnt);
|
||||
menu_refresh_layer(depth);
|
||||
menu_refresh_layer(depth); /* 刷新高亮 + 跟随滚动 + 滚动位回读持久化 */
|
||||
}
|
||||
break;
|
||||
case LV_KEY_DOWN:
|
||||
if (cnt > 0u) {
|
||||
if (cnt > 0u) { /* 空框(0 条目)不移选;同时防对 0 取模 */
|
||||
/* 移选下移、首尾环绕:% cnt 越尾自动绕回首行 */
|
||||
s_sel[depth] = (uint8_t)((s_sel[depth] + 1u) % cnt);
|
||||
menu_refresh_layer(depth);
|
||||
menu_refresh_layer(depth); /* 刷新高亮 + 跟随滚动 + 滚动位回读持久化 */
|
||||
}
|
||||
break;
|
||||
case LV_KEY_ENTER:
|
||||
case LV_KEY_RIGHT:
|
||||
if (cnt > 0u && depth + 1u < MENU_PAGE_MAX) {
|
||||
menu_open(kids[s_sel[depth]]);
|
||||
/* 进子框:空框无条目可进;最深层(depth=MAX-1)无子层可再开 */
|
||||
if (cnt > 0u && depth < MENU_PAGE_MAX - 1u) {
|
||||
menu_open(kids[s_sel[depth]]); /* 压层:建新框 + 焦点移到新框 */
|
||||
}
|
||||
break;
|
||||
case LV_KEY_ESC:
|
||||
case LV_KEY_LEFT:
|
||||
if (depth > 0u) {
|
||||
menu_back();
|
||||
if (depth > 0u) { /* 根框(d=0)不响应返回 */
|
||||
menu_back(); /* 弹层:毁最右框,焦点回父框(选中/滚动不跳) */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break; /* 其余键值忽略 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +141,7 @@ static void menu_key_handle(uint8_t depth, lv_key_t key)
|
||||
* 限定条件:容器已加入默认输入组并获焦
|
||||
* 函数说明:键值经默认输入组送达焦点容器;统一分发到 menu_key_handle
|
||||
*/
|
||||
static void menu_key_cb(lv_event_t *e)
|
||||
{
|
||||
static void menu_key_cb(lv_event_t *e) {
|
||||
uint8_t depth = (uint8_t)(uintptr_t)lv_event_get_user_data(e);
|
||||
|
||||
if (depth < MENU_PAGE_MAX) {
|
||||
@@ -157,26 +160,29 @@ static void menu_key_cb(lv_event_t *e)
|
||||
* 4. 建根框(主界面 node 0 子项)并置焦点
|
||||
* 5. 构建前后监控 LVGL 池内存并打印
|
||||
*/
|
||||
int ui_menu_init(void)
|
||||
{
|
||||
int ui_menu_init(void) {
|
||||
/* 数据表自检:各节点 parent 下标必须有效,提前捕获表内笔误(失败即返回、不建任何对象) */
|
||||
if (!ui_menu_tab_valid()) {
|
||||
DBG_ERROR("menu table: INVALID (parent index out of range)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 重置导航状态:各层从主界面(node 0)第 0 行开始、无滚动 */
|
||||
for (uint8_t d = 0u; d < MENU_PAGE_MAX; d++) {
|
||||
s_path[d] = 0u;
|
||||
s_sel[d] = 0u;
|
||||
s_scroll[d] = 0u;
|
||||
}
|
||||
s_depth = 0u;
|
||||
s_depth = 0u; /* 起始于根框 */
|
||||
|
||||
/* 取 LVGL 池内存基线(与构建后对照,量化菜单对象开销) */
|
||||
lv_mem_monitor_t mon;
|
||||
lv_mem_monitor(&mon);
|
||||
DBG_INFO("menu build start: total=%u free=%u big=%u",
|
||||
(unsigned)mon.total_size,
|
||||
(unsigned)mon.free_size, (unsigned)mon.free_biggest_size);
|
||||
|
||||
/* 初始化显示层:样式 + 4 层持久容器 + 根框框体/装饰(失败 = 对象创建失败、池耗尽) */
|
||||
if (ui_menu_view_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -187,14 +193,16 @@ int ui_menu_init(void)
|
||||
if (cont == NULL) {
|
||||
return -1;
|
||||
}
|
||||
lv_group_add_obj(lv_group_get_default(), cont);
|
||||
lv_group_add_obj(lv_group_get_default(), cont); /* 容器入组:焦点可轮到它、能收键事件 */
|
||||
/* 容器挂键回调;层深度 d 装入 user_data 指针(menu_key_cb 内拆回) */
|
||||
lv_obj_add_event_cb(cont, menu_key_cb, LV_EVENT_KEY, (void *)(uintptr_t)d);
|
||||
}
|
||||
|
||||
/* 根框:主界面(node 0)子项;建一次、持久 */
|
||||
ui_menu_view_frame_build(0u, 0u, 0u, 0u);
|
||||
ui_menu_view_focus(0u);
|
||||
ui_menu_view_frame_build(0u, 0u, 0u, 0u); /* depth=0、node=0(主界面)、sel=0、scroll=0 */
|
||||
ui_menu_view_focus(0u); /* 焦点置根框:按键首先进根框 */
|
||||
|
||||
/* 读构建后内存、打印增量(对照上方基线) */
|
||||
lv_mem_monitor(&mon);
|
||||
DBG_INFO("menu build done: total=%u free=%u big=%u used=%u",
|
||||
(unsigned)mon.total_size,
|
||||
|
||||
Reference in New Issue
Block a user