当前位置: 首页 > news >正文

WouoUI-Page移植

WouoUI-Page移植

  • 一,移植文件
  • 二,菜单配置
  • 三,缓存刷新函数
  • 四,初始化
      • 1,包含头文件
      • 2,在 main 函数中进行初始化
      • 3,修改 Oled 显示任务函数
      • 4,解决命名冲突 (如果需要):
      • 5,绑定按键操作
      • 6,使用 u8g2 提高刷新效率
  • 五,应用

一,移植文件

仅仅将WouoUI-Page的Csource资源移植到项目中

二,菜单配置

在WouoUI_conf.h中进行,这个配置文件允许你定制菜单的外观(屏幕尺寸、字体、图标、间距等)和行为,而无需修改框架的核心代码,提高了可维护性和易用性

三,缓存刷新函数

这个函数将WouoUI-Page的内容发送到屏幕上

WouoUI-Page 菜单框架本身不直接操作硬件,它将绘制好的菜单界面存储在一个缓冲区中。你需要提供一个函数,该函数能接收这个缓冲区,并将其内容发送到 OLED 屏幕上显示出来。函数的接口由 WouoUI-Page 定义

原因: 这是框架与具体显示驱动解耦的关键。WouoUI-Page 只负责生成菜单的像素数据,而如何将这些数据显示到屏幕上,则由用户提供的这个"刷新函数"决定。这样,WouoUI-Page 就可以适配各种不同的 OLED 驱动(如基础驱动、u8g2 驱动等)。

下面是基于基础驱动写的缓存刷新函数

#include "oled.h" // 假设你的基础驱动头文件是 oled.h/*** @brief 将 WouoUI 缓冲区的数据发送到 OLED 显示* @param buff WouoUI 提供的缓冲区指针,大小为 [高度/8][宽度] 或 [4][128] for 128x32*/
void OLED_SendBuff(uint8_t buff[4][128])
{  // 遍历每一页 (0-3)for(uint8_t page = 0; page < 4; page++)  {  // 设置 OLED 的页地址OLED_Write_cmd(0xb0 + page); // 0xB0 - 0xB3// 设置 OLED 的列地址 (从第 0 列开始)OLED_Write_cmd(0x00); // 低半字节列地址OLED_Write_cmd(0x10); // 高半字节列地址 (0x10 | 0 = 0)// 循环写入该页的 128 列数据for (uint8_t column = 0; column < 128; column++)  {// 从 WouoUI 缓冲区取数据,并通过基础驱动的数据写入函数发送OLED_Write_data(buff[page][column]); }} 
}

注意:此处的 OLED_Write_cmdOLED_Write_data 是你基础 OLED 驱动库提供的函数,你需要根据实际情况调整。缓冲区 buff 的维度也需要与你的屏幕和 WouoUI 配置匹配。

四,初始化

1,包含头文件

#include "WouoUI.h"      // WouoUI 核心框架
#include "WouoUI_user.h" // 用户自定义的菜单结构和回调函数 (通常需要用户创建或修改)

2,在 main 函数中进行初始化

