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