1 /** 
2  * Copyright: Enalye
3  * License: Zlib
4  * Authors: Enalye
5  */
6 module atelier.ui.layout.gridlayout;
7 
8 import std.conv : to;
9 import std.algorithm.comparison : max;
10 import atelier.render, atelier.core, atelier.common;
11 import atelier.ui.gui_element;
12 
13 /// Resize children to fit and align them on a grid.
14 class GridLayout : GuiElement {
15     private {
16         Vec2f _spacing = Vec2f.zero;
17         Vec2u _capacity;
18     }
19 
20     @property {
21         Vec2f spacing() const {
22             return _spacing;
23         }
24 
25         Vec2f spacing(Vec2f newPadding) {
26             _spacing = newPadding;
27             resize();
28             return _spacing;
29         }
30 
31         Vec2u capacity() const {
32             return _capacity;
33         }
34 
35         Vec2u capacity(Vec2u newCapacity) {
36             _capacity = newCapacity;
37             resize();
38             return _capacity;
39         }
40     }
41 
42     /// Ctor
43     this() {
44     }
45 
46     /// Ctor
47     this(Vec2f newSize) {
48         size = newSize;
49     }
50 
51     override void appendChild(GuiElement gui) {
52         gui.setAlign(GuiAlignX.left, GuiAlignY.top);
53         super.appendChild(gui);
54         resize();
55     }
56 
57     override void onSize() {
58         resize();
59     }
60 
61     protected void resize() {
62         if (!_children.length || _capacity.x == 0u)
63             return;
64 
65         int yCapacity = _capacity.y;
66         if (yCapacity == 0u)
67             yCapacity = (to!int(_children.length) / _capacity.x) + 1;
68 
69         Vec2f childSize = Vec2f(size.x / _capacity.x, size.y / yCapacity);
70         foreach (size_t id, GuiElement gui; _children) {
71             Vec2u coords = Vec2u(id % _capacity.x, cast(uint) id / _capacity.x);
72             gui.position = Vec2f(childSize.x * coords.x, childSize.y * coords.y);
73             gui.size = childSize - _spacing;
74         }
75     }
76 }