// 假设你的缓存刷新函数是 OLED_SendBuff
extern void OLED_SendBuff(uint8_t buff[4][128]);int main(void)
{// ... 系统初始化 ...OLED_Init(); // 假设调用基础驱动的初始化// 或者 u8g2 初始化序列...// --- WouoUI 初始化 ---// 1. 选择默认UI (如果 WouoUI_user.c 中定义了多个 UI 实例)WouoUI_SelectDefaultUI(); // 2. 绑定缓存刷新函数 (关键步骤)//    将你实现的 OLED_SendBuff 函数地址传递给 WouoUI 框架WouoUI_AttachSendBuffFun(OLED_SendBuff); // 3. 初始化用户菜单 (执行 WouoUI_user.c/h 中定义的菜单结构初始化)TestUI_Init(); // 函数名取决于用户文件,通常是初始化页面、列表项等// --- WouoUI 初始化完成 ---

原因: 这是将 WouoUI 框架与你的系统连接起来的关键步骤:
WouoUI_SelectDefaultUI(): (如果需要)选择要激活的菜单实例。
WouoUI_AttachSendBuffFun(): 极其重要。告诉 WouoUI 框架当它完成菜单绘制后,应该调用哪个函数 (OLED_SendBuff) 来将缓冲区内容刷新到屏幕上。
TestUI_Init() (或类似名称): 执行用户定义的菜单初始化代码,这部分通常在 WouoUI_user.c/h 中实现,用于创建菜单页面、添加列表项、绑定回调函数等。没有这一步,菜单就是空的。

3,修改 Oled 显示任务函数

void oled_task(void)
{// 调用 WouoUI 处理函数,参数为两次调用之间的间隔时间 (ms)// 这个函数会处理按键输入、更新菜单状态、绘制缓冲区WouoUI_Proc(10); // 假设任务每 10ms 调用一次
}

性能提示:如果 WouoUI_Proc() 执行时间较长或包含阻塞操作(如效率低的刷屏函数),可能会导致系统卡顿。参考文档建议可以将其放在定时器中断回调中执行(例如 10ms 定时中断),以保证固定的调用频率。但这需要注意中断服务程序应尽可能快地执行完毕。

// 示例:在 TIM2 中断回调中调用 (需要先配置并启动 TIM2)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM2) // 确保是 TIM2 中断{WouoUI_Proc(10); // 假设 TIM2 配置为 10ms 中断一次}
}// 在 main 函数中初始化后启动定时器中断
// HAL_TIM_Base_Start_IT(&htim2);

4,解决命名冲突 (如果需要):

参考文档提到,如果基础 OLED 驱动 (oled.c, oledfont.h) 中有与 WouoUI 库(或其依赖的库)冲突的名称(例如 F8X16 字体),需要重命名其中一个以解决冲突。例如,将驱动中的 F8X16 改为 Oled_F8X16
原因: C 语言不允许在同一作用域内存在同名的函数或全局变量。如果两个不同的库使用了相同的名称,编译器会报错。重命名是解决此问题的常用方法。

5,绑定按键操作

菜单需要响应用户的按键输入(上、下、左、右、确认、返回等)才能进行导航和交互。WouoUI-Page 提供了一个消息队列机制来接收按键事件。

WOUOUI_MSG_QUE_SEND() 函数可以将消息类型(用户的操作)发送给菜单

typedef enum {msg_up = 0x00,   // 上移 / 上一个msg_down,        // 下移 / 下一个msg_left,        // 左移 / 上一个 (混合模式)msg_right,       // 右移 / 下一个 (混合模式)msg_click,       // 确认 / 点击msg_return,      // 返回 / 退出msg_home,        // 回主界面 (可能未完全实现)msg_none = 0xFF, // 无操作
} InputMsg;

6,使用 u8g2 提高刷新效率

如果在实际使用中感觉菜单响应迟缓、不够流畅,尤其是在菜单切换或滚动时,这很可能是因为你在 6.3 节实现的 OLED_SendBuff 函数效率不高。

原因: 基础的 OLED 驱动通常是逐字节或逐页发送数据,并且每次发送前可能需要设置页地址和列地址,这涉及到多次 I2C 命令传输,相对耗时。而像 u8g2 这样的图形库,其底层通信回调 (u8x8_byte_hw_i2c) 通常经过优化,能够更高效地批量发送数据。此外,u8g2 的 SendBuffer 函数内部可能包含了更优化的传输策略

#include "u8g2.h" // 需要包含 u8g2 头文件
#include  // 需要包含 string.h 以使用 memcpy// 假设全局 u8g2 实例变量名为 u8g2
extern u8g2_t u8g2;/*** @brief 使用 u8g2 的缓冲区和发送函数来刷新 WouoUI 的内容* @param buff WouoUI 提供的缓冲区指针,大小 [4][128] for 128x32*/
void OLED_SendBuff(uint8_t buff[4][128])
{// 1. 获取 u8g2 内部 RAM 缓冲区的指针uint8_t *u8g2_buffer = u8g2_GetBufferPtr(&u8g2);// 2. 将 WouoUI 缓冲区的内容完整地复制到 u8g2 的缓冲区中//    注意:确保两个缓冲区大小完全一致 (4 * 128 bytes)memcpy(u8g2_buffer, buff, 4 * 128);// 3. 调用 u8g2 的发送函数,将 u8g2 缓冲区的内容发送到 OLED//    这将使用 u8g2 配置的高效 I2C 回调函数来完成传输u8g2_SendBuffer(&u8g2);
}

