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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
pub use euclid::Rect;

use crate::{
    alignment::Alignment, direction::DirectionMode, gaps::Gaps, geometry::Length, size::Size,
};

/// Node layout configuration
#[derive(PartialEq, Clone, Debug, Default)]
pub struct Node {
    /// Dimentions
    pub width: Size,
    pub height: Size,

    // Minimum dimensions
    pub minimum_width: Size,
    pub minimum_height: Size,

    // Maximum dimensions
    pub maximum_width: Size,
    pub maximum_height: Size,

    // Axis alignments for the children
    pub main_alignment: Alignment,
    pub cross_alignment: Alignment,

    /// Inner padding
    pub padding: Gaps,

    /// Inner margin
    pub margin: Gaps,

    /// Inner position offsets
    pub offset_x: Length,
    pub offset_y: Length,

    /// Direction in which it's inner Nodes will be stacked
    pub direction: DirectionMode,

    /// A Node might depend on inner sizes but have a fixed position, like scroll views.
    pub has_layout_references: bool,
}

impl Node {
    /// Create a Node with the default values
    pub fn new() -> Self {
        Self::default()
    }

    /// Construct a new Node given a size and a direction
    pub fn from_size_and_direction(width: Size, height: Size, direction: DirectionMode) -> Self {
        Self {
            width,
            height,
            direction,
            ..Default::default()
        }
    }

    /// Construct a new Node given a size and a scroll
    pub fn from_size_and_scroll(
        width: Size,
        height: Size,
        offset_x: Length,
        offset_y: Length,
    ) -> Self {
        Self {
            width,
            height,
            offset_x,
            offset_y,
            ..Default::default()
        }
    }

    /// Construct a new Node given a size and padding
    pub fn from_size_and_padding(width: Size, height: Size, padding: Gaps) -> Self {
        Self {
            width,
            height,
            padding,
            ..Default::default()
        }
    }

    /// Construct a new Node given a size, alignments and a direction
    pub fn from_size_and_alignments_and_direction(
        width: Size,
        height: Size,
        main_alignment: Alignment,
        cross_alignment: Alignment,
        direction: DirectionMode,
    ) -> Self {
        Self {
            width,
            height,
            main_alignment,
            cross_alignment,
            direction,
            ..Default::default()
        }
    }

    /// Construct a new Node given a size and a direction
    pub fn from_size_and_margin(width: Size, height: Size, margin: Gaps) -> Self {
        Self {
            width,
            height,
            margin,
            ..Default::default()
        }
    }

    /// Has properties that depend on the inner Nodes?
    pub fn does_depend_on_inner(&self) -> bool {
        Size::Inner == self.width || Size::Inner == self.height || self.has_layout_references
        // || self.main_alignment.is_not_start()
        // || self.cross_alignment.is_not_start()
    }
}