Skip to main content

ferroui_xaml_interactions_custom/icon/
path_icon_data_behavior.rs

1//! Port of `Icon/PathIconDataBehavior.cs`.
2
3use crate::{AttachedToVisualTreeBehavior, AttachedToVisualTreeBehaviorImpl};
4use ferroui_base::media::Geometry;
5use ferroui_base::reactive::IDisposable;
6use ferroui_base::{
7    ferro_class, ferro_class_info, ferro_properties, instantiate, FerroObjectImpl, FerroProperty, Nullable, Ref,
8    StaticType, StyledElementImpl, StyledProperty,
9};
10use ferroui_controls::PathIcon;
11use ferroui_xaml_interactivity::{DisposableAction, DisposingBehaviorImpl, StyledElementBehaviorImpl};
12use std::cell::RefCell;
13use std::rc::Rc;
14
15/// Sets the [`PathIcon::data`] when the associated icon is attached to the visual tree; the data
16/// the icon had is restored when it leaves the visual tree.
17#[repr(C)]
18pub struct PathIconDataBehavior {
19    base: AttachedToVisualTreeBehavior,
20    old_data: RefCell<Option<Ref<Geometry>>>,
21}
22
23ferro_class!(PathIconDataBehavior: AttachedToVisualTreeBehavior);
24ferro_class_info!(PathIconDataBehavior { new: PathIconDataBehavior::new });
25ferroui_base::ferro_impl_classes!(
26    PathIconDataBehavior: FerroObjectImpl,
27    StyledElementImpl,
28    StyledElementBehaviorImpl,
29    DisposingBehaviorImpl,
30);
31
32ferro_properties! {
33    impl PathIconDataBehavior {
34        /// Identifies the `Data` property.
35        pub fn data_property() -> StyledProperty<Option<Ref<Geometry>>> {
36            FerroProperty::register::<PathIconDataBehavior, _>("Data", None)
37        }
38    }
39}
40
41ferroui_base::ferro_overrides! {
42    impl AttachedToVisualTreeBehaviorImpl for PathIconDataBehavior {
43        fn on_attached_to_visual_tree_override(this: &Self) -> Rc<dyn IDisposable> {
44            let Some(associated_object) = this.associated_object_as::<PathIcon>() else {
45                return DisposableAction::empty();
46            };
47
48            *this.old_data.borrow_mut() = associated_object.data();
49            if let Some(data) = this.data() {
50                associated_object.set_data(data);
51            }
52
53            let behavior = this.to_ref().downgrade();
54            DisposableAction::create(move || {
55                if let Some(behavior) = behavior.upgrade() {
56                    if let Some(associated_object) = behavior.associated_object_as::<PathIcon>() {
57                        let old_data = behavior.old_data.borrow().clone();
58                        associated_object.set_data(old_data);
59                    }
60                }
61            })
62        }
63    }
64}
65
66impl PathIconDataBehavior {
67    /// Creates the class data; see [`ferroui_base::FerroObject::construct`].
68    pub fn construct() -> Self {
69        Self { base: AttachedToVisualTreeBehavior::construct(<PathIcon as StaticType>::TYPE), old_data: RefCell::new(None) }
70    }
71
72    /// Creates a behavior.
73    pub fn new() -> Ref<Self> {
74        instantiate(Self::construct())
75    }
76
77    /// Gets or sets the geometry used for the icon. This is a property of the object model.
78    pub fn data(&self) -> Option<Ref<Geometry>> {
79        self.get_value(Self::data_property())
80    }
81
82    pub fn set_data(&self, value: impl Into<Nullable<Geometry>>) {
83        self.set_value(Self::data_property(), value.into().0)
84    }
85}