原因: 这个修改利用了 u8g2 可能更优化的底层 I2C/SPI 传输实现。通过 memcpy 将 WouoUI 生成的图像数据快速复制到 u8g2 的 RAM 缓冲区,然后调用 u8g2_SendBuffer(),让 u8g2 接管实际的硬件发送过程,从而可能获得更流畅的菜单体验。

五,应用

md文件和user文件 交给ai
初始化的TestUI_Init(); 修改
7. 实战:WouoUI-Page 应用开发指南
完成了 WouoUI-Page 库的底层移植后,现在我们来深入了解如何在应用层使用它来构建你的用户界面。本指南旨在帮助你快速上手。

7.1 基本概念
在开始编码之前,理解 WouoUI-Page 的几个核心概念非常重要:

页面 (Page): UI 的基本单元,可以是占据整个屏幕的全屏页面(如标题页 TitlePage, 列表页 ListPage, 波形页 WavePage),也可以是覆盖在当前页面之上的弹窗页面(如消息窗 MsgWin, 确认窗 ConfWin, 数值调节窗 ValWin, 旋钮调节窗 SpinWin, 列表选择窗 ListWin)。每个页面都有其类型 (PageType) 和特定的处理逻辑。
选项 (Option): 页面上可供用户交互的元素。通常,一个页面的内容由一个 Option 结构体数组定义。Option 结构体包含了选项的显示文本 (text)、可能关联的内容字符串 (content)、关联的数值 (val) 等信息。text 字符串的第一个字符往往具有特殊含义,决定了该选项的基本行为:
-: 仅用作标题或分隔符,通常不可选中。
+: 点击后通常用于跳转到另一个指定的页面。
!: 点击后通常用于触发一个动作或弹出消息窗口。
~: 点击后通常打开一个数值调节弹窗 (ValWin 或 SpinWin),让用户修改此选项关联的 val 值。
@: 用于创建一个二值(开/关)选择框,点击切换状态,状态通常也存储在 val 中 (0 或 1)。
(其他字符): 普通的可选中文本项。
消息 (InputMsg): 代表用户的输入操作,例如按键按下。WouoUI 定义了一组标准输入消息,如 msg_up (上), msg_down (下), msg_left (左), msg_right (右), msg_click (确认/点击), msg_return (返回)。你需要将你的硬件按键事件映射到这些消息。
回调函数 (CallBackFunc): 你可以为每个页面(全屏页或弹窗)绑定一个回调函数。当该页面处于活动状态并接收到用户输入消息时,这个回调函数就会被 WouoUI 框架自动调用。你可以在回调函数中编写该页面的具体响应逻辑,例如:根据用户点击的选项跳转到新页面、修改选项的值、弹出确认窗口、执行特定硬件操作等。回调函数的原型通常是 bool CallBackFunc(const Page *cur_page_addr, InputMsg msg)。
7.2 初始化 WouoUI
在你的应用程序启动代码中(例如 main 函数或专门的初始化函数),需要执行一系列步骤来初始化 WouoUI 框架,使其准备好工作。

// 假设在你的 Application_Init() 函数中
#include “WouoUI.h”
#include “WouoUI_user.h” // 必须包含你定义的菜单结构头文件
#include “oled.h” // 假设你的屏幕驱动接口在这里

// 假设你的屏幕刷新函数是这个 (已在移植部分实现)
extern void OLED_SendBuff(uint8_t buff[4][128]);

