lgui_core/core/component/runtime/
action.rs1use super::{
2 input::{event_target_ids, interaction_state_target_ids},
3 *,
4};
5
6impl UiRuntime {
7 pub fn handle_default_action(
8 &mut self,
9 tree: &HostTree,
10 pending: UiDefaultAction,
11 ) -> RuntimeOutput {
12 if pending.action.id().as_str() == FOCUS_TRAVERSAL_ACTION {
13 let events = self
14 .events
15 .focus_adjacent(tree, pending.action.payload_value() == Some("reverse"));
16 let handler_events = events
17 .iter()
18 .flat_map(|event| tree.handler_events(event))
19 .collect();
20 for event in events.iter().cloned() {
21 self.dirty.mark_event(event);
22 }
23 self.mark_component_owners(tree, events.iter().flat_map(interaction_state_target_ids));
24 let animation_changed =
25 apply_events_to_animations(tree, &mut self.animations, events.iter().cloned());
26 if animation_changed {
27 self.mark_component_owners(tree, events.iter().flat_map(event_target_ids));
28 }
29 let dirty_bounds = self.dirty.take().bounds(tree);
30 return RuntimeOutput {
31 events,
32 handler_events,
33 action_events: Vec::new(),
34 default_actions: Vec::new(),
35 dirty_bounds,
36 animation_changed,
37 route_changed: false,
38 };
39 }
40 let mut action_events = Vec::new();
41 let (_, changed, route_changed) = self.apply_component_action(
42 tree,
43 &pending.action_target,
44 &pending.action,
45 &mut action_events,
46 );
47 let handler_events = changed
48 .then(|| {
49 tree.handler_event(
50 &pending.action_target,
51 UiEventPayload::Change {
52 value: pending.action.payload_value().map(str::to_owned),
53 },
54 )
55 })
56 .flatten()
57 .into_iter()
58 .collect();
59 let dirty_bounds = self.dirty.take().bounds(tree);
60 RuntimeOutput {
61 events: Vec::new(),
62 handler_events,
63 action_events,
64 default_actions: Vec::new(),
65 dirty_bounds,
66 animation_changed: changed,
67 route_changed,
68 }
69 }
70
71 fn apply_component_action(
72 &mut self,
73 tree: &HostTree,
74 target: &UiId,
75 action: &UiAction,
76 action_events: &mut Vec<UiActionEvent>,
77 ) -> (bool, bool, bool) {
78 let outcome = self.component_states.handle_action(target, action);
79 if outcome.changed {
80 self.mark_component_owners(tree, std::iter::once(target));
81 self.dirty.mark_id(target.clone());
82 }
83 for action in outcome.events {
84 let Some(handler) = tree.action_handler(target, action.id()) else {
85 continue;
86 };
87 action_events.push(UiActionEvent {
88 target: target.clone(),
89 action,
90 handler,
91 });
92 }
93 let route_changed =
94 outcome.changed && self.component_states.take_route_invalidation(target);
95 (outcome.handled, outcome.changed, route_changed)
96 }
97}