1 /** 
2  * Copyright: Enalye
3  * License: Zlib
4  * Authors: Enalye
5  */
6 module atelier.ui.container.hcontainer;
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 /// Horizontal container. \
14 /// Align its children horizontally without changing their size. \
15 /// Resized automatically to fits its children.
16 class HContainer : GuiElement {
17     protected {
18         Vec2f _spacing = Vec2f.zero;
19         GuiAlignY _childAlignY = GuiAlignY.center;
20         float _minimalHeight = 0f;
21     }
22 
23     @property {
24         Vec2f spacing() const {
25             return _spacing;
26         }
27 
28         Vec2f spacing(Vec2f newPadding) {
29             _spacing = newPadding;
30             resize();
31             return _spacing;
32         }
33 
34         float minimalHeight() const {
35             return _minimalHeight;
36         }
37 
38         float minimalHeight(float newMinimalHeight) {
39             _minimalHeight = newMinimalHeight;
40             resize();
41             return _minimalHeight;
42         }
43     }
44 
45     /// Ctor
46     this() {
47     }
48 
49     override void appendChild(GuiElement gui) {
50         gui.setAlign(GuiAlignX.left, _childAlignY);
51         super.appendChild(gui);
52         resize();
53     }
54 
55     void setChildAlign(GuiAlignY childAlignY) {
56         _childAlignY = childAlignY;
57         resize();
58     }
59 
60     override void update(float deltatime) {
61         resize();
62     }
63 
64     override void onSize() {
65         resize();
66     }
67 
68     private bool _isResizeCalled;
69     protected void resize() {
70         if (_isResizeCalled)
71             return;
72         _isResizeCalled = true;
73 
74         if (!_children.length) {
75             size = Vec2f.zero;
76             _isResizeCalled = false;
77             return;
78         }
79 
80         Vec2f totalSize = Vec2f(0f, _minimalHeight);
81         foreach (GuiElement gui; _children) {
82             totalSize.y = max(totalSize.y, gui.scaledSize.y);
83             totalSize.x += gui.scaledSize.x + _spacing.x;
84         }
85         size = totalSize + Vec2f(_spacing.x, _spacing.y * 2f);
86         Vec2f currentPosition = _spacing;
87         foreach (GuiElement gui; _children) {
88             gui.setAlign(GuiAlignX.left, _childAlignY);
89             gui.position = currentPosition;
90             currentPosition = currentPosition + Vec2f(gui.scaledSize.x + _spacing.x, 0f);
91         }
92         _isResizeCalled = false;
93     }
94 }