Skip to main content

ferroui_xaml_interactivity/templates/
behavior_collection_template.rs

1//! Port of `Templates/BehaviorCollectionTemplate.cs`.
2
3use crate::BehaviorCollection;
4use ferroui_base::styling::ITemplate;
5use ferroui_base::{ferro_markup_type, BoxedValue};
6use ferroui_markup_xaml::templates::TemplateContent;
7use std::cell::RefCell;
8use std::rc::Rc;
9
10/// A template for creating a collection of [`IBehavior`](crate::IBehavior) objects.
11///
12/// As the value of a style setter of `(Interaction.Behaviors)` it builds a new collection for
13/// each element the style applies to (a collection attaches to one object only).
14#[derive(Default)]
15pub struct BehaviorCollectionTemplate {
16    content: RefCell<Option<BoxedValue>>,
17}
18
19impl BehaviorCollectionTemplate {
20    /// Creates an empty template.
21    pub fn new() -> Rc<Self> {
22        Rc::new(Self::default())
23    }
24
25    /// Gets or sets the content of the template: deferred content built on each
26    /// [`build`](Self::build).
27    pub fn content(&self) -> Option<BoxedValue> {
28        self.content.borrow().clone()
29    }
30
31    pub fn set_content(&self, value: Option<BoxedValue>) {
32        *self.content.borrow_mut() = value;
33    }
34
35    /// Builds the collection of behaviors from the template.
36    ///
37    /// # Panics
38    /// Panics if the content is not template content, or builds something else than a
39    /// collection of behaviors.
40    pub fn build(&self) -> Option<BehaviorCollection> {
41        TemplateContent::load_as::<BehaviorCollection>(self.content().as_ref()).map(|result| result.result().clone())
42    }
43}
44
45impl ITemplate for BehaviorCollectionTemplate {
46    /// Builds the collection of behaviors from the template, as the value of the attached
47    /// property (an optional collection).
48    fn build(&self) -> BoxedValue {
49        Rc::new(BehaviorCollectionTemplate::build(self))
50    }
51}
52
53impl PartialEq for BehaviorCollectionTemplate {
54    fn eq(&self, other: &Self) -> bool {
55        std::ptr::eq(self, other)
56    }
57}
58
59ferro_markup_type!(class BehaviorCollectionTemplate {
60    this: Rc<BehaviorCollectionTemplate>,
61    handles: [BehaviorCollectionTemplate, Rc<BehaviorCollectionTemplate>, Option<Rc<BehaviorCollectionTemplate>>],
62    interfaces: [Rc<dyn ITemplate>],
63    constructors: [() => BehaviorCollectionTemplate::new],
64    content: Content,
65    properties: [
66        Content: Option<BoxedValue> {
67            get: BehaviorCollectionTemplate::content,
68            set: BehaviorCollectionTemplate::set_content
69        } [TemplateContent(TemplateResultType = type(BehaviorCollection))],
70    ],
71});