void Application_Init() {
// … 其他硬件初始化代码 (GPIO, Clock, I2C, OLED Driver Init …) …
OLED_Init(); // 确保 OLED 驱动已初始化

// --- WouoUI 初始化序列 ---
// 1. 选择默认 UI 配置 (如果 WouoUI_user.c 中有多个 UI 定义,可选)
WouoUI_SelectDefaultUI(); // 2. 绑定屏幕刷新函数 (关键!)
//    将你实现的 `OLED_SendBuff` 函数指针传递给 WouoUI
WouoUI_AttachSendBuffFun(OLED_SendBuff); // 3. 清空 WouoUI 内部缓冲区并首次发送到屏幕 (可选, 用于清屏)
//    这会确保屏幕初始状态是干净的
WouoUI_BuffClear(); // 清空 WouoUI 的 RAM 缓冲区
WouoUI_BuffSend();  // 调用 OLED_SendBuff 将空缓冲区刷到屏幕// 4. 初始化你定义的所有 UI 页面 (关键!)
//    这会调用 WouoUI_user.c 中实现的 TestUI_Init() (或其他自定义名称) 函数
//    该函数负责创建所有页面实例、定义选项、绑定回调等
TestUI_Init(); // 5. 设置默认绘图颜色 (可选)
//    对于单色屏,1 通常代表前景色 (点亮的像素)
WouoUI_GraphSetPenColor(1); 
// --- WouoUI 初始化完成 ---

}
关键点解释:

WouoUI_AttachSendBuffFun(OLED_SendBuff): 这是连接 WouoUI 内部渲染结果和你实际屏幕显示驱动的桥梁,必须正确设置。
TestUI_Init(): 这个函数通常在 WouoUI_user.c 中实现,是你定义整个 UI 结构的核心。没有它,菜单就是空的。
7.3 创建页面 (以列表页为例)
创建 UI 界面的主要工作通常在 WouoUI_user.cWouoUI_user.h 文件中完成。你需要定义页面对象、选项数组,并编写回调函数来处理交互。

步骤 1: 定义页面对象和选项数组 (通常在 .h 或 .c 文件顶部)
// WouoUI_user.h 或 WouoUI_user.c
#include “WouoUI.h”

// — 定义页面实例 —
// 假设我们有一个主页面 (main_page) 和一个列表设置页面 (settings_list_page)
extern TitlePage main_page; // 主页面可能是磁贴类型 (TitlePage)
extern ListPage settings_list_page; // 设置页面是列表类型 (ListPage)

// — 定义设置页面的选项 —
// Option 结构体数组定义了列表页的内容和行为
Option settings_options[] = {
{.text = (char*)“- Settings Menu”}, // 标题项,不可选
{.text = (char*)“! Beep On/Off”}, // 点击触发动作 (通过回调处理)
{.text = (char*)“~ Brightness”, .val=80}, // 点击打开数值调节弹窗, 初始值80
{.text = (char*)“@ Auto Save”, .val=1}, // 二值选择框,初始值为 1 (开)
{.text = (char*)“+ About”}, // 点击跳转到 “About” 页面
{.text = (char*)“-”}, // 分隔符
{.text = (char*)“< Back to Main”}, // 返回项 (也可以用 ‘+’ 跳转或在回调处理返回)
};
// 计算选项数量 (C 语言常用技巧)
#define SETTINGS_OPTIONS_NUM (sizeof(settings_options) / sizeof(Option))

// — 定义共用的弹窗页面实例 (可选, 推荐) —
// 定义一些通用的弹窗实例,可以在多个页面中复用
extern MsgWin common_msg_page; // 用于显示提示信息
extern ConfWin common_conf_page; // 用于显示确认对话框
extern ValWin common_val_page; // 用于调节数值
步骤 2: 定义页面的回调函数 (在 .c 文件中)
回调函数是处理页面交互逻辑的核心。

// WouoUI_user.c
#include “WouoUI_user.h”

