Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
GUIConsole.cpp
Go to the documentation of this file.
1
2
5#include "Headers/GUI.h"
7
11
13
14namespace Divide {
15
16namespace {
19};
20
23 , _parent(parent)
24 , _init(false)
25 , _closing(false)
26 , _lastMsgType(Console::EntryType::INFO)
27 , _editBox(nullptr)
28 , _outputWindow(nullptr)
29 , _cmdParser(std::make_unique<GUIConsoleCommandParser>(_context))
30 , _consoleWindow(nullptr)
31 , _inputHistoryIndex(0)
32 , _consoleCallbackIndex(0)
33{
35 {
37 });
38}
39
41{
43 {
45 }
46 _closing = true;
47
49 {
50 setVisible(false);
51 _init = false;
52 _parent.getCEGUIContext()->getRootWindow()->removeChild(_consoleWindow);
53 CEGUI::WindowManager::getSingletonPtr()->destroyWindow(_consoleWindow);
54 }
55}
56
58 if (_init) {
59 Console::errorfn(LOCALE_STR("ERROR_CONSOLE_DOUBLE_INIT"));
60 }
61 // load the console Window from the layout file
62 const string layoutFile(_context.config().gui.consoleLayoutFile);
63 _consoleWindow = CEGUI::WindowManager::getSingletonPtr()->loadLayoutFromFile(layoutFile.c_str());
64
65 if (_consoleWindow) {
66 // Add the Window to the GUI Root Sheet
67 _parent.getCEGUIContext()->getRootWindow()->addChild(_consoleWindow);
68 _outputWindow = static_cast<CEGUI::Listbox*>(_consoleWindow->getChild("ChatBox"));
69 _editBox = static_cast<CEGUI::Editbox*>(_consoleWindow->getChild("EditBox"));
70 // Now register the handlers for the events (Clicking, typing, etc)
72 } else {
73 // Loading layout from file, failed, so output an error Message.
74 CEGUI::Logger::getSingleton().logEvent(
75 "Error: Unable to load the ConsoleWindow from .layout");
76 Console::errorfn(LOCALE_STR("ERROR_CONSOLE_LAYOUT_FILE"),
77 layoutFile.c_str());
78 }
79
80 _consoleWindow->setVisible(false);
81 _init = true;
82 Console::printfn(LOCALE_STR("GUI_CONSOLE_CREATED"));
83}
84
86 assert(_editBox != nullptr);
87 // We need to monitor text/command submission from the editBox
88 _editBox->subscribeEvent(
89 CEGUI::Editbox::EventTextAccepted,
90 CEGUI::Event::Subscriber(&GUIConsole::Handle_TextSubmitted, this));
91 // we also monitor any key presses to make sure we do not accidentally hide
92 // the console in the middle of a sentence
93 _editBox->subscribeEvent(
94 CEGUI::Editbox::EventKeyUp,
95 CEGUI::Event::Subscriber(&GUIConsole::Handle_TextInput, this));
96}
97
98bool GUIConsole::Handle_TextInput(const CEGUI::EventArgs& e) {
99 assert(_editBox != nullptr);
100 const CEGUI::KeyEventArgs* keyEvent =
101 static_cast<const CEGUI::KeyEventArgs*>(&e);
102 // Just get the current text string from the editbox at each keypress.
103 // Performance isn't a issue for console commands
104 if (!_inputHistory.empty()) {
105 if (keyEvent->scancode == CEGUI::Key::ArrowUp) {
107 if (_inputHistoryIndex < 0)
110 }
111 if (keyEvent->scancode == CEGUI::Key::ArrowDown) {
113 if (_inputHistoryIndex >= (I32)_inputHistory.size())
116 }
117 }
118
119 _inputBuffer = _editBox->getText();
120 return true;
121}
122
123bool GUIConsole::Handle_TextSubmitted(const CEGUI::EventArgs& /*e*/) {
124 assert(_editBox != nullptr);
125 // Since we have that string, lets send it to the TextParser which will
126 // handle it from here
127 if (!_cmdParser->processCommand(_inputBuffer.c_str())) {
128 printText({"Failed to parse command!", Console::EntryType::ERR});
129 }
130 // Now that we've finished with the text, we need to ensure that we clear
131 // out the EditBox.
132 // This is what we would expect to happen after we press enter
133 _editBox->setText("");
134 _inputHistory.push_back(_inputBuffer);
135 // Keep command history low
136 if (_inputHistory.size() > CEGUI_MAX_CONSOLE_ENTRIES) {
137 _inputHistory.pop_front();
138 }
140 // reset the inputbuffer so we can handle console closing properly
141 _inputBuffer.clear();
142 return true;
143}
144
145void GUIConsole::setVisible(const bool visible) {
146 if (_init) {
147 // if it's not the first key (e.g., if the toggle key is "~", then
148 // "lorem~ipsum" should not close the Window)
149 if (!_inputBuffer.empty()) {
150 return;
151 }
152 assert(_editBox != nullptr);
153 _consoleWindow->setVisible(visible);
154
155 if (visible) {
156 _editBox->activate();
157 } else {
158 _editBox->deactivate();
159 _editBox->setText("");
160 }
161
162 printText(
163 {
164 visible ? "Toggling console display: ON"
165 : "Toggling console display: OFF",
167 }
168 );
169 const size_t count = _outputWindow->getItemCount();
170 if (count > 0 && visible) {
171 _outputWindow->ensureItemIsVisible(count - 1);
172 }
173 }
174}
175
177 if (!_init) {
178 return false;
179 }
180 return _consoleWindow->isVisible();
181}
182
184{
185 _outputBuffer.enqueue(entry);
186 if (_outputBuffer.size_approx() > CEGUI_MAX_CONSOLE_ENTRIES)
187 {
188 for (U16 i = 0u; i < CEGUI_MAX_CONSOLE_ENTRIES; ++i)
189 {
190 Console::OutputEntry message;
191 if (!_outputBuffer.try_dequeue(message))
192 {
193 break;
194 }
195 }
196 }
197}
198
200 if (_outputWindow->getItemCount() == CEGUI_MAX_CONSOLE_ENTRIES - 1) {
201 _outputWindow->removeItem(_outputWindow->getListboxItemFromIndex(0));
202 }
203
206 CEGUI::String(text._text.c_str()),
208 ? CEGUI::Colour(1.0f, 0.0f, 0.0f)
210 ? CEGUI::Colour(1.0f, 1.0f, 0.0f)
211 : CEGUI::Colour(0.4f, 0.4f, 0.3f),
212 CEGUI::HTF_WORDWRAP_LEFT_ALIGNED);
213
214 crtItem->setTextParsingEnabled(false);
215 _outputWindow->addItem(crtItem);
216 _outputWindow->ensureItemIsVisible(crtItem);
217}
218
219void GUIConsole::update(const U64 /*deltaTimeUS*/) {
220 if (!_init || !Runtime::isMainThread() || _closing) {
221 return;
222 }
223 if (!isVisible()) {
224 return;
225 }
226
227 {
228 Console::OutputEntry message;
229 while(_outputBuffer.try_dequeue(message)) {
230 const Console::EntryType type = message._type;
231 if (_lastMsgType != type) {
232 _lastMsgType = type;
233 OutputText(message);
234 _lastMsg.clear();
235 }
236
237 _lastMsg.append(message._text.c_str());
238 _lastMsg.append("\n");
239 }
240 }
241
242 if (!_lastMsg.empty()) {
244 {
245 _lastMsg.c_str(),
247 }
248 );
249 _lastMsg.clear();
250 }
251}
252
253} //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_UNEXPECTED_CALL()
! A ListboxItem based class that can do horizontal text formatting.
std::unique_ptr< GUIConsoleCommandParser > _cmdParser
pointer to the command parser instance used
Definition: GUIConsole.h:91
void RegisterHandlers()
Register our handler functions.
Definition: GUIConsole.cpp:85
bool Handle_TextSubmitted(const CEGUI::EventArgs &e)
Handle when we press Enter after typing.
Definition: GUIConsole.cpp:123
bool isVisible() const
Return true if console is visible, false if is hidden.
Definition: GUIConsole.cpp:176
CEGUI::Editbox * _editBox
pointer to the editBox to reduce typing and casting
Definition: GUIConsole.h:86
size_t _consoleCallbackIndex
Definition: GUIConsole.h:104
I16 _inputHistoryIndex
Used to cycle through history.
Definition: GUIConsole.h:100
void printText(const Console::OutputEntry &entry)
Add text to the console Window. Uses a text buffer if the console isn't ready for display yet.
Definition: GUIConsole.cpp:183
void createCEGUIWindow()
The function which will load in the CEGUI Window and register event handlers.
Definition: GUIConsole.cpp:57
CEGUI::String _lastMsg
Definition: GUIConsole.h:84
bool Handle_TextInput(const CEGUI::EventArgs &e)
A key is pressed in the console input editbox.
Definition: GUIConsole.cpp:98
GUIConsole(GUI &parent, PlatformContext &context)
Definition: GUIConsole.cpp:21
moodycamel::ConcurrentQueue< Console::OutputEntry > _outputBuffer
Definition: GUIConsole.h:102
Console::EntryType _lastMsgType
Definition: GUIConsole.h:83
~GUIConsole() override
Definition: GUIConsole.cpp:40
void setVisible(bool visible)
Hide or show the console.
Definition: GUIConsole.cpp:145
CEGUI::Listbox * _outputWindow
Definition: GUIConsole.h:89
std::deque< CEGUI::String > _inputHistory
Used to manage the input history.
Definition: GUIConsole.h:98
void update(U64 deltaTimeUS)
Definition: GUIConsole.cpp:219
CEGUI::Window * _consoleWindow
This will be a pointer to the ConsoleRoot Window.
Definition: GUIConsole.h:93
CEGUI::String _inputBuffer
Definition: GUIConsole.h:96
bool _init
used to check if the console is ready
Definition: GUIConsole.h:81
void OutputText(const Console::OutputEntry &text) const
Definition: GUIConsole.cpp:199
Graphical User Interface.
Definition: GUI.h:81
CEGUI::GUIContext * getCEGUIContext() noexcept
Provides direct access to the CEGUI context. Used by plugins (e.g. GUIConsole, GUIInput,...
Definition: GUI.cpp:862
Configuration & config() noexcept
constexpr bool IS_DEBUG_BUILD
Definition: config.h:55
bool isMainThread() noexcept
constexpr U32 CEGUI_MAX_CONSOLE_ENTRIES
Maximum number of lines to display in the console Window.
Definition: GUIConsole.cpp:18
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
int32_t I32
int16_t I16
Project & parent
Definition: DefaultScene.h:41
uint16_t U16
constexpr size_t to_size(const T value)
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
uint64_t U64
struct Divide::Configuration::GUI gui
Definition: Console.h:119
EntryType _type
Definition: Console.h:121
string _text
Definition: Console.h:120
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
static bool UnbindConsoleOutput(size_t &index)
Definition: Console.cpp:206
static size_t BindConsoleOutput(const ConsolePrintCallback &guiConsoleCallback)
Definition: Console.cpp:194