1 /** 2 Console 3 4 Copyright: (c) Enalye 2017 5 License: Zlib 6 Authors: Enalye 7 */ 8 9 module atelier.ui.console.console; 10 11 import atelier.common, atelier.core, atelier.render; 12 import atelier.ui.list, atelier.ui.gui_element, atelier.ui.layout, atelier.ui.inputfield; 13 import atelier.ui.gui_overlay, atelier.ui.text, atelier.ui.gui_manager; 14 /* 15 private { 16 Console _console; 17 ConsoleHandler _consoleHandler; 18 19 alias FunctionCallback = void function(string[]); 20 } 21 22 void setupConsole(string invokeKey) { 23 _consoleHandler = new ConsoleHandler(invokeKey); 24 _console = new Console; 25 addRootGui(_consoleHandler); 26 } 27 28 void addConsoleCmd(string cmd, GuiElementCallback callback) { 29 if(!_console) 30 return; 31 _console.addCmd(cmd, callback); 32 } 33 34 void addConsoleCmd(string cmd, FunctionCallback callback) { 35 if(!_console) 36 return; 37 _console.addCmd(cmd, callback); 38 } 39 40 void removeConsoleCmd(string cmd) { 41 if(!_console) 42 return; 43 _console.removeCmd(cmd); 44 } 45 46 void logConsole(string log) { 47 if(!_console) 48 return; 49 _console.addMessage(log); 50 } 51 52 private class ConsoleHandler: GuiElement { 53 private { 54 bool _isToggled = false; 55 string _invokeKey; 56 Timer _timer; 57 } 58 59 this(string invokeKey) { 60 _invokeKey = invokeKey; 61 } 62 63 override void onEvent(Event event) {} 64 65 override void update(float deltaTime) { 66 if(_invokeKey.length && getKeyDown(_invokeKey)) 67 toggleConsole(); 68 69 if(_timer.isRunning) { 70 _timer.update(deltaTime); 71 _console.position = lerp( 72 Vec2f(_console.size.x /2f, -_console.size.y / 2f), 73 _console.size / 2f, 74 easeInOutSine(_timer.value01)); 75 76 if(!_timer.isRunning && !_isToggled) 77 stopOverlay(); 78 } 79 } 80 81 override void draw() {} 82 83 void toggleConsole() { 84 _isToggled = !_isToggled; 85 if(_isToggled) { 86 _console.setup(); 87 if(!_timer.isRunning) { 88 setOverlay(_console); 89 _timer.start(.25f); 90 } 91 else 92 _timer.isReversed = false; 93 } 94 else { 95 if(!_timer.isRunning) 96 _timer.startReverse(.25f); 97 else 98 _timer.isReversed = true; 99 } 100 } 101 } 102 103 private class Console: AnchoredLayout { 104 private { 105 LogList _log; 106 InputField _inputField; 107 GuiElementCallback[string] _widgetCallbacks; 108 FunctionCallback[string] _functionCallbacks; 109 Sprite _background; 110 } 111 112 this() { 113 size = Vec2f(screenWidth, screenHeight / 2f); 114 115 float inputFieldRatio = 25f / size.y; 116 float inputFieldHeight = size.y * inputFieldRatio; 117 118 _inputField = new InputField(Vec2f(size.x, inputFieldHeight)); 119 _log = new LogList(size - Vec2f(0f, inputFieldHeight)); 120 121 _background = fetch!Sprite("gui_texel"); 122 _background.size = size; 123 124 addChildGui(_log, Vec2f(.5f, .5f - inputFieldRatio / 2f), Vec2f(1f, 1f - inputFieldRatio)); 125 addChildGui(_inputField, Vec2f(.5f, 1f - inputFieldRatio / 2f), Vec2f(1f, inputFieldRatio)); 126 } 127 128 override void onEvent(Event event) { 129 super.onEvent(event); 130 131 switch(event.type) with(EventType) { 132 case keyEnter: 133 if(_inputField.hasFocus) { 134 string text = _inputField.text; 135 if(text.length) { 136 parse(text); 137 _inputField.clear(); 138 } 139 } 140 break; 141 default: 142 break; 143 } 144 } 145 146 override void draw() { 147 _background.texture.setColorMod(Color.black * .25f); 148 _background.draw(center); 149 super.draw(); 150 } 151 152 void setup() { 153 _inputField.hasFocus = true; 154 } 155 156 void addCmd(string cmd, GuiElementCallback callback) { 157 _widgetCallbacks[cmd] = callback; 158 } 159 160 void addCmd(string cmd, FunctionCallback callback) { 161 _functionCallbacks[cmd] = callback; 162 } 163 164 void removeCmd(string cmd) { 165 _widgetCallbacks.remove(cmd); 166 _functionCallbacks.remove(cmd); 167 } 168 169 void addMessage(string message) { 170 //The bold tag is temporary since the font in LogList is not properly rendered. 171 _log.addChildGui(new Text("{b}" ~ message)); 172 } 173 174 protected void parse(string text) { 175 import std.array: split; 176 auto parameters = text.split; 177 if(!parameters.length) 178 return; 179 auto widgetCallback = parameters[0] in _widgetCallbacks; 180 if(widgetCallback) { 181 Event event; 182 event.type = EventType.callback; 183 event.id = (*widgetCallback).id; 184 event.sarray = parameters[1..$]; 185 (*widgetCallback).widget.onEvent(event); 186 return; 187 } 188 auto functionCallback = parameters[0] in _functionCallbacks; 189 if(functionCallback) { 190 (*functionCallback)(parameters[1..$]); 191 return; 192 } 193 addMessage("Invalid command \'" ~ parameters[0] ~ "\'."); 194 } 195 }*/