1 /** 2 * Copyright: Enalye 3 * License: Zlib 4 * Authors: Enalye 5 */ 6 module atelier.ui.container.vcontainer; 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 /// Vertical container. \ 14 /// Align its children vertically without changing their size. \ 15 /// Resized automatically to fits its children. 16 class VContainer : GuiElement { 17 protected { 18 Vec2f _spacing = Vec2f.zero; 19 GuiAlignX _childAlignX = GuiAlignX.center; 20 float _minimalWidth = 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 minimalWidth() const { 35 return _minimalWidth; 36 } 37 38 float minimalWidth(float newMinimalWidth) { 39 _minimalWidth = newMinimalWidth; 40 resize(); 41 return _minimalWidth; 42 } 43 } 44 45 /// Ctor 46 this() { 47 } 48 49 override void appendChild(GuiElement gui) { 50 gui.setAlign(_childAlignX, GuiAlignY.top); 51 super.appendChild(gui); 52 resize(); 53 } 54 55 void setChildAlign(GuiAlignX childAlignX) { 56 _childAlignX = childAlignX; 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(_minimalWidth, 0f); 81 foreach (GuiElement gui; _children) { 82 totalSize.y += gui.scaledSize.y + _spacing.y; 83 totalSize.x = max(totalSize.x, gui.scaledSize.x); 84 } 85 size = totalSize + Vec2f(_spacing.x * 2f, _spacing.y); 86 Vec2f currentPosition = _spacing; 87 foreach (GuiElement gui; _children) { 88 gui.setAlign(_childAlignX, GuiAlignY.top); 89 gui.position = currentPosition; 90 currentPosition = currentPosition + Vec2f(0f, gui.scaledSize.y + _spacing.y); 91 } 92 _isResizeCalled = false; 93 } 94 }