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, 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);
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: &mut RenderInput<'_>);
58}
59
60pub struct DrawModifierContext<'a, 'b> {
62 pub render_input: &'a mut RenderInput<'b>,
64}
65
66pub trait LayoutModifierNode: Send + Sync + 'static {
68 fn measure(
70 &self,
71 input: &LayoutModifierInput<'_>,
72 child: &mut dyn LayoutModifierChild,
73 ) -> Result<LayoutModifierOutput, MeasurementError>;
74}
75
76pub trait PlacementModifierNode: Send + Sync + 'static {
79 fn transform_position(&self, position: PxPosition) -> PxPosition;
81}
82
83pub trait DrawModifierNode: Send + Sync + 'static {
85 fn draw(&self, ctx: &mut DrawModifierContext<'_, '_>, content: &mut dyn DrawModifierContent);
87}
88
89pub trait ParentDataModifierNode: Send + Sync + 'static {
91 fn apply_parent_data(&self, data: &mut ParentDataMap);
93}
94
95pub trait BuildModifierNode: Send + Sync + 'static {
97 fn apply(&self, runtime: &mut TesseraRuntime);
99}
100
101pub trait SemanticsModifierNode: Send + Sync + 'static {
103 fn apply(
105 &self,
106 accessibility: &mut AccessibilityNode,
107 action_handler: &mut Option<AccessibilityActionHandler>,
108 );
109}
110
111pub trait PointerInputModifierNode: Send + Sync + 'static {
113 fn on_pointer_input(&self, input: PointerInput<'_>);
120}
121
122pub trait CursorModifierNode: Send + Sync + 'static {
124 fn cursor_icon(&self) -> CursorIcon;
127}
128
129pub trait KeyboardInputModifierNode: Send + Sync + 'static {
131 fn on_keyboard_input(&self, input: KeyboardInput<'_>);
133}
134
135pub trait ImeInputModifierNode: Send + Sync + 'static {
137 fn on_ime_input(&self, input: ImeInput<'_>);
139}
140
141pub trait ModifierCapabilityExt {
149 fn push_layout<N>(self, node: N) -> Self
151 where
152 N: LayoutModifierNode + PartialEq;
153
154 fn push_placement<N>(self, node: N) -> Self
156 where
157 N: PlacementModifierNode + PartialEq;
158
159 fn push_draw<N>(self, node: N) -> Self
161 where
162 N: DrawModifierNode;
163
164 fn push_parent_data<N>(self, node: N) -> Self
166 where
167 N: ParentDataModifierNode;
168
169 fn push_build<N>(self, node: N) -> Self
171 where
172 N: BuildModifierNode;
173
174 fn push_semantics<N>(self, node: N) -> Self
176 where
177 N: SemanticsModifierNode;
178
179 fn push_pointer_preview_input<N>(self, node: N) -> Self
182 where
183 N: PointerInputModifierNode;
184
185 fn push_pointer_input<N>(self, node: N) -> Self
187 where
188 N: PointerInputModifierNode;
189
190 fn push_pointer_final_input<N>(self, node: N) -> Self
193 where
194 N: PointerInputModifierNode;
195
196 fn push_keyboard_preview_input<N>(self, node: N) -> Self
199 where
200 N: KeyboardInputModifierNode;
201
202 fn push_keyboard_input<N>(self, node: N) -> Self
204 where
205 N: KeyboardInputModifierNode;
206
207 fn push_ime_preview_input<N>(self, node: N) -> Self
209 where
210 N: ImeInputModifierNode;
211
212 fn push_ime_input<N>(self, node: N) -> Self
214 where
215 N: ImeInputModifierNode;
216}
217
218#[derive(Clone, PartialEq, Eq)]
219pub(crate) enum FocusModifierRegistration {
220 Target(Option<FocusNode>),
221 Scope(Option<FocusScopeNode>),
222 Group(Option<FocusGroupNode>),
223 Restorer {
224 scope: Option<FocusScopeNode>,
225 fallback: Option<FocusRequester>,
226 },
227}
228
229#[derive(Clone, PartialEq, Eq)]
230enum FocusModifierOp {
231 Requester(FocusRequester),
232 Registration(FocusModifierRegistration),
233 Properties(FocusProperties),
234 TraversalPolicy(FocusTraversalPolicy),
235 ChangedHandler(CallbackWith<FocusState>),
236 EventHandler(CallbackWith<FocusState>),
237 BeyondBoundsHandler(CallbackWith<FocusDirection, bool>),
238 RevealHandler(CallbackWith<FocusRevealRequest, bool>),
239}
240
241pub(crate) trait ErasedLayoutModifierNode: Send + Sync + 'static {
242 fn node(&self) -> Arc<dyn LayoutModifierNode>;
243
244 fn measure_eq(&self, other: &dyn ErasedLayoutModifierNode) -> bool;
245
246 fn placement_eq(&self, other: &dyn ErasedLayoutModifierNode) -> bool;
247
248 fn as_any(&self) -> &dyn Any;
249}
250
251pub(crate) trait ErasedPlacementModifierNode: Send + Sync + 'static {
252 fn node(&self) -> Arc<dyn PlacementModifierNode>;
253
254 fn eq(&self, other: &dyn ErasedPlacementModifierNode) -> bool;
255
256 fn as_any(&self) -> &dyn Any;
257}
258
259struct ComparableLayoutModifierNode<N>
260where
261 N: LayoutModifierNode + PartialEq,
262{
263 node: Arc<N>,
264}
265
266impl<N> ErasedLayoutModifierNode for ComparableLayoutModifierNode<N>
267where
268 N: LayoutModifierNode + PartialEq,
269{
270 fn node(&self) -> Arc<dyn LayoutModifierNode> {
271 self.node.clone()
272 }
273
274 fn measure_eq(&self, other: &dyn ErasedLayoutModifierNode) -> bool {
275 other
276 .as_any()
277 .downcast_ref::<Self>()
278 .is_some_and(|other| self.node.as_ref() == other.node.as_ref())
279 }
280
281 fn placement_eq(&self, other: &dyn ErasedLayoutModifierNode) -> bool {
282 self.measure_eq(other)
283 }
284
285 fn as_any(&self) -> &dyn Any {
286 self
287 }
288}
289
290struct ComparablePlacementModifierNode<N>
291where
292 N: PlacementModifierNode + PartialEq,
293{
294 node: Arc<N>,
295}
296
297impl<N> ErasedPlacementModifierNode for ComparablePlacementModifierNode<N>
298where
299 N: PlacementModifierNode + PartialEq,
300{
301 fn node(&self) -> Arc<dyn PlacementModifierNode> {
302 self.node.clone()
303 }
304
305 fn eq(&self, other: &dyn ErasedPlacementModifierNode) -> bool {
306 other
307 .as_any()
308 .downcast_ref::<Self>()
309 .is_some_and(|other| self.node.as_ref() == other.node.as_ref())
310 }
311
312 fn as_any(&self) -> &dyn Any {
313 self
314 }
315}
316
317#[derive(Clone)]
318enum ModifierAction {
319 Layout(Arc<dyn ErasedLayoutModifierNode>),
320 Placement(Arc<dyn ErasedPlacementModifierNode>),
321 Draw(Arc<dyn DrawModifierNode>),
322 ParentData(Arc<dyn ParentDataModifierNode>),
323 Build(Arc<dyn BuildModifierNode>),
324 Semantics(Arc<dyn SemanticsModifierNode>),
325 Cursor(Arc<dyn CursorModifierNode>),
326 PointerPreviewInput(Arc<dyn PointerInputModifierNode>),
327 PointerInput(Arc<dyn PointerInputModifierNode>),
328 PointerFinalInput(Arc<dyn PointerInputModifierNode>),
329 KeyboardPreviewInput(Arc<dyn KeyboardInputModifierNode>),
330 KeyboardInput(Arc<dyn KeyboardInputModifierNode>),
331 ImePreviewInput(Arc<dyn ImeInputModifierNode>),
332 ImeInput(Arc<dyn ImeInputModifierNode>),
333 Focus(FocusModifierOp),
334}
335
336#[derive(Clone)]
337pub(crate) enum OrderedModifierAction {
338 Layout(Arc<dyn ErasedLayoutModifierNode>),
339 Placement(Arc<dyn ErasedPlacementModifierNode>),
340 Draw(Arc<dyn DrawModifierNode>),
341 ParentData(Arc<dyn ParentDataModifierNode>),
342 Cursor(Arc<dyn CursorModifierNode>),
343 PointerPreviewInput(Arc<dyn PointerInputModifierNode>),
344 PointerInput(Arc<dyn PointerInputModifierNode>),
345 PointerFinalInput(Arc<dyn PointerInputModifierNode>),
346 KeyboardPreviewInput(Arc<dyn KeyboardInputModifierNode>),
347 KeyboardInput(Arc<dyn KeyboardInputModifierNode>),
348 ImePreviewInput(Arc<dyn ImeInputModifierNode>),
349 ImeInput(Arc<dyn ImeInputModifierNode>),
350}
351
352#[derive(Clone)]
353struct ModifierLink {
354 prev: Option<Arc<ModifierLink>>,
355 action: ModifierAction,
356}
357
358fn collect_actions(mut node: Option<Arc<ModifierLink>>) -> Vec<ModifierAction> {
359 let mut actions: SmallVec<[ModifierAction; 8]> = SmallVec::new();
360 while let Some(current) = node {
361 actions.push(current.action.clone());
362 node = current.prev.clone();
363 }
364 actions.into_vec()
365}
366
367fn collect_actions_in_source_order(node: Option<Arc<ModifierLink>>) -> Vec<ModifierAction> {
368 let mut actions = collect_actions(node);
369 actions.reverse();
370 actions
371}
372
373#[derive(Clone, Default)]
375pub struct Modifier {
376 tail: Option<Arc<ModifierLink>>,
377}
378
379pub trait FocusModifierExt {
381 fn focusable(self) -> Modifier;
383
384 fn focus_requester(self, requester: FocusRequester) -> Modifier;
386
387 fn focus_properties(self, properties: FocusProperties) -> Modifier;
389
390 fn focus_group(self) -> Modifier;
392
393 fn focus_scope_with(self, scope: FocusScopeNode) -> Modifier;
395
396 fn focus_group_with(self, group: FocusGroupNode) -> Modifier;
398
399 fn focus_restorer(self, fallback: Option<FocusRequester>) -> Modifier;
401
402 fn focus_restorer_with(
404 self,
405 scope: FocusScopeNode,
406 fallback: Option<FocusRequester>,
407 ) -> Modifier;
408
409 fn focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Modifier;
411
412 fn on_focus_changed<F>(self, handler: F) -> Modifier
414 where
415 F: Into<CallbackWith<FocusState>>;
416
417 fn on_focus_event<F>(self, handler: F) -> Modifier
419 where
420 F: Into<CallbackWith<FocusState>>;
421
422 fn focus_beyond_bounds_handler<F>(self, handler: F) -> Modifier
424 where
425 F: Into<CallbackWith<FocusDirection, bool>>;
426
427 fn focus_reveal_handler<F>(self, handler: F) -> Modifier
430 where
431 F: Into<CallbackWith<FocusRevealRequest, bool>>;
432}
433
434pub trait CursorModifierExt {
436 fn hover_cursor_icon(self, icon: CursorIcon) -> Modifier;
438}
439
440impl Modifier {
441 pub fn new() -> Self {
443 ensure_build_phase();
444 Self::default()
445 }
446
447 fn push_action(self, action: ModifierAction) -> Self {
448 ensure_build_phase();
449 Self {
450 tail: Some(Arc::new(ModifierLink {
451 prev: self.tail,
452 action,
453 })),
454 }
455 }
456
457 pub fn then(mut self, other: Modifier) -> Self {
459 let actions = collect_actions(other.tail);
460 for action in actions.into_iter().rev() {
461 self = self.push_action(action);
462 }
463 self
464 }
465
466 pub(crate) fn push_layout<N>(self, node: N) -> Self
467 where
468 N: LayoutModifierNode + PartialEq,
469 {
470 self.push_action(ModifierAction::Layout(Arc::new(
471 ComparableLayoutModifierNode {
472 node: Arc::new(node),
473 },
474 )))
475 }
476
477 pub(crate) fn push_placement<N>(self, node: N) -> Self
478 where
479 N: PlacementModifierNode + PartialEq,
480 {
481 self.push_action(ModifierAction::Placement(Arc::new(
482 ComparablePlacementModifierNode {
483 node: Arc::new(node),
484 },
485 )))
486 }
487
488 pub(crate) fn push_draw<N>(self, node: N) -> Self
489 where
490 N: DrawModifierNode,
491 {
492 self.push_action(ModifierAction::Draw(Arc::new(node)))
493 }
494
495 pub(crate) fn push_parent_data<N>(self, node: N) -> Self
496 where
497 N: ParentDataModifierNode,
498 {
499 self.push_action(ModifierAction::ParentData(Arc::new(node)))
500 }
501
502 pub(crate) fn push_build<N>(self, node: N) -> Self
503 where
504 N: BuildModifierNode,
505 {
506 self.push_action(ModifierAction::Build(Arc::new(node)))
507 }
508
509 pub(crate) fn push_semantics<N>(self, node: N) -> Self
510 where
511 N: SemanticsModifierNode,
512 {
513 self.push_action(ModifierAction::Semantics(Arc::new(node)))
514 }
515
516 fn push_cursor<N>(self, node: N) -> Self
517 where
518 N: CursorModifierNode,
519 {
520 self.push_action(ModifierAction::Cursor(Arc::new(node)))
521 }
522
523 pub(crate) fn push_pointer_preview_input<N>(self, node: N) -> Self
524 where
525 N: PointerInputModifierNode,
526 {
527 self.push_action(ModifierAction::PointerPreviewInput(Arc::new(node)))
528 }
529
530 pub(crate) fn push_pointer_input<N>(self, node: N) -> Self
531 where
532 N: PointerInputModifierNode,
533 {
534 self.push_action(ModifierAction::PointerInput(Arc::new(node)))
535 }
536
537 pub(crate) fn push_pointer_final_input<N>(self, node: N) -> Self
538 where
539 N: PointerInputModifierNode,
540 {
541 self.push_action(ModifierAction::PointerFinalInput(Arc::new(node)))
542 }
543
544 pub(crate) fn push_keyboard_preview_input<N>(self, node: N) -> Self
545 where
546 N: KeyboardInputModifierNode,
547 {
548 self.push_action(ModifierAction::KeyboardPreviewInput(Arc::new(node)))
549 }
550
551 pub(crate) fn push_keyboard_input<N>(self, node: N) -> Self
552 where
553 N: KeyboardInputModifierNode,
554 {
555 self.push_action(ModifierAction::KeyboardInput(Arc::new(node)))
556 }
557
558 pub(crate) fn push_ime_preview_input<N>(self, node: N) -> Self
559 where
560 N: ImeInputModifierNode,
561 {
562 self.push_action(ModifierAction::ImePreviewInput(Arc::new(node)))
563 }
564
565 pub(crate) fn push_ime_input<N>(self, node: N) -> Self
566 where
567 N: ImeInputModifierNode,
568 {
569 self.push_action(ModifierAction::ImeInput(Arc::new(node)))
570 }
571
572 fn push_focus_requester(self, requester: FocusRequester) -> Self {
573 self.push_focus_op(FocusModifierOp::Requester(requester))
574 }
575
576 fn push_focus_target(self) -> Self {
577 self.push_focus_op(FocusModifierOp::Registration(
578 FocusModifierRegistration::Target(None),
579 ))
580 }
581
582 fn push_focus_scope_with(self, scope: FocusScopeNode) -> Self {
583 self.push_focus_op(FocusModifierOp::Registration(
584 FocusModifierRegistration::Scope(Some(scope)),
585 ))
586 }
587
588 fn push_focus_group(self) -> Self {
589 self.push_focus_op(FocusModifierOp::Registration(
590 FocusModifierRegistration::Group(None),
591 ))
592 }
593
594 fn push_focus_group_with(self, group: FocusGroupNode) -> Self {
595 self.push_focus_op(FocusModifierOp::Registration(
596 FocusModifierRegistration::Group(Some(group)),
597 ))
598 }
599
600 fn push_focus_restorer(self, fallback: Option<FocusRequester>) -> Self {
601 self.push_focus_op(FocusModifierOp::Registration(
602 FocusModifierRegistration::Restorer {
603 scope: None,
604 fallback,
605 },
606 ))
607 }
608
609 fn push_focus_restorer_with(
610 self,
611 scope: FocusScopeNode,
612 fallback: Option<FocusRequester>,
613 ) -> Self {
614 self.push_focus_op(FocusModifierOp::Registration(
615 FocusModifierRegistration::Restorer {
616 scope: Some(scope),
617 fallback,
618 },
619 ))
620 }
621
622 fn push_focus_properties(self, properties: FocusProperties) -> Self {
623 self.push_focus_op(FocusModifierOp::Properties(properties))
624 }
625
626 fn push_focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Self {
627 self.push_focus_op(FocusModifierOp::TraversalPolicy(policy))
628 }
629
630 fn push_focus_changed_handler(self, handler: CallbackWith<FocusState>) -> Self {
631 self.push_focus_op(FocusModifierOp::ChangedHandler(handler))
632 }
633
634 fn push_focus_event_handler(self, handler: CallbackWith<FocusState>) -> Self {
635 self.push_focus_op(FocusModifierOp::EventHandler(handler))
636 }
637
638 fn push_focus_beyond_bounds_handler(self, handler: CallbackWith<FocusDirection, bool>) -> Self {
639 self.push_focus_op(FocusModifierOp::BeyondBoundsHandler(handler))
640 }
641
642 fn push_focus_reveal_handler(self, handler: CallbackWith<FocusRevealRequest, bool>) -> Self {
643 self.push_focus_op(FocusModifierOp::RevealHandler(handler))
644 }
645
646 fn push_focus_op(self, op: FocusModifierOp) -> Self {
647 self.push_action(ModifierAction::Focus(op))
648 }
649
650 pub fn attach(self) {
652 ensure_build_phase();
653
654 let actions = collect_actions(self.tail.clone());
655 TesseraRuntime::with_mut(|runtime| {
656 runtime.append_current_modifier(self.clone());
657 });
658
659 let mut accessibility = AccessibilityNode::new();
660 let mut action_handler = None;
661 let mut has_semantics = false;
662 for action in actions.into_iter().rev() {
663 match action {
664 ModifierAction::Build(node) => {
665 TesseraRuntime::with_mut(|runtime| node.apply(runtime));
666 }
667 ModifierAction::Semantics(node) => {
668 has_semantics = true;
669 node.apply(&mut accessibility, &mut action_handler);
670 }
671 ModifierAction::Focus(op) => {
672 TesseraRuntime::with_mut(|runtime| {
673 apply_focus_op(runtime::FocusModifierRuntime::new(runtime), op);
674 });
675 }
676 _ => {}
677 }
678 }
679
680 TesseraRuntime::with_mut(|runtime| {
681 runtime.set_current_accessibility(has_semantics.then_some(accessibility));
682 runtime.set_current_accessibility_action_handler(action_handler);
683 });
684 }
685
686 pub fn run<F>(self, child: F)
688 where
689 F: Fn() + Send + Sync + 'static,
690 {
691 self.attach();
692 child();
693 }
694
695 pub fn is_empty(&self) -> bool {
697 self.tail.is_none()
698 }
699
700 pub(crate) fn ordered_actions(&self) -> Vec<OrderedModifierAction> {
701 collect_actions_in_source_order(self.tail.clone())
702 .into_iter()
703 .filter_map(|action| match action {
704 ModifierAction::Layout(node) => Some(OrderedModifierAction::Layout(node)),
705 ModifierAction::Placement(node) => Some(OrderedModifierAction::Placement(node)),
706 ModifierAction::Draw(node) => Some(OrderedModifierAction::Draw(node)),
707 ModifierAction::ParentData(node) => Some(OrderedModifierAction::ParentData(node)),
708 ModifierAction::Cursor(node) => Some(OrderedModifierAction::Cursor(node)),
709 ModifierAction::PointerPreviewInput(node) => {
710 Some(OrderedModifierAction::PointerPreviewInput(node))
711 }
712 ModifierAction::PointerInput(node) => {
713 Some(OrderedModifierAction::PointerInput(node))
714 }
715 ModifierAction::PointerFinalInput(node) => {
716 Some(OrderedModifierAction::PointerFinalInput(node))
717 }
718 ModifierAction::KeyboardPreviewInput(node) => {
719 Some(OrderedModifierAction::KeyboardPreviewInput(node))
720 }
721 ModifierAction::KeyboardInput(node) => {
722 Some(OrderedModifierAction::KeyboardInput(node))
723 }
724 ModifierAction::ImePreviewInput(node) => {
725 Some(OrderedModifierAction::ImePreviewInput(node))
726 }
727 ModifierAction::ImeInput(node) => Some(OrderedModifierAction::ImeInput(node)),
728 ModifierAction::Build(_)
729 | ModifierAction::Semantics(_)
730 | ModifierAction::Focus(_) => None,
731 })
732 .collect()
733 }
734
735 pub(crate) fn layout_measure_eq(&self, other: &Self) -> bool {
736 let lhs: Vec<_> = self
737 .ordered_actions()
738 .into_iter()
739 .filter_map(|action| match action {
740 OrderedModifierAction::Layout(node) => Some(node),
741 _ => None,
742 })
743 .collect();
744 let rhs: Vec<_> = other
745 .ordered_actions()
746 .into_iter()
747 .filter_map(|action| match action {
748 OrderedModifierAction::Layout(node) => Some(node),
749 _ => None,
750 })
751 .collect();
752 lhs.len() == rhs.len()
753 && lhs
754 .iter()
755 .zip(rhs.iter())
756 .all(|(lhs, rhs)| lhs.measure_eq(rhs.as_ref()))
757 }
758
759 pub(crate) fn layout_placement_eq(&self, other: &Self) -> bool {
760 #[derive(Clone)]
761 enum PlacementComparableAction {
762 Layout(Arc<dyn ErasedLayoutModifierNode>),
763 Placement(Arc<dyn ErasedPlacementModifierNode>),
764 }
765
766 let lhs: Vec<_> = self
767 .ordered_actions()
768 .into_iter()
769 .filter_map(|action| match action {
770 OrderedModifierAction::Layout(node) => {
771 Some(PlacementComparableAction::Layout(node))
772 }
773 OrderedModifierAction::Placement(node) => {
774 Some(PlacementComparableAction::Placement(node))
775 }
776 _ => None,
777 })
778 .collect();
779 let rhs: Vec<_> = other
780 .ordered_actions()
781 .into_iter()
782 .filter_map(|action| match action {
783 OrderedModifierAction::Layout(node) => {
784 Some(PlacementComparableAction::Layout(node))
785 }
786 OrderedModifierAction::Placement(node) => {
787 Some(PlacementComparableAction::Placement(node))
788 }
789 _ => None,
790 })
791 .collect();
792 lhs.len() == rhs.len()
793 && lhs
794 .iter()
795 .zip(rhs.iter())
796 .all(|(lhs, rhs)| match (lhs, rhs) {
797 (
798 PlacementComparableAction::Layout(lhs),
799 PlacementComparableAction::Layout(rhs),
800 ) => lhs.placement_eq(rhs.as_ref()),
801 (
802 PlacementComparableAction::Placement(lhs),
803 PlacementComparableAction::Placement(rhs),
804 ) => lhs.eq(rhs.as_ref()),
805 _ => false,
806 })
807 }
808}
809
810impl ModifierCapabilityExt for Modifier {
811 fn push_layout<N>(self, node: N) -> Self
812 where
813 N: LayoutModifierNode + PartialEq,
814 {
815 Modifier::push_layout(self, node)
816 }
817
818 fn push_placement<N>(self, node: N) -> Self
819 where
820 N: PlacementModifierNode + PartialEq,
821 {
822 Modifier::push_placement(self, node)
823 }
824
825 fn push_draw<N>(self, node: N) -> Self
826 where
827 N: DrawModifierNode,
828 {
829 Modifier::push_draw(self, node)
830 }
831
832 fn push_parent_data<N>(self, node: N) -> Self
833 where
834 N: ParentDataModifierNode,
835 {
836 Modifier::push_parent_data(self, node)
837 }
838
839 fn push_build<N>(self, node: N) -> Self
840 where
841 N: BuildModifierNode,
842 {
843 Modifier::push_build(self, node)
844 }
845
846 fn push_semantics<N>(self, node: N) -> Self
847 where
848 N: SemanticsModifierNode,
849 {
850 Modifier::push_semantics(self, node)
851 }
852
853 fn push_pointer_preview_input<N>(self, node: N) -> Self
854 where
855 N: PointerInputModifierNode,
856 {
857 Modifier::push_pointer_preview_input(self, node)
858 }
859
860 fn push_pointer_input<N>(self, node: N) -> Self
861 where
862 N: PointerInputModifierNode,
863 {
864 Modifier::push_pointer_input(self, node)
865 }
866
867 fn push_pointer_final_input<N>(self, node: N) -> Self
868 where
869 N: PointerInputModifierNode,
870 {
871 Modifier::push_pointer_final_input(self, node)
872 }
873
874 fn push_keyboard_preview_input<N>(self, node: N) -> Self
875 where
876 N: KeyboardInputModifierNode,
877 {
878 Modifier::push_keyboard_preview_input(self, node)
879 }
880
881 fn push_keyboard_input<N>(self, node: N) -> Self
882 where
883 N: KeyboardInputModifierNode,
884 {
885 Modifier::push_keyboard_input(self, node)
886 }
887
888 fn push_ime_preview_input<N>(self, node: N) -> Self
889 where
890 N: ImeInputModifierNode,
891 {
892 Modifier::push_ime_preview_input(self, node)
893 }
894
895 fn push_ime_input<N>(self, node: N) -> Self
896 where
897 N: ImeInputModifierNode,
898 {
899 Modifier::push_ime_input(self, node)
900 }
901}
902
903#[derive(Clone, Copy)]
904struct StaticCursorModifierNode {
905 icon: CursorIcon,
906}
907
908impl CursorModifierNode for StaticCursorModifierNode {
909 fn cursor_icon(&self) -> CursorIcon {
910 self.icon
911 }
912}
913
914impl CursorModifierExt for Modifier {
915 fn hover_cursor_icon(self, icon: CursorIcon) -> Modifier {
916 self.push_cursor(StaticCursorModifierNode { icon })
917 }
918}
919
920impl FocusModifierExt for Modifier {
921 fn focusable(self) -> Modifier {
922 self.push_focus_target()
923 }
924
925 fn focus_requester(self, requester: FocusRequester) -> Modifier {
926 self.push_focus_requester(requester)
927 }
928
929 fn focus_properties(self, properties: FocusProperties) -> Modifier {
930 self.push_focus_properties(properties)
931 }
932
933 fn focus_group(self) -> Modifier {
934 self.push_focus_group()
935 }
936
937 fn focus_scope_with(self, scope: FocusScopeNode) -> Modifier {
938 self.push_focus_scope_with(scope)
939 }
940
941 fn focus_group_with(self, group: FocusGroupNode) -> Modifier {
942 self.push_focus_group_with(group)
943 }
944
945 fn focus_restorer(self, fallback: Option<FocusRequester>) -> Modifier {
946 self.push_focus_restorer(fallback)
947 }
948
949 fn focus_restorer_with(
950 self,
951 scope: FocusScopeNode,
952 fallback: Option<FocusRequester>,
953 ) -> Modifier {
954 self.push_focus_restorer_with(scope, fallback)
955 }
956
957 fn focus_traversal_policy(self, policy: FocusTraversalPolicy) -> Modifier {
958 self.push_focus_traversal_policy(policy)
959 }
960
961 fn on_focus_changed<F>(self, handler: F) -> Modifier
962 where
963 F: Into<CallbackWith<FocusState>>,
964 {
965 self.push_focus_changed_handler(handler.into())
966 }
967
968 fn on_focus_event<F>(self, handler: F) -> Modifier
969 where
970 F: Into<CallbackWith<FocusState>>,
971 {
972 self.push_focus_event_handler(handler.into())
973 }
974
975 fn focus_beyond_bounds_handler<F>(self, handler: F) -> Modifier
976 where
977 F: Into<CallbackWith<FocusDirection, bool>>,
978 {
979 self.push_focus_beyond_bounds_handler(handler.into())
980 }
981
982 fn focus_reveal_handler<F>(self, handler: F) -> Modifier
983 where
984 F: Into<CallbackWith<FocusRevealRequest, bool>>,
985 {
986 self.push_focus_reveal_handler(handler.into())
987 }
988}
989
990impl fmt::Debug for Modifier {
991 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992 f.debug_struct("Modifier")
993 .field("is_empty", &self.tail.is_none())
994 .finish()
995 }
996}
997
998impl PartialEq for Modifier {
999 fn eq(&self, other: &Self) -> bool {
1000 match (&self.tail, &other.tail) {
1001 (None, None) => true,
1002 (Some(lhs), Some(rhs)) => Arc::ptr_eq(lhs, rhs),
1003 _ => false,
1004 }
1005 }
1006}
1007
1008impl Eq for Modifier {}
1009
1010impl Hash for Modifier {
1011 fn hash<H: Hasher>(&self, state: &mut H) {
1012 match &self.tail {
1013 Some(node) => std::ptr::hash(Arc::as_ptr(node), state),
1014 None => 0u8.hash(state),
1015 }
1016 }
1017}
1018
1019mod runtime {
1020 use super::FocusModifierRegistration;
1021 use crate::{
1022 FocusProperties, FocusRequester, FocusScopeNode, FocusState, FocusTraversalPolicy,
1023 focus::{FocusDirection, FocusRevealRequest},
1024 prop::CallbackWith,
1025 runtime::TesseraRuntime,
1026 };
1027
1028 pub(super) struct FocusModifierRuntime<'a> {
1029 runtime: &'a mut TesseraRuntime,
1030 }
1031
1032 impl<'a> FocusModifierRuntime<'a> {
1033 pub(super) fn new(runtime: &'a mut TesseraRuntime) -> Self {
1034 Self { runtime }
1035 }
1036
1037 pub(super) fn bind_requester(&mut self, requester: FocusRequester) {
1038 self.runtime.bind_current_focus_requester(requester);
1039 }
1040
1041 pub(super) fn ensure_registration(&mut self, registration: FocusModifierRegistration) {
1042 match registration {
1043 FocusModifierRegistration::Target(node) => {
1044 let node = node.unwrap_or_else(|| {
1045 self.runtime
1046 .current_focus_target_handle()
1047 .unwrap_or_else(|| {
1048 crate::runtime::persistent_focus_target_for_current_instance(
1049 "__tessera_focus_target",
1050 )
1051 })
1052 });
1053 self.runtime.ensure_current_focus_target(node);
1054 }
1055 FocusModifierRegistration::Scope(scope) => {
1056 let scope = scope.unwrap_or_else(|| {
1057 self.runtime
1058 .current_focus_scope_handle()
1059 .unwrap_or_else(|| {
1060 crate::runtime::persistent_focus_scope_for_current_instance(
1061 "__tessera_focus_scope",
1062 )
1063 })
1064 });
1065 self.runtime.ensure_current_focus_scope(scope);
1066 }
1067 FocusModifierRegistration::Group(group) => {
1068 let group = group.unwrap_or_else(|| {
1069 self.runtime
1070 .current_focus_group_handle()
1071 .unwrap_or_else(|| {
1072 crate::runtime::persistent_focus_group_for_current_instance(
1073 "__tessera_focus_group",
1074 )
1075 })
1076 });
1077 self.runtime.ensure_current_focus_group(group);
1078 }
1079 FocusModifierRegistration::Restorer { scope, fallback } => {
1080 let scope: FocusScopeNode = scope.unwrap_or_else(|| {
1081 self.runtime
1082 .current_focus_scope_handle()
1083 .unwrap_or_else(|| {
1084 crate::runtime::persistent_focus_scope_for_current_instance(
1085 "__tessera_focus_scope",
1086 )
1087 })
1088 });
1089 self.runtime.ensure_current_focus_scope(scope);
1090 if let Some(fallback) = fallback {
1091 self.runtime.set_current_focus_restorer_fallback(fallback);
1092 }
1093 }
1094 }
1095 }
1096
1097 pub(super) fn set_properties(&mut self, properties: FocusProperties) {
1098 self.runtime.set_current_focus_properties(properties);
1099 }
1100
1101 pub(super) fn set_traversal_policy(&mut self, policy: FocusTraversalPolicy) {
1102 self.runtime.set_current_focus_traversal_policy(policy);
1103 }
1104
1105 pub(super) fn set_changed_handler(&mut self, handler: CallbackWith<FocusState>) {
1106 self.runtime.set_current_focus_changed_handler(handler);
1107 }
1108
1109 pub(super) fn set_event_handler(&mut self, handler: CallbackWith<FocusState>) {
1110 self.runtime.set_current_focus_event_handler(handler);
1111 }
1112
1113 pub(super) fn set_beyond_bounds_handler(
1114 &mut self,
1115 handler: CallbackWith<FocusDirection, bool>,
1116 ) {
1117 self.runtime
1118 .set_current_focus_beyond_bounds_handler(handler);
1119 }
1120
1121 pub(super) fn set_reveal_handler(
1122 &mut self,
1123 handler: CallbackWith<FocusRevealRequest, bool>,
1124 ) {
1125 self.runtime.set_current_focus_reveal_handler(handler);
1126 }
1127 }
1128}
1129
1130fn apply_focus_op(runtime: runtime::FocusModifierRuntime<'_>, op: FocusModifierOp) {
1131 let mut runtime = runtime;
1132 match op {
1133 FocusModifierOp::Requester(requester) => runtime.bind_requester(requester),
1134 FocusModifierOp::Registration(registration) => runtime.ensure_registration(registration),
1135 FocusModifierOp::Properties(properties) => runtime.set_properties(properties),
1136 FocusModifierOp::TraversalPolicy(policy) => runtime.set_traversal_policy(policy),
1137 FocusModifierOp::ChangedHandler(handler) => runtime.set_changed_handler(handler),
1138 FocusModifierOp::EventHandler(handler) => runtime.set_event_handler(handler),
1139 FocusModifierOp::BeyondBoundsHandler(handler) => runtime.set_beyond_bounds_handler(handler),
1140 FocusModifierOp::RevealHandler(handler) => runtime.set_reveal_handler(handler),
1141 }
1142}