1 ///
2 module fluid.structs;
3 
4 import std.conv;
5 
6 
7 @safe:
8 
9 
10 enum NodeAlign {
11 
12     start, center, end, fill
13 
14 }
15 
16 /// Create a new layout
17 /// Params:
18 ///     expand = Numerator of the fraction of space this node should occupy in the parent.
19 ///     align_ = Align of the node (horizontal and vertical).
20 ///     alignX = Horizontal align of the node.
21 ///     alignY = Vertical align of the node.
22 Layout layout(uint expand, NodeAlign alignX, NodeAlign alignY) pure {
23 
24     return Layout(expand, [alignX, alignY]);
25 
26 }
27 
28 /// Ditto
29 Layout layout(uint expand, NodeAlign align_) pure {
30 
31     return Layout(expand, align_);
32 
33 }
34 
35 /// Ditto
36 Layout layout(NodeAlign alignX, NodeAlign alignY) pure {
37 
38     return Layout(0, [alignX, alignY]);
39 
40 }
41 
42 /// Ditto
43 Layout layout(NodeAlign align_) pure {
44 
45     return Layout(0, align_);
46 
47 }
48 
49 /// Ditto
50 Layout layout(uint expand) pure {
51 
52     return Layout(expand);
53 
54 }
55 
56 /// CTFE version of the layout constructor, allows using strings instead of enum members, to avoid boilerplate.
57 Layout layout(uint expand, string alignX, string alignY)() pure {
58 
59     enum valueX = alignX.to!NodeAlign;
60     enum valueY = alignY.to!NodeAlign;
61 
62     return Layout(expand, [valueX, valueY]);
63 
64 }
65 
66 /// Ditto
67 Layout layout(uint expand, string align_)() pure {
68 
69     enum valueXY = align_.to!NodeAlign;
70 
71     return Layout(expand, valueXY);
72 
73 }
74 
75 /// Ditto
76 Layout layout(string alignX, string alignY)() pure {
77 
78     enum valueX = alignX.to!NodeAlign;
79     enum valueY = alignY.to!NodeAlign;
80 
81     return Layout(0, [valueX, valueY]);
82 
83 }
84 
85 /// Ditto
86 Layout layout(string align_)() pure {
87 
88     enum valueXY = align_.to!NodeAlign;
89 
90     return Layout(0, valueXY);
91 
92 }
93 
94 /// Ditto
95 Layout layout(uint expand)() pure {
96 
97     return Layout(expand);
98 
99 }
100 
101 unittest {
102 
103     assert(layout!1 == layout(1));
104     assert(layout!("fill") == layout(NodeAlign.fill, NodeAlign.fill));
105     assert(layout!("fill", "fill") == layout(NodeAlign.fill));
106 
107     assert(!__traits(compiles, layout!"expand"));
108     assert(!__traits(compiles, layout!("expand", "noexpand")));
109     assert(!__traits(compiles, layout!(1, "whatever")));
110     assert(!__traits(compiles, layout!(2, "foo", "bar")));
111 
112 }
113 
114 /// Represents a node's layout
115 struct Layout {
116 
117     /// Fraction of available space this node should occupy in the node direction.
118     ///
119     /// If set to `0`, the node doesn't have a strict size limit and has size based on content.
120     uint expand;
121 
122     /// Align the content box to a side of the occupied space.
123     NodeAlign[2] nodeAlign;
124 
125     string toString() const {
126 
127         import std.format;
128 
129         const equalAlign = nodeAlign[0] == nodeAlign[1];
130         const startAlign = equalAlign && nodeAlign[0] == NodeAlign.start;
131 
132         if (expand) {
133 
134             if (startAlign) return format!".layout!%s"(expand);
135             else if (equalAlign) return format!".layout!(%s, %s)"(expand, nodeAlign[0]);
136             else return format!".layout!(%s, %s, %s)"(expand, nodeAlign[0], nodeAlign[1]);
137 
138         }
139 
140         else {
141 
142             if (startAlign) return format!"Layout()";
143             else if (equalAlign) return format!".layout!%s"(nodeAlign[0]);
144             else return format!".layout!(%s, %s)"(nodeAlign[0], nodeAlign[1]);
145 
146         }
147 
148     }
149 
150 }
151 
152 /// Node core constructor parameters, to be passed from node to node.
153 struct NodeParams {
154 
155     import fluid.style;
156 
157     Layout layout;
158     Theme theme;
159 
160     this(Layout layout, Theme theme = null) {
161 
162         this.layout = layout;
163         this.theme  = theme;
164 
165     }
166 
167     /// Ditto
168     this(Theme theme, Layout layout = Layout.init) {
169 
170         this(layout, theme);
171 
172     }
173 
174 }