将菜单的架构改成 MVP,并且进一步优化视图层和模型层的逻辑

This commit is contained in:
2026-04-01 19:42:05 +08:00
parent 0690d6a00e
commit 8b44b84d4c
54 changed files with 5362 additions and 2200 deletions

View File

@@ -1,191 +1,54 @@
#include "menu.h"
#include <stddef.h>
#include <stdio.h>
#include "../../pages/menu/page.h"
#include "../model/display.h"
#include "../../key.h"
#include "../view/menu_layout.h"
#include "../presenter/menu_presenter.h"
#include "../view/menu_render_port.h"
#include "../common/menu_state_types.h"
/* -------------------------------------------------------------------------
* 运行态状态收口App 层私有)
*
* 设计意图:
* 1) 避免全局变量四处散落,统一由 app/menu.c 托管生命周期;
* 2) 外部模块只能经由 MenuApp_* 接口访问,降低耦合;
* 3) Presenter/Model/View 依赖都在初始化时一次性装配。
*
* 变量职责:
* - s_dspCtrl:
* 显示刷新控制状态(例如首帧标记 bFirst
* - s_menuCtrl:
* 导航与路由控制状态(当前节点、各级 route、0 级入口等)。
* - s_menuItems[300]:
* 运行时菜单节点池(树构建后常驻内存),由 Model 初始化、View 读取布局/渲染。
* - g_menuPresenter:
* MVP 调度中枢实例,封装输入处理与刷新协同。
* - g_menuLayoutConfig:
* 布局参数快照(屏幕尺寸、行高、边距、菜单宽度等),初始化时写入一次。
* ------------------------------------------------------------------------- */
static tagDspCtrl s_dspCtrl;
static tagMenuCtrl s_menuCtrl;
static tagMenuItem s_menuItems[300];
static MenuPresenter g_menuPresenter;
static MenuLayoutConfig g_menuLayoutConfig;
void MenuApp_Render(void)
void MenuProc_See_AppInfo(void)
{
/* 统一渲染入口:由 Presenter 决定全量/增量刷新策略。 */
MenuPresenter_Refresh(&g_menuPresenter);
MenuPage_TriggerCurrentAction();
}
void MenuApp_HandleInput(uint8_t keyVal)
void MenuProc_See_YC(void)
{
/* 单次输入事件入口:按键解释与状态迁移都在 Presenter 内完成。 */
MenuPresenter_HandleInput(&g_menuPresenter, keyVal);
MenuPage_TriggerCurrentAction();
}
void MenuApp_PollInput(void)
{
/* 轮询输入设备(键盘/按键),再复用事件处理入口。 */
MenuApp_HandleInput(Key_Read());
}
void MenuProc_Set_Value(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Set_Soft(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_Time(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_RevEvent(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_ManualWave(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_Input(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_Set(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_Soft(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_YX_SetCommType(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_YX_SetWidth(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_YX_SetTwin(void) { MenuPage_TriggerCurrentAction(); }
void MenuApp_Init(void)
{
const MenuRenderPort *renderPort = MenuRenderPort_Lcd();
uint16_t lcdSizeX;
uint16_t lcdSizeY;
/* 1) 初始化底层渲染设备LCD/模拟器具体实现由 renderPort 决定)。 */
renderPort->init();
/* 2) 通过渲染端口查询设备能力,避免 app 层直接依赖 lcd.h 宏。 */
lcdSizeX = renderPort->get_size_x();
lcdSizeY = renderPort->get_size_y();
/* 3) 组装布局配置(后续由 View 布局计算与渲染阶段复用)。 */
g_menuLayoutConfig.lcdSizeX = lcdSizeX;
g_menuLayoutConfig.lcdSizeY = lcdSizeY;
g_menuLayoutConfig.menuYMin = MENU_YMIN;
g_menuLayoutConfig.menuYMax = MENU_YMAX_FROM_LCD(lcdSizeY);
g_menuLayoutConfig.lineHeight = LINE_HEIGHT;
g_menuLayoutConfig.menuWidth = MENU_WITDTH;
g_menuLayoutConfig.menuXAdd = MENU_XADD;
g_menuLayoutConfig.menuYAdd = MENU_YADD;
/* 4) 装配 Presenter注入控制状态、菜单池、渲染端口与布局配置。 */
MenuPresenter_Setup(&g_menuPresenter,
&s_dspCtrl,
&s_menuCtrl,
s_menuItems,
renderPort,
&g_menuLayoutConfig);
/* 5) 初始化模型数据并建立初始路由/布局。 */
MenuPresenter_InitModel(&g_menuPresenter, g_tMenuModelTab, MENU_MAX_ITEM);
}
const tagMenuItem *MenuApp_GetMenuItems(uint16_t *count)
{
/* 诊断/测试只读访问接口:
* - 返回内部菜单池首地址;
* - 若 count 非空,同步返回数组容量。 */
if (count != NULL)
{
*count = (uint16_t)(sizeof(s_menuItems) / sizeof(s_menuItems[0]));
}
return s_menuItems;
}
void MenuProc_See_AppInfo()
{
printf("MenuProc_See_AppInfo\n");
}
void MenuProc_See_YC()
{
printf("MenuProc_See_YC\n");
}
void MenuProc_Set_Value()
{
printf("MenuProc_Set_Value\n");
}
void MenuProc_Set_Soft()
{
printf("MenuProc_Set_Soft\n");
}
void MenuProc_Cfg_Time()
{
printf("MenuProc_Cfg_Time\n");
}
void MenuProc_Cfg_RevEvent()
{
printf("MenuProc_Cfg_RevEvent\n");
}
void MenuProc_Cfg_ManualWave()
{
printf("MenuProc_Cfg_ManualWave\n");
}
void MenuProc_See_Input()
{
printf("MenuProc_See_Input\n");
}
void MenuProc_See_Set()
{
printf("MenuProc_See_Set\n");
}
void MenuProc_See_Soft()
{
printf("MenuProc_See_Soft\n");
}
void MenuProc_YX_SetCommType()
{
printf("MenuProc_YX_SetCommType\n");
}
void MenuProc_YX_SetWidth()
{
printf("MenuProc_YX_SetWidth\n");
}
void MenuProc_YX_SetTwin()
{
printf("MenuProc_YX_SetTwin\n");
}
/* ---------- 以下为 display.c 菜单表引用、暂无具体实现的桩函数,避免链接未定义符号 ---------- */
void Menu_NonPfunc(void) { printf("Menu_NonPfunc\n"); }
void MenuProc_AllInf_Default(void) { printf("MenuProc_AllInf_Default\n"); }
void MenuProc_Para_Default(void) { printf("MenuProc_Para_Default\n"); }
void MenuProc_Set_Default(void) { printf("MenuProc_Set_Default\n"); }
void MenuProc_Resume_Soft(void) { printf("MenuProc_Resume_Soft\n"); }
void MenuProc_Cfg_CellDef(void) { printf("MenuProc_Cfg_CellDef\n"); }
void MenuProc_Cfg_ShowAnaType(void) { printf("MenuProc_Cfg_ShowAnaType\n"); }
void MenuProc_Dbg_XuYX(void) { printf("MenuProc_Dbg_XuYX\n"); }
void MenuProc_Dbg_XuYC(void) { printf("MenuProc_Dbg_XuYC\n"); }
void MenuProc_Dbg_XuEvent(void) { printf("MenuProc_Dbg_XuEvent\n"); }
void MenuProc_Dbg_Relay(void) { printf("MenuProc_Dbg_Relay\n"); }
void MenuProc_See_VersionBoard(void) { printf("MenuProc_See_VersionBoard\n"); }
void MenuProc_Cfg_ClrRec(void) { printf("MenuProc_Cfg_ClrRec\n"); }
void MenuProc_Cfg_ComPara(void) { printf("MenuProc_Cfg_ComPara\n"); }
void MenuProc_Cfg_EditIP(void) { printf("MenuProc_Cfg_EditIP\n"); }
void MenuProc_Cfg_EditSntp(void) { printf("MenuProc_Cfg_EditSntp\n"); }
void MenuProc_Cfg_CellConf(void) { printf("MenuProc_Cfg_CellConf\n"); }
void MenuProc_See_RecSOE(void) { printf("MenuProc_See_RecSOE\n"); }
void MenuProc_See_RecAct(void) { printf("MenuProc_See_RecAct\n"); }
void MenuProc_See_RecOpt(void) { printf("MenuProc_See_RecOpt\n"); }
void MenuProc_See_RecAlm(void) { printf("MenuProc_See_RecAlm\n"); }
void MenuProc_See_RecStart(void) { printf("MenuProc_See_RecStart\n"); }
void MenuProc_See_RecYK(void) { printf("MenuProc_See_RecYK\n"); }
void MenuProc_See_RecChk(void) { printf("MenuProc_See_RecChk\n"); }
void MenuProc_See_RecRun(void) { printf("MenuProc_See_RecRun\n"); }
void MenuProc_See_RecFault(void) { printf("MenuProc_See_RecFault\n"); }
void MenuProc_YC_SetSqValue(void) { printf("MenuProc_YC_SetSqValue\n"); }
void MenuProc_YC_SetAdjCoe(void) { printf("MenuProc_YC_SetAdjCoe\n"); }
void Menu_NonPfunc(void) {}
void MenuProc_AllInf_Default(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Para_Default(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Set_Default(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Resume_Soft(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_CellDef(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_ShowAnaType(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Dbg_XuYX(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Dbg_XuYC(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Dbg_XuEvent(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Dbg_Relay(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_VersionBoard(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_ClrRec(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_ComPara(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_EditIP(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_EditSntp(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_Cfg_CellConf(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecSOE(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecAct(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecOpt(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecAlm(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecStart(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecYK(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecChk(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecRun(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_See_RecFault(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_YC_SetSqValue(void) { MenuPage_TriggerCurrentAction(); }
void MenuProc_YC_SetAdjCoe(void) { MenuPage_TriggerCurrentAction(); }