// — 设置列表页面的回调函数 —
// 当 settings_list_page 活动时,发生按键输入会调用此函数
bool SettingsListPage_CallBack(const Page cur_page_addr, InputMsg msg) {
// 检查是否是 “确认/点击” 消息
if (msg == msg_click) {
// 获取当前光标选中的是哪个选项
Option
selected_option = WouoUI_ListTitlePageGetSelectOpt(cur_page_addr);

    // --- 根据选中的选项文本执行不同操作 ---if (strcmp(selected_option->text, "! Beep On/Off") == 0) {// 切换蜂鸣器状态 (假设有 Beep_Toggle() 函数)// Beep_Toggle(); // (可选) 弹出提示消息WouoUI_MsgWinPageSetContent(&common_msg_page, (char*)"Beep Toggled!");WouoUI_JumpToPage((PageAddr)cur_page_addr, &common_msg_page); // 跳转到消息弹窗return true; // 返回 true 表示消息已处理} else if (strcmp(selected_option->text, "~ Brightness") == 0) {// 用户点击了亮度调节项,WouoUI 会自动处理跳转到 ValWin// 因为选项文本以 '~' 开头。// 我们可以在 ValWin 的回调中获取最终调节的值,或者让它自动写回// (如果 ValWin 初始化时 auto_set_bg_opt 设置为 true)// (可选) 在跳转前,可以预设 ValWin 的参数WouoUI_ValWinPageSetMinStepMax(&common_val_page, 0, 5, 100); // 设置范围 0-100, 步长 5// 注意:跳转是自动的,无需手动调用 WouoUI_JumpToPage} else if (strcmp(selected_option->text, "@ Auto Save") == 0) {// 用户点击了自动保存选项,WouoUI 会自动切换 val 的值 (0/1)// 并更新界面上的勾选框状态。// 我们可以在这里读取切换后的值 selected_option->val 来执行实际操作// Apply_AutoSave_Setting(selected_option->val);return true; // 消息已处理}else if (strcmp(selected_option->text, "+ About") == 0) {// 用户点击了跳转项,WouoUI 会自动跳转到 'about_page'// (前提是 about_page 已经在 TestUI_Init 中正确初始化)// 跳转是自动的,无需手动调用 WouoUI_JumpToPage}else if (strcmp(selected_option->text, "< Back to Main") == 0) {// 手动跳转回主页面WouoUI_JumpToPage((PageAddr)cur_page_addr, &main_page); return true; // 消息已处理}
} 
// 检查是否是 "返回" 消息
else if (msg == msg_return) {// 在列表页按返回键,跳转回主页面WouoUI_JumpToPage((PageAddr)cur_page_addr, &main_page); return true; // 返回 true 阻止 WouoUI 的默认返回处理 (如果有)
}// 如果这个回调函数没有完全处理该消息 (例如上下移动 msg_up/down),
// 返回 false,让 WouoUI 继续执行其默认处理 (如列表滚动)
return false; 

}
步骤 3: 在 TestUI_Init() 中初始化页面 (在 .c 文件中)
TestUI_Init 函数负责创建所有页面实例,并将它们连接起来。

// WouoUI_user.c

// — 定义页面和弹窗的实例变量 —
// (这些变量需要与 .h 文件中的 extern 声明对应)
TitlePage main_page;
ListPage settings_list_page;
// … 其他页面 …
MsgWin common_msg_page;
ConfWin common_conf_page;
ValWin common_val_page;

