1use std::{
10 any::{Any, TypeId},
11 collections::HashMap,
12 fmt,
13 hash::{Hash, Hasher},
14 sync::Arc,
15};
16
17use smallvec::SmallVec;
18
19use crate::{
20 AccessibilityActionHandler, AccessibilityNode, ComputedData, Constraint, FocusGroupNode,
21 FocusProperties, FocusRequester, FocusScopeNode, FocusState, FocusTraversalPolicy, ImeInput,
22 KeyboardInput, MeasurementError, PointerInput, PxPosition,
23 focus::{FocusDirection, FocusNode, FocusRevealRequest},
24 layout::{LayoutInput, LayoutOutput, RenderInput},
25 prop::CallbackWith,
26 runtime::{TesseraRuntime, ensure_build_phase},
27 winit::window::CursorIcon,
28};
29
30pub type ParentDataMap = HashMap<TypeId, Arc<dyn Any + Send + Sync>>;
32
33pub trait LayoutModifierChild {
35 fn measure(&mut self, constraint: &Constraint) -> Result<ComputedData, MeasurementError>;
37
38 fn place(&mut self, position: PxPosition, output: &mut LayoutOutput<'_>);
40}
41
42pub struct LayoutModifierInput<'a> {
44 pub layout_input: &'a LayoutInput<'a>,
46}
47
48pub struct LayoutModifierOutput {
50 pub size: ComputedData,
52}
53
54pub trait DrawModifierContent {
56 fn draw(&mut self, input: &RenderInput<'_>);
58}
59
60pub struct DrawModifierContext<'a> {
62 pub render_input: &'a RenderInput<'a>,
64}
65
66pub trait LayoutModifierNode: Send + Sync + 'static {
68 fn measure(
70 &self,
71 input: &LayoutModifierInput<'_>,
72 child: &mut dyn LayoutModifierChild,
73 output: &mut LayoutOutput<'_>,
74 ) -> Result<LayoutModifierOutput, MeasurementError>;
75}
76
77pub trait DrawModifierNode: Send + Sync + 'static {
79 fn draw(&self, ctx: &mut DrawModifierContext<'_>, content: &mut dyn DrawModifierContent);
81}
82
83pub trait ParentDataModifierNode: Send + Sync + 'static {
85 fn apply_parent_data(&self, data: &mut ParentDataMap);
87}
88
89pub trait BuildModifierNode: Send + Sync + 'static {
91 fn apply(&self, runtime: &mut TesseraRuntime);
93}
94
95pub trait SemanticsModifierNode: Send + Sync + 'static {
97 fn apply(
99 &self,
100 accessibility: &mut AccessibilityNode,
101 action_handler: &mut Option<AccessibilityActionHandler>,
102 );
103}
104
105pub trait PointerInputModifierNode: Send + Sync + 'static {
107 fn on_pointer_input(&self, input: PointerInput<'_>);
114}
115
116pub trait CursorModifierNode: Send + Sync + 'static {
118 fn cursor_icon(&self) -> CursorIcon;
121}
122
123pub trait KeyboardInputModifierNode: Send + Sync + 'static {
125 fn on_keyboard_input(&self, input: KeyboardInput<'_>);
127}
128
129pub trait ImeInputModifierNode: Send + Sync + 'static {
131 fn on_ime_input(&self, input: ImeInput<'_>);
133}
134
135pub trait ModifierCapabilityExt {
143 fn push_layout<N>(self, node: N) -> Self
145 where
146 N: LayoutModifierNode;
147
148 fn push_draw<N>(self, node: N) -> Self
150 where
151 N: DrawModifierNode;
152
153 fn push_parent_data<N>(self, node: N) -> Self
155 where
156 N: ParentDataModifierNode;
157
158 fn push_build<N>(self, node: N) -> Self
160 where
161 N: BuildModifierNode;
162
163 fn push_semantics<N>(self, node: N) -> Self
165 where
166 N: SemanticsModifierNode;
167
168 fn push_pointer_preview_input<N>(self, node: N) -> Self
171 where
172 N: PointerInputModifierNode;
173
174 fn push_pointer_input<N>(self, node: N) -> Self
176 where
177 N: PointerInputModifierNode;
178
179 fn push_pointer_final_input<N>(self, node: N) -> Self
182 where
183 N: PointerInputModifierNode;
184
185 fn push_keyboard_preview_input<N>(self, node: N) -> Self
188 where
189 N: KeyboardInputModifierNode;
190
191 fn push_keyboard_input<N>(self, node: N) -> Self
193 where
194 N: KeyboardInputModifierNode;
195
196 fn push_ime_preview_input<N>(self, node: N) -> Self
198 where
199 N: ImeInputModifierNode;
200
201 fn push_ime_input<N>(self, node: N) -> Self
203 where
204 N: ImeInputModifierNode;
205}
206
207#[derive(Clone, PartialEq, Eq)]
208pub(crate) enum FocusModifierRegistration {
209 Target(Option<FocusNode>),
210 Scope(Option<FocusScopeNode>),
211 Group(Option<FocusGroupNode>),
212 Restorer {
213 scope: Option<FocusScopeNode>,
214 fallback: Option<FocusRequester>,
215 },
216}
217
218#[derive(Clone, PartialEq, Eq)]
219enum FocusModifierOp {
220 Requester(FocusRequester),
221 Registration(FocusModifierRegistration),
222 Properties(FocusProperties),
223 TraversalPolicy(FocusTraversalPolicy),
224 ChangedHandler(CallbackWith<FocusState>),
225 EventHandler(CallbackWith<FocusState>),
226 BeyondBoundsHandler(CallbackWith<FocusDirection, bool>),
227 RevealHandler(CallbackWith<FocusRevealRequest, bool>),
228}
229
230#[derive(Clone)]
231enum ModifierAction {
232 Layout(Arc<dyn LayoutModifierNode>),
233 Draw(Arc<dyn DrawModifierNode>),
234 ParentData(Arc<dyn ParentDataModifierNode>),
235 Build(Arc<dyn BuildModifierNode>),
236 Semantics(Arc<dyn SemanticsModifierNode>),
237 Cursor(Arc<dyn CursorModifierNode>),
238 PointerPreviewInput(Arc<dyn PointerInputModifierNode>),
239 PointerInput(Arc<dyn PointerInputModifierNode>),
240 PointerFinalInput(Arc<dyn PointerInputModifierNode>),
241 KeyboardPreviewInput(Arc<dyn KeyboardInputModifierNode>),
242 KeyboardInput(Arc<dyn KeyboardInputModifierNode>),
243 ImePreviewInput(Arc<dyn ImeInputModifierNode>),
244 ImeInput(Arc<dyn ImeInputModifierNode>),
245 Focus(FocusModifierOp),
246}
247
248#[derive(Clone)]
249struct ModifierLink {
250 prev: Option<Arc<ModifierLink>>,
251 action: ModifierAction,
252}
253
254fn collect_actions(mut node: Option<Arc<ModifierLink>>) -> Vec<ModifierAction> {
255 let mut actions: SmallVec<[ModifierAction; 8]> = SmallVec::new();
256 while let Some(current) = node {
257 actions.push(current.action.clone());
258 node = current.prev.clone();
259 }
260 actions.into_vec()
261}
262
263#[derive(Clone, Default)]
265pub struct Modifier {
266 tail: Option<Arc<ModifierLink>>,
267}
268
269pub trait FocusModifierExt {
271 fn focusable(self) -> Modifier;
273
274 fn focus_requester(self, requester: FocusRequester) -> Modifier;
276
277 fn focus_properties(self, properties: FocusProperties) -> Modifier;
279
280 fn focus_group(self) -> Modifier;
282
283 fn focus_scope_with(self, scope: FocusScopeNode) -> Modifier;
285
286 fn focus_group_with(self, group: FocusGroupNode) -> Modifier;
288
289 fn focus_restorer(self, fallback: Option<FocusRequester>) -> Modifier;
291
292 fn focus_restorer_with(
294 self,
295 scope: FocusScopeNode,
296 fallback: Option<FocusRequester>,
297 ) -> Modifier;
298
299 fn focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Modifier;
301
302 fn on_focus_changed<F>(self, handler: F) -> Modifier
304 where
305 F: Into<CallbackWith<FocusState>>;
306
307 fn on_focus_event<F>(self, handler: F) -> Modifier
309 where
310 F: Into<CallbackWith<FocusState>>;
311
312 fn focus_beyond_bounds_handler<F>(self, handler: F) -> Modifier
314 where
315 F: Into<CallbackWith<FocusDirection, bool>>;
316
317 fn focus_reveal_handler<F>(self, handler: F) -> Modifier
320 where
321 F: Into<CallbackWith<FocusRevealRequest, bool>>;
322}
323
324pub trait CursorModifierExt {
326 fn hover_cursor_icon(self, icon: CursorIcon) -> Modifier;
328}
329
330impl Modifier {
331 pub fn new() -> Self {
333 ensure_build_phase();
334 Self::default()
335 }
336
337 fn push_action(self, action: ModifierAction) -> Self {
338 ensure_build_phase();
339 Self {
340 tail: Some(Arc::new(ModifierLink {
341 prev: self.tail,
342 action,
343 })),
344 }
345 }
346
347 pub fn then(mut self, other: Modifier) -> Self {
349 let actions = collect_actions(other.tail);
350 for action in actions.into_iter().rev() {
351 self = self.push_action(action);
352 }
353 self
354 }
355
356 pub(crate) fn push_layout<N>(self, node: N) -> Self
357 where
358 N: LayoutModifierNode,
359 {
360 self.push_action(ModifierAction::Layout(Arc::new(node)))
361 }
362
363 pub(crate) fn push_draw<N>(self, node: N) -> Self
364 where
365 N: DrawModifierNode,
366 {
367 self.push_action(ModifierAction::Draw(Arc::new(node)))
368 }
369
370 pub(crate) fn push_parent_data<N>(self, node: N) -> Self
371 where
372 N: ParentDataModifierNode,
373 {
374 self.push_action(ModifierAction::ParentData(Arc::new(node)))
375 }
376
377 pub(crate) fn push_build<N>(self, node: N) -> Self
378 where
379 N: BuildModifierNode,
380 {
381 self.push_action(ModifierAction::Build(Arc::new(node)))
382 }
383
384 pub(crate) fn push_semantics<N>(self, node: N) -> Self
385 where
386 N: SemanticsModifierNode,
387 {
388 self.push_action(ModifierAction::Semantics(Arc::new(node)))
389 }
390
391 fn push_cursor<N>(self, node: N) -> Self
392 where
393 N: CursorModifierNode,
394 {
395 self.push_action(ModifierAction::Cursor(Arc::new(node)))
396 }
397
398 pub(crate) fn push_pointer_preview_input<N>(self, node: N) -> Self
399 where
400 N: PointerInputModifierNode,
401 {
402 self.push_action(ModifierAction::PointerPreviewInput(Arc::new(node)))
403 }
404
405 pub(crate) fn push_pointer_input<N>(self, node: N) -> Self
406 where
407 N: PointerInputModifierNode,
408 {
409 self.push_action(ModifierAction::PointerInput(Arc::new(node)))
410 }
411
412 pub(crate) fn push_pointer_final_input<N>(self, node: N) -> Self
413 where
414 N: PointerInputModifierNode,
415 {
416 self.push_action(ModifierAction::PointerFinalInput(Arc::new(node)))
417 }
418
419 pub(crate) fn push_keyboard_preview_input<N>(self, node: N) -> Self
420 where
421 N: KeyboardInputModifierNode,
422 {
423 self.push_action(ModifierAction::KeyboardPreviewInput(Arc::new(node)))
424 }
425
426 pub(crate) fn push_keyboard_input<N>(self, node: N) -> Self
427 where
428 N: KeyboardInputModifierNode,
429 {
430 self.push_action(ModifierAction::KeyboardInput(Arc::new(node)))
431 }
432
433 pub(crate) fn push_ime_preview_input<N>(self, node: N) -> Self
434 where
435 N: ImeInputModifierNode,
436 {
437 self.push_action(ModifierAction::ImePreviewInput(Arc::new(node)))
438 }
439
440 pub(crate) fn push_ime_input<N>(self, node: N) -> Self
441 where
442 N: ImeInputModifierNode,
443 {
444 self.push_action(ModifierAction::ImeInput(Arc::new(node)))
445 }
446
447 fn push_focus_requester(self, requester: FocusRequester) -> Self {
448 self.push_focus_op(FocusModifierOp::Requester(requester))
449 }
450
451 fn push_focus_target(self) -> Self {
452 self.push_focus_op(FocusModifierOp::Registration(
453 FocusModifierRegistration::Target(None),
454 ))
455 }
456
457 fn push_focus_scope_with(self, scope: FocusScopeNode) -> Self {
458 self.push_focus_op(FocusModifierOp::Registration(
459 FocusModifierRegistration::Scope(Some(scope)),
460 ))
461 }
462
463 fn push_focus_group(self) -> Self {
464 self.push_focus_op(FocusModifierOp::Registration(
465 FocusModifierRegistration::Group(None),
466 ))
467 }
468
469 fn push_focus_group_with(self, group: FocusGroupNode) -> Self {
470 self.push_focus_op(FocusModifierOp::Registration(
471 FocusModifierRegistration::Group(Some(group)),
472 ))
473 }
474
475 fn push_focus_restorer(self, fallback: Option<FocusRequester>) -> Self {
476 self.push_focus_op(FocusModifierOp::Registration(
477 FocusModifierRegistration::Restorer {
478 scope: None,
479 fallback,
480 },
481 ))
482 }
483
484 fn push_focus_restorer_with(
485 self,
486 scope: FocusScopeNode,
487 fallback: Option<FocusRequester>,
488 ) -> Self {
489 self.push_focus_op(FocusModifierOp::Registration(
490 FocusModifierRegistration::Restorer {
491 scope: Some(scope),
492 fallback,
493 },
494 ))
495 }
496
497 fn push_focus_properties(self, properties: FocusProperties) -> Self {
498 self.push_focus_op(FocusModifierOp::Properties(properties))
499 }
500
501 fn push_focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Self {
502 self.push_focus_op(FocusModifierOp::TraversalPolicy(policy))
503 }
504
505 fn push_focus_changed_handler(self, handler: CallbackWith<FocusState>) -> Self {
506 self.push_focus_op(FocusModifierOp::ChangedHandler(handler))
507 }
508
509 fn push_focus_event_handler(self, handler: CallbackWith<FocusState>) -> Self {
510 self.push_focus_op(FocusModifierOp::EventHandler(handler))
511 }
512
513 fn push_focus_beyond_bounds_handler(self, handler: CallbackWith<FocusDirection, bool>) -> Self {
514 self.push_focus_op(FocusModifierOp::BeyondBoundsHandler(handler))
515 }
516
517 fn push_focus_reveal_handler(self, handler: CallbackWith<FocusRevealRequest, bool>) -> Self {
518 self.push_focus_op(FocusModifierOp::RevealHandler(handler))
519 }
520
521 fn push_focus_op(self, op: FocusModifierOp) -> Self {
522 self.push_action(ModifierAction::Focus(op))
523 }
524
525 pub fn attach(self) {
527 ensure_build_phase();
528
529 let actions = collect_actions(self.tail.clone());
530 TesseraRuntime::with_mut(|runtime| {
531 runtime.append_current_modifier(self.clone());
532 });
533
534 let mut accessibility = AccessibilityNode::new();
535 let mut action_handler = None;
536 let mut has_semantics = false;
537 for action in actions.into_iter().rev() {
538 match action {
539 ModifierAction::Build(node) => {
540 TesseraRuntime::with_mut(|runtime| node.apply(runtime));
541 }
542 ModifierAction::Semantics(node) => {
543 has_semantics = true;
544 node.apply(&mut accessibility, &mut action_handler);
545 }
546 ModifierAction::Focus(op) => {
547 TesseraRuntime::with_mut(|runtime| {
548 apply_focus_op(runtime::FocusModifierRuntime::new(runtime), op);
549 });
550 }
551 _ => {}
552 }
553 }
554
555 TesseraRuntime::with_mut(|runtime| {
556 runtime.set_current_accessibility(has_semantics.then_some(accessibility));
557 runtime.set_current_accessibility_action_handler(action_handler);
558 });
559 }
560
561 pub fn run<F>(self, child: F)
563 where
564 F: Fn() + Send + Sync + 'static,
565 {
566 self.attach();
567 child();
568 }
569
570 pub fn is_empty(&self) -> bool {
572 self.tail.is_none()
573 }
574
575 pub(crate) fn layout_nodes(&self) -> Vec<Arc<dyn LayoutModifierNode>> {
576 collect_actions(self.tail.clone())
577 .into_iter()
578 .filter_map(|action| match action {
579 ModifierAction::Layout(node) => Some(node),
580 _ => None,
581 })
582 .collect()
583 }
584
585 pub(crate) fn draw_nodes(&self) -> Vec<Arc<dyn DrawModifierNode>> {
586 collect_actions(self.tail.clone())
587 .into_iter()
588 .filter_map(|action| match action {
589 ModifierAction::Draw(node) => Some(node),
590 _ => None,
591 })
592 .collect()
593 }
594
595 pub(crate) fn apply_parent_data(&self, data: &mut ParentDataMap) {
596 for action in collect_actions(self.tail.clone()).into_iter().rev() {
597 if let ModifierAction::ParentData(node) = action {
598 node.apply_parent_data(data);
599 }
600 }
601 }
602
603 pub(crate) fn pointer_preview_input_nodes(&self) -> Vec<Arc<dyn PointerInputModifierNode>> {
604 collect_actions(self.tail.clone())
605 .into_iter()
606 .filter_map(|action| match action {
607 ModifierAction::PointerPreviewInput(node) => Some(node),
608 _ => None,
609 })
610 .collect()
611 }
612
613 pub(crate) fn pointer_input_nodes(&self) -> Vec<Arc<dyn PointerInputModifierNode>> {
614 collect_actions(self.tail.clone())
615 .into_iter()
616 .filter_map(|action| match action {
617 ModifierAction::PointerInput(node) => Some(node),
618 _ => None,
619 })
620 .collect()
621 }
622
623 pub(crate) fn pointer_final_input_nodes(&self) -> Vec<Arc<dyn PointerInputModifierNode>> {
624 collect_actions(self.tail.clone())
625 .into_iter()
626 .filter_map(|action| match action {
627 ModifierAction::PointerFinalInput(node) => Some(node),
628 _ => None,
629 })
630 .collect()
631 }
632
633 pub(crate) fn keyboard_preview_input_nodes(&self) -> Vec<Arc<dyn KeyboardInputModifierNode>> {
634 collect_actions(self.tail.clone())
635 .into_iter()
636 .filter_map(|action| match action {
637 ModifierAction::KeyboardPreviewInput(node) => Some(node),
638 _ => None,
639 })
640 .collect()
641 }
642
643 pub(crate) fn keyboard_input_nodes(&self) -> Vec<Arc<dyn KeyboardInputModifierNode>> {
644 collect_actions(self.tail.clone())
645 .into_iter()
646 .filter_map(|action| match action {
647 ModifierAction::KeyboardInput(node) => Some(node),
648 _ => None,
649 })
650 .collect()
651 }
652
653 pub(crate) fn ime_preview_input_nodes(&self) -> Vec<Arc<dyn ImeInputModifierNode>> {
654 collect_actions(self.tail.clone())
655 .into_iter()
656 .filter_map(|action| match action {
657 ModifierAction::ImePreviewInput(node) => Some(node),
658 _ => None,
659 })
660 .collect()
661 }
662
663 pub(crate) fn ime_input_nodes(&self) -> Vec<Arc<dyn ImeInputModifierNode>> {
664 collect_actions(self.tail.clone())
665 .into_iter()
666 .filter_map(|action| match action {
667 ModifierAction::ImeInput(node) => Some(node),
668 _ => None,
669 })
670 .collect()
671 }
672
673 pub(crate) fn has_pointer_input_nodes(&self) -> bool {
674 collect_actions(self.tail.clone())
675 .into_iter()
676 .any(|action| {
677 matches!(
678 action,
679 ModifierAction::PointerPreviewInput(_)
680 | ModifierAction::PointerInput(_)
681 | ModifierAction::PointerFinalInput(_)
682 )
683 })
684 }
685
686 pub(crate) fn cursor_icon(&self) -> Option<CursorIcon> {
687 collect_actions(self.tail.clone())
688 .into_iter()
689 .find_map(|action| match action {
690 ModifierAction::Cursor(node) => Some(node.cursor_icon()),
691 _ => None,
692 })
693 }
694
695 pub(crate) fn has_cursor_icon(&self) -> bool {
696 self.cursor_icon().is_some()
697 }
698}
699
700impl ModifierCapabilityExt for Modifier {
701 fn push_layout<N>(self, node: N) -> Self
702 where
703 N: LayoutModifierNode,
704 {
705 Modifier::push_layout(self, node)
706 }
707
708 fn push_draw<N>(self, node: N) -> Self
709 where
710 N: DrawModifierNode,
711 {
712 Modifier::push_draw(self, node)
713 }
714
715 fn push_parent_data<N>(self, node: N) -> Self
716 where
717 N: ParentDataModifierNode,
718 {
719 Modifier::push_parent_data(self, node)
720 }
721
722 fn push_build<N>(self, node: N) -> Self
723 where
724 N: BuildModifierNode,
725 {
726 Modifier::push_build(self, node)
727 }
728
729 fn push_semantics<N>(self, node: N) -> Self
730 where
731 N: SemanticsModifierNode,
732 {
733 Modifier::push_semantics(self, node)
734 }
735
736 fn push_pointer_preview_input<N>(self, node: N) -> Self
737 where
738 N: PointerInputModifierNode,
739 {
740 Modifier::push_pointer_preview_input(self, node)
741 }
742
743 fn push_pointer_input<N>(self, node: N) -> Self
744 where
745 N: PointerInputModifierNode,
746 {
747 Modifier::push_pointer_input(self, node)
748 }
749
750 fn push_pointer_final_input<N>(self, node: N) -> Self
751 where
752 N: PointerInputModifierNode,
753 {
754 Modifier::push_pointer_final_input(self, node)
755 }
756
757 fn push_keyboard_preview_input<N>(self, node: N) -> Self
758 where
759 N: KeyboardInputModifierNode,
760 {
761 Modifier::push_keyboard_preview_input(self, node)
762 }
763
764 fn push_keyboard_input<N>(self, node: N) -> Self
765 where
766 N: KeyboardInputModifierNode,
767 {
768 Modifier::push_keyboard_input(self, node)
769 }
770
771 fn push_ime_preview_input<N>(self, node: N) -> Self
772 where
773 N: ImeInputModifierNode,
774 {
775 Modifier::push_ime_preview_input(self, node)
776 }
777
778 fn push_ime_input<N>(self, node: N) -> Self
779 where
780 N: ImeInputModifierNode,
781 {
782 Modifier::push_ime_input(self, node)
783 }
784}
785
786#[derive(Clone, Copy)]
787struct StaticCursorModifierNode {
788 icon: CursorIcon,
789}
790
791impl CursorModifierNode for StaticCursorModifierNode {
792 fn cursor_icon(&self) -> CursorIcon {
793 self.icon
794 }
795}
796
797impl CursorModifierExt for Modifier {
798 fn hover_cursor_icon(self, icon: CursorIcon) -> Modifier {
799 self.push_cursor(StaticCursorModifierNode { icon })
800 }
801}
802
803impl FocusModifierExt for Modifier {
804 fn focusable(self) -> Modifier {
805 self.push_focus_target()
806 }
807
808 fn focus_requester(self, requester: FocusRequester) -> Modifier {
809 self.push_focus_requester(requester)
810 }
811
812 fn focus_properties(self, properties: FocusProperties) -> Modifier {
813 self.push_focus_properties(properties)
814 }
815
816 fn focus_group(self) -> Modifier {
817 self.push_focus_group()
818 }
819
820 fn focus_scope_with(self, scope: FocusScopeNode) -> Modifier {
821 self.push_focus_scope_with(scope)
822 }
823
824 fn focus_group_with(self, group: FocusGroupNode) -> Modifier {
825 self.push_focus_group_with(group)
826 }
827
828 fn focus_restorer(self, fallback: Option<FocusRequester>) -> Modifier {
829 self.push_focus_restorer(fallback)
830 }
831
832 fn focus_restorer_with(
833 self,
834 scope: FocusScopeNode,
835 fallback: Option<FocusRequester>,
836 ) -> Modifier {
837 self.push_focus_restorer_with(scope, fallback)
838 }
839
840 fn focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Modifier {
841 self.push_focus_traversal_policy(policy)
842 }
843
844 fn on_focus_changed<F>(self, handler: F) -> Modifier
845 where
846 F: Into<CallbackWith<FocusState>>,
847 {
848 self.push_focus_changed_handler(handler.into())
849 }
850
851 fn on_focus_event<F>(self, handler: F) -> Modifier
852 where
853 F: Into<CallbackWith<FocusState>>,
854 {
855 self.push_focus_event_handler(handler.into())
856 }
857
858 fn focus_beyond_bounds_handler<F>(self, handler: F) -> Modifier
859 where
860 F: Into<CallbackWith<FocusDirection, bool>>,
861 {
862 self.push_focus_beyond_bounds_handler(handler.into())
863 }
864
865 fn focus_reveal_handler<F>(self, handler: F) -> Modifier
866 where
867 F: Into<CallbackWith<FocusRevealRequest, bool>>,
868 {
869 self.push_focus_reveal_handler(handler.into())
870 }
871}
872
873impl fmt::Debug for Modifier {
874 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
875 f.debug_struct("Modifier")
876 .field("is_empty", &self.tail.is_none())
877 .finish()
878 }
879}
880
881impl PartialEq for Modifier {
882 fn eq(&self, other: &Self) -> bool {
883 match (&self.tail, &other.tail) {
884 (None, None) => true,
885 (Some(lhs), Some(rhs)) => Arc::ptr_eq(lhs, rhs),
886 _ => false,
887 }
888 }
889}
890
891impl Eq for Modifier {}
892
893impl Hash for Modifier {
894 fn hash<H: Hasher>(&self, state: &mut H) {
895 match &self.tail {
896 Some(node) => std::ptr::hash(Arc::as_ptr(node), state),
897 None => 0u8.hash(state),
898 }
899 }
900}
901
902mod runtime {
903 use super::FocusModifierRegistration;
904 use crate::{
905 FocusProperties, FocusRequester, FocusScopeNode, FocusState, FocusTraversalPolicy,
906 focus::{FocusDirection, FocusRevealRequest},
907 prop::CallbackWith,
908 runtime::TesseraRuntime,
909 };
910
911 pub(super) struct FocusModifierRuntime<'a> {
912 runtime: &'a mut TesseraRuntime,
913 }
914
915 impl<'a> FocusModifierRuntime<'a> {
916 pub(super) fn new(runtime: &'a mut TesseraRuntime) -> Self {
917 Self { runtime }
918 }
919
920 pub(super) fn bind_requester(&mut self, requester: FocusRequester) {
921 self.runtime.bind_current_focus_requester(requester);
922 }
923
924 pub(super) fn ensure_registration(&mut self, registration: FocusModifierRegistration) {
925 match registration {
926 FocusModifierRegistration::Target(node) => {
927 let node = node.unwrap_or_else(|| {
928 self.runtime
929 .current_focus_target_handle()
930 .unwrap_or_else(|| {
931 crate::runtime::persistent_focus_target_for_current_instance(
932 "__tessera_focus_target",
933 )
934 })
935 });
936 self.runtime.ensure_current_focus_target(node);
937 }
938 FocusModifierRegistration::Scope(scope) => {
939 let scope = scope.unwrap_or_else(|| {
940 self.runtime
941 .current_focus_scope_handle()
942 .unwrap_or_else(|| {
943 crate::runtime::persistent_focus_scope_for_current_instance(
944 "__tessera_focus_scope",
945 )
946 })
947 });
948 self.runtime.ensure_current_focus_scope(scope);
949 }
950 FocusModifierRegistration::Group(group) => {
951 let group = group.unwrap_or_else(|| {
952 self.runtime
953 .current_focus_group_handle()
954 .unwrap_or_else(|| {
955 crate::runtime::persistent_focus_group_for_current_instance(
956 "__tessera_focus_group",
957 )
958 })
959 });
960 self.runtime.ensure_current_focus_group(group);
961 }
962 FocusModifierRegistration::Restorer { scope, fallback } => {
963 let scope: FocusScopeNode = scope.unwrap_or_else(|| {
964 self.runtime
965 .current_focus_scope_handle()
966 .unwrap_or_else(|| {
967 crate::runtime::persistent_focus_scope_for_current_instance(
968 "__tessera_focus_scope",
969 )
970 })
971 });
972 self.runtime.ensure_current_focus_scope(scope);
973 if let Some(fallback) = fallback {
974 self.runtime.set_current_focus_restorer_fallback(fallback);
975 }
976 }
977 }
978 }
979
980 pub(super) fn set_properties(&mut self, properties: FocusProperties) {
981 self.runtime.set_current_focus_properties(properties);
982 }
983
984 pub(super) fn set_traversal_policy(&mut self, policy: FocusTraversalPolicy) {
985 self.runtime.set_current_focus_traversal_policy(policy);
986 }
987
988 pub(super) fn set_changed_handler(&mut self, handler: CallbackWith<FocusState>) {
989 self.runtime.set_current_focus_changed_handler(handler);
990 }
991
992 pub(super) fn set_event_handler(&mut self, handler: CallbackWith<FocusState>) {
993 self.runtime.set_current_focus_event_handler(handler);
994 }
995
996 pub(super) fn set_beyond_bounds_handler(
997 &mut self,
998 handler: CallbackWith<FocusDirection, bool>,
999 ) {
1000 self.runtime
1001 .set_current_focus_beyond_bounds_handler(handler);
1002 }
1003
1004 pub(super) fn set_reveal_handler(
1005 &mut self,
1006 handler: CallbackWith<FocusRevealRequest, bool>,
1007 ) {
1008 self.runtime.set_current_focus_reveal_handler(handler);
1009 }
1010 }
1011}
1012
1013fn apply_focus_op(runtime: runtime::FocusModifierRuntime<'_>, op: FocusModifierOp) {
1014 let mut runtime = runtime;
1015 match op {
1016 FocusModifierOp::Requester(requester) => runtime.bind_requester(requester),
1017 FocusModifierOp::Registration(registration) => runtime.ensure_registration(registration),
1018 FocusModifierOp::Properties(properties) => runtime.set_properties(properties),
1019 FocusModifierOp::TraversalPolicy(policy) => runtime.set_traversal_policy(policy),
1020 FocusModifierOp::ChangedHandler(handler) => runtime.set_changed_handler(handler),
1021 FocusModifierOp::EventHandler(handler) => runtime.set_event_handler(handler),
1022 FocusModifierOp::BeyondBoundsHandler(handler) => runtime.set_beyond_bounds_handler(handler),
1023 FocusModifierOp::RevealHandler(handler) => runtime.set_reveal_handler(handler),
1024 }
1025}