事件系统
HoneyGUI Visual Designer 的事件系统采用 事件-动作 (Event-Action) 模式,用户可以在设计器中为组件配置事件响应,无需编写代码即可实现常见交互逻辑。
核心概念
事件 (Event)
组件触发的交互行为。
动作 (Action)
事件触发后执行的操作,一个事件可以配置多个动作,按顺序执行。
消息 (Message)
全局广播机制,组件可以发送消息,其他组件可以监听并响应。
UI 设计变更
属性面板标签页统一
原有的视图切换功能已统一到 Event-Action 体系中:
属性界面
属性: 组件基础属性(位置、大小、样式等)
事件: Event-Action 配置(包含原视图切换功能)
事件类型 (Event Types)
通用事件(所有组件支持)
事件名 |
标识符 |
说明 |
|---|---|---|
单击 |
|
点击后抬起触发 |
长按 |
|
按住超过阈值时间触发 |
按下 |
|
手指按下时触发 |
抬起 |
|
手指抬起时触发 |
滑动事件(容器组件支持)
事件名 |
标识符 |
说明 |
支持组件 |
|---|---|---|---|
左滑 |
|
向左滑动触发 |
hg_view, hg_window |
右滑 |
|
向右滑动触发 |
hg_view, hg_window |
上滑 |
|
向上滑动触发 |
hg_view, hg_window |
下滑 |
|
向下滑动触发 |
hg_view, hg_window |
状态事件(特定组件支持)
事件名 |
标识符 |
说明 |
支持组件 |
|---|---|---|---|
值改变 |
|
值变化时触发 |
hg_slider, hg_progressbar, hg_input |
选中改变 |
|
选中状态变化 |
hg_checkbox, hg_switch, hg_radio |
生命周期事件(容器组件支持)
事件名 |
标识符 |
说明 |
支持组件 |
|---|---|---|---|
显示 |
|
组件显示时触发 |
hg_view, hg_window |
隐藏 |
|
组件隐藏时触发 |
hg_view, hg_window |
消息事件(所有组件支持)
事件名 |
标识符 |
说明 |
|---|---|---|
消息监听 |
|
收到指定消息时触发 |
组件支持的事件
组件类型 |
支持的事件 |
|---|---|
hg_view |
onClick, onLongPress, onTouchDown, onTouchUp, onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown, onShow, onHide, onMessage |
hg_window |
onClick, onLongPress, onTouchDown, onTouchUp, onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown, onShow, onHide, onMessage |
hg_button |
onClick, onLongPress, onTouchDown, onTouchUp, onMessage |
hg_image |
onClick, onLongPress, onTouchDown, onTouchUp, onMessage |
hg_label |
onClick, onLongPress, onMessage |
hg_switch |
onClick, onCheckedChange, onMessage |
hg_checkbox |
onClick, onCheckedChange, onMessage |
hg_radio |
onClick, onCheckedChange, onMessage |
hg_slider |
onClick, onValueChange, onMessage |
hg_progressbar |
onClick, onValueChange, onMessage |
hg_input |
onClick, onValueChange, onMessage |
hg_video |
onClick, onLongPress, onMessage |
hg_3d |
onClick, onLongPress, onMessage |
动作类型 (Action Types)
视图切换动作
动作名 |
标识符 |
参数 |
说明 |
|---|---|---|---|
跳转界面 |
|
target, switchOutStyle, switchInStyle |
带动画的视图切换 |
switchOutStyle 选项:
平移:
SWITCH_OUT_TO_LEFT/RIGHT/TOP/BOTTOM_USE_TRANSLATION立方体:
SWITCH_OUT_TO_LEFT/RIGHT/TOP/BOTTOM_USE_CUBE其他:
SWITCH_OUT_NONE_ANIMATION,SWITCH_OUT_ANIMATION_FADE
switchInStyle 选项:
平移:
SWITCH_IN_FROM_LEFT/RIGHT/TOP/BOTTOM_USE_TRANSLATION立方体:
SWITCH_IN_FROM_LEFT/RIGHT/TOP/BOTTOM_USE_CUBE其他:
SWITCH_IN_NONE_ANIMATION,SWITCH_IN_ANIMATION_FADE
消息动作
动作名 |
标识符 |
参数 |
说明 |
|---|---|---|---|
发送消息 |
|
message |
广播消息 |
自定义动作
动作名 |
标识符 |
参数 |
说明 |
|---|---|---|---|
调用函数 |
|
functionName |
调用用户自定义 C 函数 |
消息系统 (Message System)
概念
消息系统提供组件间的解耦通信机制:
发送方: 通过
sendMessage动作广播消息接收方: 通过
onMessage事件监听消息
使用场景
跨界面通信: 界面 A 的操作影响界面 B 的显示
全局状态同步: 多个组件响应同一状态变化
模块解耦: 避免组件间直接引用
数据结构
HML 中的事件配置
按钮点击跳转:
<hg_button id="btn1" x="10" y="10" w="100" h="40" text="Click">
<events>
<event type="onClick">
<action type="switchView" target="screen2" />
</event>
</events>
</hg_button>
视图滑动切换(原 view_switch 功能):
<hg_view id="main_view" x="0" y="0" w="480" h="272">
<events>
<event type="onSwipeLeft">
<action type="switchView" target="screen2"
switchOutStyle="SWITCH_OUT_TO_LEFT_USE_TRANSLATION"
switchInStyle="SWITCH_IN_FROM_RIGHT_USE_TRANSLATION" />
</event>
</events>
</hg_view>
TypeScript 类型定义
// 事件类型
type EventType =
// 通用事件
| 'onClick' | 'onLongPress' | 'onTouchDown' | 'onTouchUp'
// 滑动事件
| 'onSwipeLeft' | 'onSwipeRight' | 'onSwipeUp' | 'onSwipeDown'
// 状态事件
| 'onValueChange' | 'onCheckedChange'
// 生命周期事件
| 'onShow' | 'onHide'
// 消息事件
| 'onMessage';
// 动作类型
type ActionType =
// 视图切换(带动画)
| 'switchView'
// 消息
| 'sendMessage'
// 自定义
| 'callFunction';
// 动作定义
interface Action {
type: ActionType;
target?: string; // 目标组件/界面ID
message?: string; // 消息名(sendMessage 用)
functionName?: string; // 函数名(callFunction 用)
// switchView专用
switchOutStyle?: string; // 退出动画
switchInStyle?: string; // 进入动画
}
// 事件定义
interface EventConfig {
type: EventType;
message?: string; // 仅 onMessage 事件需要
actions: Action[];
}
C 代码生成实现
视图切换 (switchView)
无需生成独立的回调函数,直接在 GUI_VIEW_INSTANCE 宏的 switch_in 回调中使用 gui_view_switch_on_event 注册:
static void main_view_switch_in(gui_view_t *view)
{
// 注册左滑跳转事件
gui_view_switch_on_event(view, "screen2",
SWITCH_OUT_TO_LEFT_USE_TRANSLATION,
SWITCH_IN_FROM_RIGHT_USE_TRANSLATION,
GUI_EVENT_TOUCH_MOVE_LEFT);
// 创建子组件...
}
GUI_VIEW_INSTANCE("main_view", false, main_view_switch_in, main_view_switch_out);
其他事件
将生成回调函数并在组件创建时绑定:
// ui/main_ui.c
gui_obj_add_event_cb(btn1, on_btn1_click, GUI_EVENT_CLICKED, NULL);
// callbacks/main_callbacks.c
/* @protected start on_btn1_click */
void on_btn1_click(gui_obj_t *obj) {
// 用户实现逻辑
}
/* @protected end on_btn1_click */
UI 设计
属性面板 - 事件标签页
事件界面
实际使用示例
示例 1: 按钮点击跳转
场景: 点击 下一步 按钮跳转到第二页
HML 配置:
<hg_button id="next_btn" x="190" y="200" w="100" h="40" text="下一步">
<events>
<event type="onClick">
<action type="switchView" target="page2"
switchOutStyle="SWITCH_OUT_TO_LEFT_USE_TRANSLATION"
switchInStyle="SWITCH_IN_FROM_RIGHT_USE_TRANSLATION" />
</event>
</events>
</hg_button>
生成的 C 代码:
// 在 callbacks 文件中生成回调
void on_next_btn_click(gui_obj_t *obj) {
gui_switch_app(gui_current_app(), gui_app_get_by_name("page2"));
}
示例 2: 左滑切换界面
场景: 在主界面左滑进入设置界面
HML 配置:
<hg_view id="main_view" x="0" y="0" w="480" h="272">
<events>
<event type="onSwipeLeft">
<action type="switchView" target="settings"
switchOutStyle="SWITCH_OUT_TO_LEFT_USE_TRANSLATION"
switchInStyle="SWITCH_IN_FROM_RIGHT_USE_TRANSLATION" />
</event>
</events>
</hg_view>
生成的 C 代码:
static void main_view_switch_in(gui_view_t *view)
{
gui_view_switch_on_event(view, "settings",
SWITCH_OUT_TO_LEFT_USE_TRANSLATION,
SWITCH_IN_FROM_RIGHT_USE_TRANSLATION,
GUI_EVENT_TOUCH_MOVE_LEFT);
// ...
}
示例 3: 消息通信
场景: 按钮发送消息,其他组件监听并响应
发送方 HML:
<hg_button id="refresh_btn" x="10" y="10" w="100" h="40" text="刷新">
<events>
<event type="onClick">
<action type="sendMessage" message="refresh_data" />
</event>
</events>
</hg_button>
接收方 HML:
<hg_label id="data_label" x="10" y="60" w="200" h="30" text="数据">
<events>
<event type="onMessage" message="refresh_data">
<action type="callFunction" functionName="on_refresh_data" />
</event>
</events>
</hg_label>
示例 4: 自定义函数调用
场景: 按钮点击执行复杂业务逻辑
HML 配置:
<hg_button id="save_btn" x="10" y="10" w="100" h="40" text="保存">
<events>
<event type="onClick">
<action type="callFunction" functionName="save_settings" />
</event>
</events>
</hg_button>
用户实现:
// callbacks/main_callbacks.c
/* @protected start save_settings */
void save_settings(gui_obj_t *obj) {
// 读取各种设置
bool wifi_enabled = get_wifi_switch_state();
int brightness = get_brightness_value();
// 保存到闪存
flash_write_config(wifi_enabled, brightness);
// 显示提示
show_toast("设置已保存");
}
/* @protected end save_settings */
最佳实践
事件命名规范
使用清晰的函数名:
on_save_click,handle_login包含事件类型:
on_button_click,on_slider_change描述业务逻辑:
save_user_settings,refresh_data
性能优化
避免在频繁触发的事件中执行耗时操作
使用消息系统解耦复杂交互
合理使用防抖和节流
调试技巧
在回调函数中添加日志输出
使用断点调试验证事件流程
检查生成的 C 代码确认事件绑定