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.modal;
26 
27 import core.all;
28 import render.all;
29 import common.all;
30 
31 import ui.widget;
32 import ui.layout;
33 import ui.label;
34 import ui.button;
35 import ui.panel;
36 
37 private {
38 	Widget[] _widgetsBackup;
39 	ModalWindow _modal;
40 //	string _modalName;
41 	bool _isModal = false;
42 }
43 
44 void setModalWindow(ModalWindow newModal) {
45 	if(_isModal)
46 		throw new Exception("Modal window already set");
47 	_isModal = true;
48 	//_modalName = newModalName;
49 	_widgetsBackup = getWidgets();
50 	removeWidgets();
51 	_modal = newModal;
52 	addWidget(_modal);
53 	/+Event event = EventType.ModalOpen;
54 	event.id = _modalName;
55 	event.widget = _modal;
56 	sendEvent(event);+/
57 }
58 
59 bool isModal() {
60 	return _isModal;
61 }
62 
63 T getModal(T)() {
64 	if(_modal is null)
65 		throw new Exception("Modal: No window instanciated");
66 	T convModal = cast(T)_modal;
67 	if(convModal is null)
68 		throw new Exception("Modal: Type error");
69 	return convModal;
70 }
71 
72 private void onModalClose() {
73 	removeWidgets();
74 	if(_modal is null)
75 		throw new Exception("Modal: No window instanciated");
76 	setWidgets(_widgetsBackup);
77 	_widgetsBackup.length = 0L;
78 	_isModal = false;
79 }
80 
81 class ModalWindow: WidgetGroup {
82 	AnchoredLayout layout;
83 	TextButton cancelBtn, applyBtn;
84 
85 	private {
86 		Panel _panel;
87 		HLayout _lowerBox;
88 		Label _titleLabel;
89 		ImgButton _exitBtn;
90 	}
91 
92 	this(string newTitle, Vec2f newSize) {
93 		_size = newSize + Vec2f(22f, 116f);
94 		_isMovable = true;
95 		_isFrame = false;
96 		position = centerScreen;
97 
98 		_titleLabel = new Label(newTitle);
99 		_titleLabel.color = Color.white * 0.21;
100 		_panel = new Panel;
101 		_panel.position = _position;
102 		layout = new AnchoredLayout;
103 		layout.position = _position;
104 
105 		_exitBtn = new ImgButton;
106 		_exitBtn.idleSprite = fetch!Sprite("gui_window_exit");
107 		_exitBtn.onClick = {
108 			{
109 				Event event;
110 				event.type = EventType.Callback;
111 				event.id = "exit";
112 				_modal.onEvent(event);
113 			}
114 			onModalClose();
115 			/+Event event = EventType.ModalCancel;
116 			event.id = _modalName;
117 			event.widget = _modal;
118 			_modal.onEvent(event);
119 			sendEvent(event);
120 			event.type = EventType.ModalClose;
121 			_modal.onEvent(event);
122 			sendEvent(event);+/
123 		};
124 
125 		{ //Confirmation buttons
126 			_lowerBox = new HLayout;
127 			_lowerBox.isLocked = true;
128 			_lowerBox.spacing = Vec2f(10f, 15f);
129 
130 			cancelBtn = new TextButton("Annuler");
131 			applyBtn = new TextButton("Valider");
132 			cancelBtn.onClick = {
133 				{
134 					Event event;
135 					event.type = EventType.Callback;
136 					event.id = "cancel";
137 					_modal.onEvent(event);
138 				}
139 				onModalClose();
140 				/+Event event = EventType.ModalCancel;
141 				event.id = _modalName;
142 				event.widget = _modal;
143 				_modal.onEvent(event);
144 				sendEvent(event);
145 				event.type = EventType.ModalClose;
146 				_modal.onEvent(event);
147 				sendEvent(event);+/
148 			};
149 			applyBtn.onClick = {
150 				{
151 					Event event;
152 					event.type = EventType.Callback;
153 					event.id = "apply";
154 					_modal.onEvent(event);
155 				}
156 				onModalClose();
157 				/+Event event = EventType.ModalApply;
158 				event.id = _modalName;
159 				event.widget = _modal;
160 				_modal.onEvent(event);
161 				sendEvent(event);
162 				event.type = EventType.ModalClose;
163 				_modal.onEvent(event);
164 				sendEvent(event);+/
165 			};
166 
167 			addChild(_lowerBox);
168 			_lowerBox.addChild(cancelBtn);
169 			_lowerBox.addChild(applyBtn);
170 		}
171 
172 		addChild(_titleLabel);
173 		addChild(layout);
174 		addChild(_exitBtn);
175 		addChild(_panel);
176 		resize();
177 	}
178 
179 	override void update(float deltaTime) {
180 		layout.position = _position;
181 		//Update suspended widgets
182 		foreach(child; _widgetsBackup)
183 			child.update(deltaTime);
184 		super.update(deltaTime);
185 	}
186 
187 	override void draw() {
188 		//Render suspended widgets in background
189 		foreach(child; _widgetsBackup)
190 			child.draw();
191 		super.draw();
192 	}
193 
194     override void onSize() {
195         _size += Vec2f(22f, 116f);
196         resize();
197     }
198 
199 	protected void resize() {
200 		_exitBtn.position = _position + Vec2f((_size.x - _exitBtn.size.x), (-_size.y + _exitBtn.size.y)) / 2f;
201 		_lowerBox.size = Vec2f(_size.x - 25f, 40f);
202 		_lowerBox.position = _position + Vec2f(0f, _size.y / 2f - 30f);
203 		_panel.size = _size;
204 		layout.position = _position - Vec2f(8f, 0f);
205 		layout.size = Vec2f(_size.x - 22f, _size.y - 116f);
206 		_titleLabel.position = Vec2f(_position.x, _position.y - _size.y / 2f + 25f);
207 	}
208 }