Mercurial > fife-parpg
comparison engine/core/gui/console/console.cpp @ 697:ecaa4d98f05f tip
Abstracted the GUI code and refactored the GUIChan-specific code into its own module.
* Most of the GUIChan code has been refactored into its own gui/guichan module. However, references to the GuiFont class still persist in the Engine and GuiManager code and these will need further refactoring.
* GuiManager is now an abstract base class which specific implementations (e.g. GUIChan) should subclass.
* The GUIChan GUI code is now a concrete implementation of GuiManager, most of which is in the new GuiChanGuiManager class.
* The GUI code in the Console class has been refactored out of the Console and into the GUIChan module as its own GuiChanConsoleWidget class. The rest of the Console class related to executing commands was left largely unchanged.
* Existing client code may need to downcast the GuiManager pointer received from FIFE::Engine::getGuiManager() to GuiChanGuiManager, since not all functionality is represented in the GuiManager abstract base class. Python client code can use the new GuiChanGuiManager.castTo static method for this purpose.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Sat, 18 Jun 2011 00:28:40 -1000 |
parents | e201abd8c807 |
children |
comparison
equal
deleted
inserted
replaced
696:e201abd8c807 | 697:ecaa4d98f05f |
---|---|
1 /*************************************************************************** | |
2 * Copyright (C) 2005-2008 by the FIFE team * | |
3 * http://www.fifengine.de * | |
4 * This file is part of FIFE. * | |
5 * * | |
6 * FIFE is free software; you can redistribute it and/or * | |
7 * modify it under the terms of the GNU Lesser General Public * | |
8 * License as published by the Free Software Foundation; either * | |
9 * version 2.1 of the License, or (at your option) any later version. * | |
10 * * | |
11 * This library is distributed in the hope that it will be useful, * | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * | |
14 * Lesser General Public License for more details. * | |
15 * * | |
16 * You should have received a copy of the GNU Lesser General Public * | |
17 * License along with this library; if not, write to the * | |
18 * Free Software Foundation, Inc., * | |
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * | |
20 ***************************************************************************/ | |
21 | |
22 // Standard C++ library includes | |
23 #include <cassert> | |
24 | |
25 // 3rd party library includes | |
26 #include <boost/bind.hpp> | |
27 #include <boost/lexical_cast.hpp> | |
28 #include <boost/regex.hpp> | |
29 #include <boost/tokenizer.hpp> | |
30 | |
31 // FIFE includes | |
32 // These includes are split up in two parts, separated by one empty line | |
33 // First block: files included from the FIFE root src directory | |
34 // Second block: files included from the same folder | |
35 #include "video/renderbackend.h" | |
36 #include "util/time/timemanager.h" | |
37 #include "util/log/logger.h" | |
38 #include "util/base/exception.h" | |
39 #include "gui/guimanager.h" | |
40 #include "gui/base/gui_font.h" | |
41 #include "gui/widgets/utf8textbox.h" | |
42 | |
43 #include "commandline.h" | |
44 #include "console.h" | |
45 | |
46 namespace FIFE { | |
47 const unsigned Console::m_maxOutputRows = 50; | |
48 static Logger _log(LM_CONSOLE); | |
49 | |
50 Console::Console() | |
51 : gcn::Container(), | |
52 m_consoleexec(0), | |
53 m_input(new CommandLine()), | |
54 m_output(new gcn::UTF8TextBox()), | |
55 m_outputscrollarea(new gcn::ScrollArea(m_output)), | |
56 m_status(new gcn::Label()), | |
57 m_toolsbutton(new gcn::Button("Tools")) | |
58 { | |
59 reLayout(); | |
60 | |
61 add(m_outputscrollarea); | |
62 add(m_input); | |
63 add(m_status); | |
64 add(m_toolsbutton); | |
65 | |
66 setOpaque(true); | |
67 | |
68 m_input->setCallback( std::bind1st( std::mem_fun(&Console::execute), this) ); | |
69 m_prompt = "-- "; | |
70 | |
71 m_isAttached = false; | |
72 | |
73 m_fpsTimer.setInterval(500); | |
74 m_fpsTimer.setCallback( boost::bind(&Console::updateCaption, this) ); | |
75 | |
76 m_hiding = true; | |
77 | |
78 m_animationTimer.setInterval(20); | |
79 m_animationTimer.setCallback( boost::bind(&Console::updateAnimation, this) ); | |
80 | |
81 m_toolsbutton->addActionListener(this); | |
82 m_toolsbutton->setFocusable(false); | |
83 m_input->addFocusListener(this); | |
84 | |
85 GuiFont* font = GUIManager::instance()->createFont(); | |
86 font->setColor(255,255,255); | |
87 setIOFont(font); | |
88 } | |
89 | |
90 void Console::reLayout() { | |
91 Image* screen = RenderBackend::instance()->getScreenImage(); | |
92 assert(screen); | |
93 | |
94 int w, h, b, input_h, bbar_h, button_w; | |
95 w = screen->getWidth() * 4/5; | |
96 h = screen->getHeight() * 4/5; | |
97 b = 0; | |
98 input_h = getFont()->getHeight(); | |
99 bbar_h = input_h; | |
100 button_w = 80; | |
101 | |
102 gcn::Color black(0x00,0,0,0xff); | |
103 gcn::Color white(0xff,0xff,0xff,0xff); | |
104 gcn::Color dark(50,60,50,0xff); | |
105 | |
106 setSize(w, h); | |
107 setPosition((screen->getWidth() - w) / 2,-h); | |
108 setFrameSize(0); | |
109 | |
110 setForegroundColor(white); | |
111 setBackgroundColor(black); | |
112 setBaseColor(dark); | |
113 | |
114 setSize(w, h); | |
115 | |
116 m_outputscrollarea->setSize(w - 2*b, h - input_h - 3*b - bbar_h); | |
117 m_outputscrollarea->setPosition(b,0); | |
118 | |
119 m_input->setPosition(b, h - input_h - b - bbar_h); | |
120 m_input->setSize(w - 2*b, input_h); | |
121 | |
122 m_status->setPosition(b, h - b - bbar_h); | |
123 m_status->setSize(w - 2*b, bbar_h); | |
124 | |
125 m_toolsbutton->setPosition(w - button_w, h - b - bbar_h); | |
126 m_toolsbutton->setSize(button_w, bbar_h); | |
127 | |
128 m_output->setBackgroundColor(black); | |
129 m_output->setFocusable(false); | |
130 | |
131 m_outputscrollarea->setBackgroundColor(black); | |
132 m_outputscrollarea->setBaseColor(dark); | |
133 | |
134 m_input->setForegroundColor(white); | |
135 m_input->setBackgroundColor(black); | |
136 | |
137 m_status->setForegroundColor(white); | |
138 m_status->setBackgroundColor(black); | |
139 | |
140 m_toolsbutton->setForegroundColor(white); | |
141 m_toolsbutton->setBackgroundColor(black); | |
142 m_toolsbutton->setBaseColor(dark); | |
143 | |
144 m_hiddenPos = -h; | |
145 m_animationDelta = h/6; | |
146 } | |
147 | |
148 Console::~Console() { | |
149 doHide(); | |
150 | |
151 remove(m_input); | |
152 remove(m_outputscrollarea); | |
153 remove(m_status); | |
154 | |
155 delete m_output; | |
156 delete m_input; | |
157 delete m_outputscrollarea; | |
158 delete m_status; | |
159 delete m_toolsbutton; | |
160 } | |
161 | |
162 void Console::updateCaption() { | |
163 std::string caption = "FIFE Console - FPS: "; | |
164 float fps = 1e3/double(TimeManager::instance()->getAverageFrameTime()); | |
165 caption += boost::lexical_cast<std::string>(fps); | |
166 m_status->setCaption( caption ); | |
167 } | |
168 | |
169 void Console::updateAnimation() { | |
170 if (m_hiding){ | |
171 setPosition(getX(), getY() - m_animationDelta); | |
172 if (getY() <= m_hiddenPos){ | |
173 doHide(); | |
174 m_animationTimer.stop(); | |
175 } | |
176 }else{ | |
177 setPosition(getX(), getY() + m_animationDelta); | |
178 if (getY() >= 0){ | |
179 setPosition(getX(), 0); | |
180 m_animationTimer.stop(); | |
181 } | |
182 } | |
183 } | |
184 | |
185 void Console::clear() { | |
186 m_output->setText(""); | |
187 } | |
188 | |
189 void Console::doShow() { | |
190 if (m_isAttached) | |
191 return; | |
192 m_isAttached = true; | |
193 GUIManager::instance()->add(this); | |
194 GUIManager::instance()->getTopContainer()->moveToTop(this); | |
195 // Assure the input field is focused when shown. | |
196 m_input->requestFocus(); | |
197 | |
198 m_fpsTimer.start(); | |
199 } | |
200 | |
201 void Console::doHide() { | |
202 if (!m_isAttached) | |
203 return; | |
204 m_isAttached = false; | |
205 GUIManager::instance()->remove(this); | |
206 m_fpsTimer.stop(); | |
207 } | |
208 | |
209 void Console::show() { | |
210 if(m_hiding) { | |
211 m_hiding = false; | |
212 doShow(); | |
213 m_animationTimer.start(); | |
214 } | |
215 } | |
216 | |
217 void Console::hide() { | |
218 if(!m_hiding) { | |
219 m_hiding = true; | |
220 m_animationTimer.start(); | |
221 } | |
222 } | |
223 | |
224 void Console::toggleShowHide() { | |
225 m_hiding = !m_hiding; | |
226 if(!m_hiding) | |
227 doShow(); | |
228 m_animationTimer.start(); | |
229 } | |
230 | |
231 void Console::execute(std::string cmd) { | |
232 FL_DBG(_log, LMsg("in execute with command ") << cmd); | |
233 if (cmd.empty()) | |
234 return; | |
235 | |
236 // copy input to output | |
237 println(m_prompt + cmd); | |
238 | |
239 // run the command | |
240 try { | |
241 if (m_consoleexec) { | |
242 std::string resp = m_consoleexec->onConsoleCommand(cmd); | |
243 println(resp); | |
244 } else { | |
245 FL_WARN(_log, LMsg("ConsoleExecuter not bind, but command received: ") << cmd.c_str()); | |
246 } | |
247 } | |
248 catch (const FIFE::Exception & e) { | |
249 FL_WARN(_log, LMsg("Console caught exception: ") << e.what()); | |
250 println(e.what()); | |
251 } | |
252 } | |
253 | |
254 void Console::println(const std::string & s) { | |
255 assert(m_output); | |
256 | |
257 // Add the text in rows | |
258 boost::char_separator<char> separator("\n"); | |
259 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | |
260 tokenizer tokens(s,separator); | |
261 for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i) { | |
262 m_output->addRow(*i); | |
263 } | |
264 | |
265 // Assure the maximum number of rows | |
266 if( m_output->getNumberOfRows() > m_maxOutputRows ) { | |
267 unsigned rows = m_output->getNumberOfRows(); | |
268 int delta_rows = rows - m_maxOutputRows; | |
269 std::vector<std::string> rows_text; | |
270 for(size_t i=delta_rows; i != rows; ++i) { | |
271 rows_text.push_back(m_output->getTextRow(i)); | |
272 } | |
273 m_output->setText(""); | |
274 for(size_t i=0; i != rows_text.size(); ++i) { | |
275 m_output->addRow(rows_text[i]); | |
276 } | |
277 } | |
278 | |
279 // Assure the new text is visible | |
280 gcn::Rectangle rect(0,m_output->getHeight(),0,0); | |
281 m_outputscrollarea->showWidgetPart(m_output,rect); | |
282 } | |
283 | |
284 void Console::action(const gcn::ActionEvent & event) { | |
285 if (m_consoleexec) { | |
286 m_consoleexec->onToolsClick(); | |
287 } else { | |
288 FL_WARN(_log, "ConsoleExecuter not bind, but tools button clicked"); | |
289 } | |
290 } | |
291 | |
292 void Console::setConsoleExecuter(ConsoleExecuter* const consoleexec) { | |
293 m_consoleexec = consoleexec; | |
294 } | |
295 | |
296 void Console::removeConsoleExecuter() { | |
297 m_consoleexec = NULL; | |
298 } | |
299 | |
300 void Console::setIOFont(GuiFont* font) { | |
301 m_input->setFont(font); | |
302 m_output->setFont(font); | |
303 } | |
304 | |
305 void Console::focusLost(const gcn::Event& ) { | |
306 hide(); | |
307 } | |
308 } | |
309 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */ |