1     type Stack @mut =
2         inherit Panel
3     
4         var is_horizontal = false
5         var distance : u32 = 0
6     
7         def Control.measure w h =
8             let mut res_w = 0
9             let mut res_h = 0
10            let mut count = 0
11    
12            let (item_width, item_height) = if is_horizontal
13                                            then (Control.max_size, h)
14                                            else (w, Control.max_size)
15            for item in items do
16                measure_clamped item item_width item_height
17                let dimension = if is_horizontal
18                                then item.measure_width
19                                else item.measure_height
20    
21                if item.is_visible && dimension > 0 then
22                    if is_horizontal then
23                        res_h = res_h.max item.measure_height
24                        res_w += item.measure_width
25                    else
26                        res_w = res_w.max item.measure_width
27                        res_h += item.measure_height
28    
29                    count += 1
30                else
31                    if is_horizontal then
32                        res_h = res_h.max item.measure_height
33                    else
34                        res_w = res_w.max item.measure_width
35    
36            let d_sum = count - 1 |> max 0 as u32 * distance
37            if is_horizontal then
38                res_w += d_sum
39            else
40                res_h += d_sum
41    
42            measure_width = res_w
43            measure_height = res_h
44    
45        def Control.arrange self =
46            let distance = self.distance
47            let items = self.items
48            if items.is_empty then
49                return
50    
51            let stack_width = self.width
52            let stack_height = self.height
53    
54            if self.is_horizontal then
55                assert stack_width >= self.measure_width
56                let get_y (control : Control) =
57                    let control_height = control.height
58                    let y = if control_height >= stack_height then
59                        0
60                    else
61                        case control.align_v of
62                            AlignV/Up | AlignV/Stretch -> 0
63                            AlignV/Down -> stack_height - control_height
64                            AlignV/Center -> (stack_height - control_height) / 2
65    
66                    y as f32
67    
68                let get_height (control : Control) =
69                    if control.align_v == AlignV/Stretch
70                    then stack_height
71                    else control.measure_height
72    
73                let mut x = 0
74                for item in items do
75                    if not item.is_visible then
76                        continue
77    
78                    item.width = item.measure_width
79                         height = get_height item
80                         arrange
81    
82                    let v = Vector3 x.as<f32> (get_y item) Control.offset_z
83                    item.position = v
84                    let width = item.width
85                    if width > 0 then
86                        x += width + distance
87            else
88                let get_x (control : Control) =
89                    case control.align_h of
90                        AlignH/Left | AlignH/Stretch -> 0
91                        AlignH/Right -> stack_width - control.width
92                        AlignH/Center -> (stack_width - control.width) / 2
93                    |> as<f32>
94    
95                let get_width (control : Control) =
96                    if control.align_h == AlignH/Stretch
97                    then stack_width
98                    else control.measure_width.min stack_width
99    
100               let mut y = 0
101               for item in items do
102                   if not item.is_visible then
103                       continue
104   
105                   item.width = get_width item
106                        height = item.measure_height
107                        arrange
108   
109                   assert item.width <= stack_width
110                   let v = Vector3 (get_x item) y.as<f32> Control.offset_z
111                   item.position = v
112                   let height = item.height
113                   if height > 0 then
114                       y += height + distance
115   
116               let height = y - distance
117               if height <> stack_height then
118                   self.height = height
119                   assert self.height >= height
120