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 }