// — TestUI_Init 函数 —
void TestUI_Init() {
// (可选) 在这里修改全局 UI 参数,例如动画速度
// g_default_ui_para.ani_param[LIST_ANI] = 300; // 减慢列表动画

// --- 初始化主页面 (假设是磁贴类型) ---
// WouoUI_TitlePageInit(&main_page, MAIN_OPTIONS_NUM, main_options, Setting_loop, MainPage_CallBack); 
// (需要先定义 main_options 和 MainPage_CallBack)// --- 初始化设置列表页面 ---
// 参数: 页面实例指针, 选项数量, 选项数组指针, 页面设置(如循环滚动), 回调函数指针
WouoUI_ListPageInit(&settings_list_page, SETTINGS_OPTIONS_NUM, settings_options, Setting_loop, SettingsListPage_CallBack);// --- 初始化其他页面 (例如 About 页面) ---
// WouoUI_XXXPageInit(&about_page, ...);// --- 初始化共用的弹窗页面 ---
// 这些弹窗通常只需要初始化一次,然后在需要时通过设置内容和跳转来使用
// 消息弹窗: 标题 null, 不模糊背景, 显示 2 秒自动返回, 无回调
WouoUI_MsgWinPageInit(&common_msg_page, NULL, false, 2000, NULL); 
// 确认弹窗: 标题 null, 模糊背景, 阻塞(需用户选Yes/No), 有回调处理结果
WouoUI_ConfWinPageInit(&common_conf_page, NULL, true, true, CommonConfPage_CallBack); 
// 数值弹窗: 标题 null, 默认值0, 范围0-100, 步长1, 自动写回背景选项, 循环, 无回调
WouoUI_ValWinPageInit(&common_val_page, NULL, 0, 0, 100, 1, true, true, NULL); 
// ... 初始化其他弹窗 ...// --- 设置 UI 的主页/起始页 ---
// 告诉 WouoUI 哪个页面是应用程序启动时或按 Home 键时应该显示的页面
p_cur_ui->home_page = &main_page; // 将 main_page 设为主页// --- 设置共用弹窗页面 ---
// 将之前初始化的共用弹窗实例地址告诉 WouoUI 框架
// 这样当选项文本以 '!', '~' 等开头时,框架知道跳转到哪个弹窗
p_cur_ui->msg_win = &common_msg_page;
p_cur_ui->val_win = &common_val_page;
p_cur_ui->conf_win = &common_conf_page;
// ... 设置其他共用弹窗 ...

}
7.4 页面跳转
页面之间的切换主要通过 WouoUI_JumpToPage(PageAddr self_page, PageAddr terminate_page) 函数实现。

self_page: 当前页面的地址。在回调函数中,通常传入其第一个参数 cur_page_addr。
terminate_page: 要跳转到的目标页面的地址(例如 &settings_list_page, &common_msg_page)。
跳转可以在回调函数中根据用户操作显式调用,或者由 WouoUI 根据选项文本的特殊前缀(如 +, ~, !)自动触发。

// 在某个回调函数中,根据条件跳转到设置页面
if (user_action == GO_TO_SETTINGS) {
WouoUI_JumpToPage((PageAddr)cur_page_addr, &settings_list_page);
}
7.5 处理用户输入
自动处理: 对于列表页 (ListPage) 和磁贴页 (TitlePage),WouoUI 会自动处理 msg_up 和 msg_down 消息,实现光标的上下移动(如果设置了循环模式 Setting_loop,则会循环滚动)。
回调函数处理: 你需要在页面的回调函数中捕获关键的交互消息,主要是 msg_click (确认) 和 msg_return (返回),并根据当前选中的选项执行相应逻辑。
获取选中项: 在列表页或磁贴页的回调函数中,使用 WouoUI_ListTitlePageGetSelectOpt(cur_page_addr) 函数可以获取当前光标所在的 Option 结构体的指针,从而访问其 text, val 等成员。
消息传递: 确保你的按键驱动(或中断处理)能够将按键事件转换为正确的 InputMsg,并使用 WOUOUI_MSG_QUE_SEND(msg) 发送到 WouoUI 的消息队列。
7.6 使用弹窗
弹窗是覆盖在当前页面之上的临时页面,用于显示信息、获取用户确认或输入。

