
关于
Robius 事件和动作处理专家,用于构建响应式跨平台 Rust UI 应用。
name: robius-event-action description: | 关键:用于Robius事件和动作模式。触发条件: custom action, MatchEvent, post_action, cx.widget_action, handle_actions, DefaultNone, widget action, event handling risk: unknown source: community
Robius 事件和动作模式技能
基于Robrix和Moly代码库的Makepad应用程序中事件处理和动作模式的最佳实践。
源代码库:
- Robrix:Matrix聊天客户端 - MessageAction、RoomsListAction、AppStateAction
- Moly:AI聊天应用 - StoreAction、ChatAction、NavigationAction、Timer模式
何时使用
在以下情况使用此技能:
- 在Makepad中实现自定义动作
- 在widget中处理事件
- 在App中集中处理动作
- Widget间通信
- 关键词:makepad action、makepad event、widget action、handle_actions、cx.widget_action
自定义动作模式
定义领域特定动作
use makepad_widgets::*;
/// Message widget 发出的动作
#[derive(Clone, DefaultNone, Debug)]
pub enum MessageAction {
/// 用户想要对消息做出反应
React { details: MessageDetails, reaction: String },
/// 用户想要回复消息
Reply(MessageDetails),
/// 用户想要编辑消息
Edit(MessageDetails),
/// 用户想要删除消息
Delete(MessageDetails),
/// 用户请求打开上下文菜单
OpenContextMenu { details: MessageDetails, abs_pos: DVec2 },
/// 必需的默认变体
None,
}
/// 与消息动作关联的数据
#[derive(Clone, Debug)]
pub struct MessageDetails {
pub room_id: OwnedRoomId,
pub event_id: OwnedEventId,
pub content: String,
pub sender_id: OwnedUserId,
}
从Widget发出动作
impl Widget for Message {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
self.view.handle_event(cx, event, scope);
let area = self.view.area();
match event.hits(cx, area) {
Hit::FingerDown(_fe) => {
cx.set_key_focus(area);
}
Hit::FingerUp(fe) => {
if fe.is_over && fe.is_primary_hit() && fe.was_tap() {
// 发出widget动作
cx.widget_action(
self.widget_uid(),
&scope.path,
MessageAction::Reply(self.get_details()),
);
}
}
_ => {}
}
}
}
在App中处理动作
impl MatchEvent for App {
fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) {
for action in actions {
// 使用 cast! 宏匹配动作类型
match action.as_widget_action().cast() {
MessageAction::Reply(details) => {
// 处理回复动作
self.handle_reply(cx, details);
}
MessageAction::React { details, reaction } => {
// 处理反应动作
self.handle_reaction(cx, details, reaction);
}
_ => {}
}
}
}
}
关键模式
- DefaultNone派生:所有动作枚举必须派生
DefaultNone并包含None变体 - Widget UID:使用
self.widget_uid()标识动作来源 - Scope路径:传递
&scope.path用于动作路由 - cast!宏:在
handle_actions中使用cast()匹配动作类型 - post_action:用于从非widget上下文发出动作
兼容工具
Claude CodeCursor
标签
前端开发