1 /** 2 Grimoire 3 Copyright (c) 2017 Enalye 4 5 This software is provided 'as-is', without any express or implied warranty. 6 In no event will the authors be held liable for any damages arising 7 from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute 11 it freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; 14 you must not claim that you wrote the original software. 15 If you use this software in a product, an acknowledgment 16 in the product documentation would be appreciated but 17 is not required. 18 19 2. Altered source versions must be plainly marked as such, 20 and must not be misrepresented as being the original software. 21 22 3. This notice may not be removed or altered from any source distribution. 23 */ 24 25 module ui.list.dropdownlist; 26 27 import std.conv: to; 28 29 import core.all; 30 import render.all; 31 import common.all; 32 33 import ui.list.vlist; 34 import ui.widget; 35 import ui.overlay; 36 37 class DropDownList: WidgetGroup { 38 private { 39 VList _list; 40 Vec2f _originalSize, _originalPosition; 41 bool _isClicked = false; 42 uint _maxListLength = 5; 43 } 44 45 @property { 46 uint selected() const { return _list.selected; } 47 uint selected(uint id) { return _list.selected = id; } 48 } 49 50 this(Vec2f newSize, uint maxListLength = 5U) { 51 _maxListLength = maxListLength; 52 _originalSize = newSize; 53 _list = new VList(_originalSize * Vec2f(1f, _maxListLength)); 54 _size = _originalSize; 55 } 56 57 override void onEvent(Event event) { 58 super.onEvent(event); 59 if(!isLocked) { 60 if(event.type == EventType.MouseUp) { 61 _isClicked = !_isClicked; 62 63 if(_isClicked) { 64 setOverlay(this); 65 setOverlay(_list); 66 } 67 else { 68 stopOverlay(); 69 triggerCallback(); 70 } 71 } 72 } 73 if(_isClicked) 74 _list.onEvent(event); 75 } 76 77 override void onPosition() { 78 _originalPosition = _position; 79 } 80 81 override void update(float deltaTime) { 82 if(_isClicked) { 83 Vec2f newSize = _originalSize * Vec2f(1f, _maxListLength + 1f); 84 _list.position = _originalPosition + Vec2f(0f, newSize.y / 2f); 85 _list.update(deltaTime); 86 } 87 } 88 89 override void draw() { 90 super.draw(); 91 auto widgets = _list.getList(); 92 if(widgets.length > _list.selected) { 93 auto widget = widgets[_list.selected]; 94 auto wPos = widget.position; 95 auto wSize = widget.size; 96 97 widget.position = _originalPosition; 98 widget.size = _originalSize; 99 widget.draw(); 100 101 widget.position = wPos; 102 widget.size = wSize; 103 } 104 drawRect(_originalPosition - _originalSize / 2f, _originalSize, Color.white); 105 } 106 107 override void drawOverlay() { 108 super.drawOverlay(); 109 if(_isClicked) 110 _list.draw(); 111 } 112 113 override void addChild(Widget widget) { 114 _list.addChild(widget); 115 } 116 117 override void removeChildren() { 118 _list.removeChildren(); 119 } 120 121 override void removeChild(uint id) { 122 _list.removeChild(id); 123 } 124 125 override int getChildrenCount() { 126 return _list.getChildrenCount(); 127 } 128 129 Widget[] getList() { 130 return _list.getList(); 131 } 132 }