定义与初始化: 如 7.3 节所示,在 WouoUI_user.c/h 中定义弹窗页面实例 (MsgWin, ConfWin, ValWin 等),并在 TestUI_Init() 中调用对应的 WouoUI_XXXWinPageInit() 函数进行初始化。通常建议将常用的弹窗设为共用实例 (如 common_msg_page),并在 TestUI_Init 中通过 p_cur_ui->msg_win = &common_msg_page; 等方式将其注册到框架。
触发弹窗:
自动触发: 如果列表项文本以特定字符开头(如 ! 对应 MsgWinConfWin,~ 对应 ValWinSpinWin,@ 触发内置逻辑),WouoUI 会自动跳转到注册的共用弹窗页面。
手动触发: 在任何页面的回调函数中,可以通过调用 WouoUI_JumpToPage((PageAddr)cur_page_addr, &my_specific_popup_page); 来跳转到任何已初始化的弹窗页面。
配置弹窗内容/行为 (跳转前): 在手动跳转到弹窗前,通常需要设置其内容或参数:
WouoUI_MsgWinPageSetContent(&common_msg_page, “Action Done!”); 设置消息内容。
WouoUI_ConfWinPageSetContent(&common_conf_page, “Save Changes?”); 设置确认框的提示文本。
WouoUI_ValWinPageSetMinStepMax(&common_val_page, 0, 10, 100); 设置数值调节范围和步长。
WouoUI_ValWinPageSetCurVal(&common_val_page, current_value); 设置数值调节的初始值。
处理弹窗结果:
MsgWin: 通常用于显示信息,可设置显示一段时间后自动返回 (auto_ret_time 参数)。
ConfWin: 如果设置了回调函数,可以在回调函数中检查 conf_ret 成员 (true 为 Yes, false 为 No) 来获取用户的选择。
ValWin / SpinWin:
如果初始化时设置了 auto_set_bg_opt = true,弹窗关闭时会自动将用户调节好的值写回触发它的那个列表选项的 val 成员。
也可以在弹窗的回调函数中,通过访问页面结构体的 val 成员获取最终值。
ListWin: 在回调函数中检查 sel_str_index 获取用户选择的列表项索引。
7.7 配置 UI 参数 (进阶)
可以通过修改全局结构体变量 g_default_ui_para 中的成员来调整 UI 的一些默认视觉和行为参数。这些修改通常放在 TestUI_Init() 函数的开头,页面初始化之前。

// 在 TestUI_Init() 开头
void TestUI_Init() {
// 示例:加快列表动画速度 (数值越小越快)
g_default_ui_para.ani_param[LIST_ANI] = 150;

// 示例:禁用列表页的循环滚动模式
g_default_ui_para.loop_param[LIST_LOOP] = 0; // 0 表示禁用// 示例:修改弹窗背景模糊程度 (数值越大越模糊?)
g_default_ui_para.blur_param = 5;// ... 然后开始初始化页面 ...
// WouoUI_ListPageInit(...);

}
可配置的参数包括动画速度、循环模式、各种边距、字体、颜色、模糊效果等,具体可查阅 WouoUI_common.h 中 UI_Params 结构体的定义。

7.8 主循环集成
在你的应用程序主循环 (例如 main 函数的 while(1) 或 RTOS 任务循环) 中,需要确保以下几点:

获取用户输入: 持续检测按键状态(或其他输入方式)。
发送消息: 当检测到有效的用户操作时,将其转换为对应的 InputMsg,并使用 WOUOUI_MSG_QUE_SEND(msg) 发送给 WouoUI。
处理 UI: 周期性地调用 WouoUI_Proc(delta_time) 函数。delta_time 是两次调用之间经过的时间(毫秒),用于动画和时间相关的处理。
#include “WouoUI.h”
#include “key_driver.h” // 假设你的按键驱动接口在这里
#include “timing.h” // 假设你的计时函数在这里

uint32_t last_tick = 0; // 用于计算时间间隔

int main(void) {
// … 系统初始化 …
Application_Init(); // 执行之前的 WouoUI 和硬件初始化

last_tick = Get_System_Millis(); // 获取初始时间while (1) {// --- 1. 获取用户输入 ---InputMsg current_msg = Get_Mapped_UserInput(); // 返回 WouoUI 定义的 InputMsg// --- 2. 发送消息 ---if (current_msg != msg_none) {WOUOUI_MSG_QUE_SEND(current_msg);}// --- 3. 计算时间间隔 ---uint32_t current_tick = Get_System_Millis(); uint16_t delta_time = current_tick - last_tick;// 防止时间戳回绕或 delta_time 过大 (根据实际情况调整阈值)if (delta_time == 0 || delta_time > 500) { delta_time = 10; // 提供一个默认或最小间隔}last_tick = current_tick;// --- 4. 处理 UI ---// 可以直接在主循环调用,也可以如前所述放在定时中断或任务中WouoUI_Proc(delta_time); // ... 其他主循环任务 ...
}

}

