Skip to main content Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/BEKO2210/Firstbrain --skill robius-event-actionDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository
Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation
name robius-event-action description | type skill created 2026-02-27T00:00:00.000Z domain productivity category developer-experience risk unknown source community tags ["skill","productivity","developer-experience","robius","event","action"]
Robius Event and Action Patterns Skill
Best practices for event handling and action patterns in Makepad applications based on Robrix and Moly codebases.
Source codebases:
Robrix : Matrix chat client - MessageAction, RoomsListAction, AppStateAction
Moly : AI chat application - StoreAction, ChatAction, NavigationAction, Timer patterns
When to Use
Use this skill when:
Implementing custom actions in Makepad
Handling events in widgets
Centralizing action handling in App
Widget-to-widget communication
Keywords: makepad action, makepad event, widget action, handle_actions, cx.widget_action
Custom Action Pattern
Defining Domain-Specific Actions
use makepad_widgets::*;
#[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,
}
Emitting Actions from Widgets 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 () {
cx.widget_action (
self .widget_uid (),
&scope.path,
MessageAction::Reply (self .get_details ()),
);
}
}
Hit::FingerLongPress (lpe) => {
cx.widget_action (
self .widget_uid (),
&scope.path,
MessageAction::OpenContextMenu {
details: self .get_details (),
abs_pos: lpe.abs,
},
);
}
_ => {}
}
}
}
Centralized Action Handling in App
Using MatchEvent Trait impl MatchEvent for App {
fn handle_startup (&mut self , cx: &mut Cx) {
self .initialize (cx);
}
fn handle_actions (&mut self , cx: &mut Cx, actions: &Actions) {
for action in actions {
if let Some (action) = action.downcast_ref::<LoginAction>() {
match action {
LoginAction::LoginSuccess => {
self .app_state.logged_in = true ;
self .update_ui_visibility (cx);
}
LoginAction::LoginFailure (error) => {
self .show_error (cx, error);
}
}
continue ;
}
if let MessageAction ::OpenContextMenu { details, abs_pos } =
action.as_widget_action ().cast ()
{
self .show_context_menu (cx, details, abs_pos);
continue ;
}
match action.downcast_ref () {
Some (AppStateAction::RoomFocused (room)) => {
self .app_state.selected_room = Some (room.clone ());
continue ;
}
Some (AppStateAction::NavigateToRoom { destination }) => {
self .navigate_to_room (cx, destination);
continue ;
}
_ => {}
}
match action.downcast_ref () {
Some (ModalAction::Open { kind }) => {
self .ui.modal (ids!(my_modal)).open (cx);
continue ;
}
Some (ModalAction::Close { was_internal }) => {
if *was_internal {
self .ui.modal (ids!(my_modal)).close (cx);
}
continue ;
}
_ => {}
}
}
}
}
impl AppMain for App {
fn handle_event (&mut self , cx: &mut Cx, event: &Event) {
self .match_event (cx, event);
let scope = &mut Scope::with_data (&mut self .app_state);
self .ui.handle_event (cx, event, scope);
}
}
Action Types
Widget Actions (UI Thread) Emitted by widgets, handled in the same frame:
cx.widget_action (
self .widget_uid (),
&scope.path,
MyAction::Something,
);
if let MyAction ::Something = action.as_widget_action ().cast () {
}
if let Some (uid) = action.as_widget_action ().widget_uid () {
if uid == my_expected_uid {
if let MyAction ::Something = action.as_widget_action ().cast () {
}
}
}
Posted Actions (From Async) Posted from async tasks, received in next event cycle:
Cx::post_action (DataFetchedAction { data });
SignalToUI::set_ui_signal ();
if let Some (action) = action.downcast_ref::<DataFetchedAction>() {
self .process_data (&action.data);
}
Global Actions For app-wide state changes:
cx.action (NavigationAction::GoBack);
if let Some (NavigationAction::GoBack) = action.downcast_ref () {
self .navigate_back (cx);
}
Event Handling Patterns
Hit Testing impl Widget for MyWidget {
fn handle_event (&mut self , cx: &mut Cx, event: &Event, scope: &mut 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 () {
if fe.was_tap () {
}
if fe.was_long_press () {
}
}
}
Hit::FingerMove (fe) => {
}
Hit::FingerHoverIn (_) => {
self .animator_play (cx, id!(hover.on));
}
Hit::FingerHoverOut (_) => {
self .animator_play (cx, id!(hover.off));
}
Hit::FingerScroll (se) => {
}
_ => {}
}
}
}
Keyboard Events fn handle_event (&mut self , cx: &mut Cx, event: &Event, scope: &mut Scope) {
if let Event ::KeyDown (ke) = event {
match ke.key_code {
KeyCode::Return if !ke.modifiers.shift => {
self .submit (cx);
}
KeyCode::Escape => {
self .cancel (cx);
}
KeyCode::KeyC if ke.modifiers.control || ke.modifiers.logo => {
self .copy_to_clipboard (cx);
}
_ => {}
}
}
}
Signal Events For handling async updates:
fn handle_event (&mut self , cx: &mut Cx, event: &Event, scope: &mut Scope) {
if let Event ::Signal = event {
while let Some (update) = PENDING_UPDATES.pop () {
self .apply_update (cx, update);
}
}
}
Action Chaining Pattern Widget emits action → Parent catches and re-emits with more context:
cx.widget_action (
self .widget_uid (),
&scope.path,
ItemAction::Selected (item_id),
);
if let ItemAction ::Selected (item_id) = action.as_widget_action ().cast () {
cx.widget_action (
self .widget_uid (),
&scope.path,
ListAction::ItemSelected {
list_id: self .list_id.clone (),
item_id,
},
);
}
Best Practices
Use DefaultNone derive : All action enums must have a None variant
Use continue after handling : Prevents unnecessary processing
Downcast pattern for async actions : Posted actions are not widget actions
Widget action cast for UI actions : Use as_widget_action().cast()
Always call SignalToUI::set_ui_signal() : After posting actions from async
Centralize in App::handle_actions : Keep action handling in one place
Use descriptive action names : MessageAction::Reply not MessageAction::Action1
Reference Files
references/action-patterns.md - Additional action patterns (Robrix)
references/event-handling.md - Event handling reference (Robrix)
references/moly-action-patterns.md - Moly-specific patterns
Store-based action forwarding
Timer-based retry pattern
Radio button navigation
External link handling
Platform-conditional actions (#[cfg])
UiRunner event handling
Connections
Domain: [[Produktivitaet & Werkzeuge]]
Kategorie: [[Developer Experience]]
Navigation: [[Skills Uebersicht]], [[Home]]