1 /** 2 Log list 3 4 Copyright: (c) Enalye 2017 5 License: Zlib 6 Authors: Enalye 7 */ 8 9 module atelier.ui.list.loglist; 10 11 import std.conv : to; 12 import atelier.core, atelier.render, atelier.common; 13 import atelier.ui.gui_element, atelier.ui.layout, atelier.ui.slider; 14 15 private class LogContainer : GuiElement { 16 public { 17 LogLayout layout; 18 } 19 20 this(Vec2f newSize) { 21 isLocked = true; 22 layout = new LogLayout; 23 size(newSize); 24 appendChild(layout); 25 hasCanvas(true); 26 } 27 28 override void draw() { 29 layout.draw(); 30 } 31 } 32 33 class LogList : GuiElement { 34 protected { 35 LogContainer _container; 36 Slider _slider; 37 Vec2f _lastMousePos = Vec2f.zero; 38 uint _idElementSelected = 0u; 39 } 40 41 @property { 42 uint selected() const { 43 return _idElementSelected; 44 } 45 46 /// The list of all its children. 47 override const(GuiElement[]) children() const { 48 return _container.layout.children; 49 } 50 /// Ditto 51 override GuiElement[] children() { 52 return _container.layout.children; 53 } 54 55 /// Return the first child gui. 56 override GuiElement firstChild() { 57 return _container.layout.firstChild; 58 } 59 60 /// Return the last child gui. 61 override GuiElement lastChild() { 62 return _container.layout.lastChild; 63 } 64 65 /// The number of children it currently has. 66 override size_t childCount() const { 67 return _container.layout.childCount; 68 } 69 } 70 71 this(Vec2f newSize) { 72 isLocked = true; 73 _slider = new VScrollbar; 74 _slider.value01 = 1f; 75 _container = new LogContainer(newSize); 76 77 super.appendChild(_slider); 78 super.appendChild(_container); 79 80 size(newSize); 81 position(Vec2f.zero); 82 } 83 84 override void onEvent(Event event) { 85 super.onEvent(event); 86 if (event.type == Event.Type.mouseDown || event.type == Event.Type.mouseUp 87 || event.type == Event.Type.mouseUpdate) { 88 _lastMousePos = event.mouse.position; 89 if (_slider.isInside(event.mouse.position)) 90 _slider.onEvent(event); 91 else if (event.type == Event.Type.mouseDown) { 92 auto widgets = _container.layout.children; 93 foreach (size_t id, const GuiElement widget; widgets) { 94 if (widget.isHovered) 95 _idElementSelected = cast(uint) id; 96 } 97 } 98 } 99 if (!isOnInteractableGuiElement(_lastMousePos) && event.type == Event.Type.mouseWheel) 100 _slider.onEvent(event); 101 } 102 103 override void onPosition() { 104 _slider.position = center - Vec2f((size.x - _slider.size.x) / 2f, 0f) + size / 2f; 105 _container.position = center + Vec2f(_slider.size.x / 2f, 0f) + size / 2f; 106 } 107 108 override void onSize() { 109 _slider.size = Vec2f(10f, size.y); 110 _container.size = Vec2f(size.x - _slider.size.x, size.y); 111 _container.canvas.renderSize = _container.size.to!Vec2i; 112 onPosition(); 113 } 114 115 override void update(float deltaTime) { 116 _slider.update(deltaTime); 117 float min = _container.canvas.size.y / 2f; 118 float max = _container.layout.size.y - _container.canvas.size.y / 2f; 119 float exceedingHeight = _container.layout.size.y - _container.canvas.size.y; 120 121 if (exceedingHeight < 0f) { 122 _slider.max = 0; 123 _slider.step = 0; 124 } 125 else { 126 _slider.max = exceedingHeight / (_container.canvas.size.y / 50f); 127 _slider.step = to!uint(_slider.max); 128 } 129 _container.canvas.position = Vec2f(0f, lerp(min, max, _slider.offset)); 130 } 131 132 private void repositionContainer() { 133 _container.layout.position = Vec2f(5f + _container.layout.size.x / 2f - _container.size.x / 2f, 134 _container.layout.size.y / 2f); 135 } 136 137 override void prependChild(GuiElement gui) { 138 _container.layout.prependChild(gui); 139 repositionContainer(); 140 } 141 142 override void appendChild(GuiElement gui) { 143 _container.layout.appendChild(gui); 144 repositionContainer(); 145 } 146 147 override void removeChildren() { 148 _container.layout.removeChildren(); 149 repositionContainer(); 150 } 151 152 override void removeChild(size_t id) { 153 _container.layout.removeChild(id); 154 repositionContainer(); 155 } 156 157 override void removeChild(GuiElement gui) { 158 _container.layout.removeChild(gui); 159 repositionContainer(); 160 } 161 }