// — 示例:按键输入映射函数 —
InputMsg Get_Mapped_UserInput() {
if (Is_KeyUp_Pressed_Event()) return msg_up;
if (Is_KeyDown_Pressed_Event()) return msg_down;
if (Is_KeyLeft_Pressed_Event()) return msg_left;
if (Is_KeyRight_Pressed_Event()) return msg_right;
if (Is_KeyConfirm_Pressed_Event()) return msg_click;
if (Is_KeyBack_Pressed_Event()) return msg_return;
return msg_none; // 没有有效按键事件
}
7.9 简单示例回顾
结合以上步骤,一个最简单的应用流程如下:

硬件和 WouoUI 初始化: 在 Application_Init() 中完成屏幕驱动初始化、绑定 OLED_SendBuff、调用 TestUI_Init
定义页面和选项: 在 WouoUI_user.c/.h 中定义你的页面实例(如 main_page, settings_list_page)、选项数组 (Option settings_options[] = {…}) 和页面回调函数 (SettingsListPage_CallBack)。
初始化页面: 在 WouoUI_user.cTestUI_Init() 函数中,调用 WouoUI_ListPageInit(), WouoUI_TitlePageInit() 等函数创建页面实例,设置主页,注册共用弹窗。
主循环:
检测按键输入 -> Get_Mapped_UserInput()
发送 WouoUI 消息 -> WOUOUI_MSG_QUE_SEND()
处理 UI 状态和渲染 -> WouoUI_Proc()
页面逻辑: 在页面的回调函数中,响应 msg_clickmsg_return,根据选中的选项 WouoUI_ListTitlePageGetSelectOpt(),使用 WouoUI_JumpToPage() 进行页面切换或弹出窗口,或者执行其他应用逻辑。
希望这份详细的应用开发指南能帮助你更好地使用 WouoUI-Page 框架构建嵌入式菜单系统!如有疑问,请仔细阅读 WouoUI 源码中的注释,并参考其提供的 WouoUI_user.c 示例代码。

©

http://www.dtcms.com/a/270387.html

相关文章:

  • Java-Collections、Map
  • H3初识——入门介绍之常用中间件
  • 11款常用C++在线编译与运行平台推荐与对比
  • ffmpeg 中config 文件一些理解
  • Flutter基础(前端教程②-卡片列表)
  • study_WebView介绍
  • MYSQL进阶知识
  • 在keil中使用stlink下载程序报错Invalid ROM Table
  • Day07_C语言IO进程线程(重难点)
  • TensorFlow 和PyTorch的全方位对比和选择建议
  • Latex几种常用的花体
  • [2-02-02].第04节:环境搭建 - Linux搭建ES集群环境
  • [RPA] 影刀RPA基本知识
  • Kafka多组消费:同一Topic,不同Group ID
  • NV298NV312美光固态闪存NW639NW640
  • 基于mysqlfrm工具解析mysql数据结构文件frm表结构和数据库版本信息
  • 【Nginx】Nginx代理WebSocket
  • 扣子Coze远程连接数据库插件
  • C语言基础(1)
  • 【C++】AVL树底层思想 and 大厂面试
  • Python 的内置函数 slice
  • 为什么elementui的<el-table-column label=“名称“ prop=“name“ label不用写成:label
  • RS-232协议与RS485协议详解
  • [Backlog] 命令行界面CLI vs Web界面及服务端
  • 快手电商要投入多少钱?快手电商入驻条件和费用
  • 分布式无线工业数据采集终端应用场景简析
  • POI报表
  • Paimon本地表查询引擎LocalTableQuery详解
  • Mybits-plus 表关联查询,嵌套查询,子查询示例演示
  • 使用策略模式 + 自动注册机制来构建旅游点评系统的搜索模块