1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use dces::prelude::Entity;

use crate::{layout::*, render_object::*};

use super::BuildContext;

/// The `Template` trait defines the template of a particular type of a widget.
///
/// A widget's `Template` consists three type of objects:
/// * default values of its properties, children, handlers
/// * a render object
/// * a layout object
pub trait Template: Sized {
    /// Builds the template of the widget and returns it.
    ///
    /// # Arguments
    /// * `_id`: The id (Entity) of the instantiated widget in the Entity Store
    /// * `_context`: The BuildContext used to build and instantiate new widgets
    ///
    /// # Example
    /// Define a widget called MyWidget with min, max and val properties with type of usize,
    /// and then set default values and add a TextBlock child.
    ///
    /// ```
    /// widget!(MyWidget {
    ///     min: usize,
    ///     max: usize,
    ///     val: usize
    /// });
    ///
    /// impl Template for MyWidget {
    ///     fn template(self, _id: Entity, context: &mut BuildContext) -> Self {
    ///         self.name("MyWidget")
    ///             .min(100)
    ///             .max(1000)
    ///             .val(500)
    ///             .child(TextBlock::new().text("Set a value!").build(context))
    ///     }
    ///
    ///     fn render_object(&self) -> Box<dyn RenderObject> {
    ///         Box::new(RectangleRenderObject)
    ///     }
    ///
    ///     fn layout(&self) -> Box<dyn Layout> {
    ///        Box::new(AbsoluteLayout)
    ///     }
    /// }
    /// ```
    fn template(self, _id: Entity, _context: &mut BuildContext) -> Self {
        self
    }

    /// Returns a pointer to a heap allocated object
    /// which specifies how the widget should be drawn on the canvas.
    /// For the list of available render objects, see the [`render_object`] module.
    fn render_object(&self) -> Box<dyn RenderObject> {
        Box::new(DefaultRenderObject)
    }

    /// Returns a pointer to a heap allocated object
    /// which specifies the way in which the widget are arranged or laid out on the canvas.
    /// For the list of available layout objects, see the [`layout`] module.
    fn layout(&self) -> Box<dyn Layout> {
        Box::new(GridLayout::new())
    }
}