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 }