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 }