Skip to main content

ferroui_xaml_interactivity/templates/
object_template.rs

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