FIFE  2008.0
console.cpp
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/guichan/guichanmanager.h"
40 #include "gui/guichan/base/gui_font.h"
41 #include "gui/guichan/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 
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 = GUIChanManager::instance()->createFont();
86  font->setColor(255,255,255);
87  setIOFont(font);
88  }
89 
91  int32_t w, h, b, input_h, bbar_h, button_w;
92  w = RenderBackend::instance()->getScreenWidth() * 4/5;
93  h = RenderBackend::instance()->getScreenHeight() * 4/5;
94  b = 0;
95  input_h = getFont()->getHeight();
96  bbar_h = input_h;
97  button_w = 80;
98 
99  gcn::Color black(0x00,0,0,0xff);
100  gcn::Color white(0xff,0xff,0xff,0xff);
101  gcn::Color dark(50,60,50,0xff);
102 
103  setSize(w, h);
104  setPosition((RenderBackend::instance()->getScreenWidth() - w) / 2,-h);
105  setFrameSize(0);
106 
107  setForegroundColor(white);
108  setBackgroundColor(black);
109  setBaseColor(dark);
110 
111  setSize(w, h);
112 
113  m_outputscrollarea->setSize(w - 2*b, h - input_h - 3*b - bbar_h);
114  m_outputscrollarea->setPosition(b,0);
115 
116  m_input->setPosition(b, h - input_h - b - bbar_h);
117  m_input->setSize(w - 2*b, input_h);
118 
119  m_status->setPosition(b, h - b - bbar_h);
120  m_status->setSize(w - 2*b, bbar_h);
121 
122  m_toolsbutton->setPosition(w - button_w, h - b - bbar_h);
123  m_toolsbutton->setSize(button_w, bbar_h);
124 
125  m_output->setBackgroundColor(black);
126  m_output->setFocusable(false);
127 
128  m_outputscrollarea->setBackgroundColor(black);
129  m_outputscrollarea->setBaseColor(dark);
130 
131  m_input->setForegroundColor(white);
132  m_input->setBackgroundColor(black);
133 
134  m_status->setForegroundColor(white);
135  m_status->setBackgroundColor(black);
136 
137  m_toolsbutton->setForegroundColor(white);
138  m_toolsbutton->setBackgroundColor(black);
139  m_toolsbutton->setBaseColor(dark);
140 
141  m_hiddenPos = -h;
142  m_animationDelta = h/6;
143  }
144 
146  doHide();
147 
148  remove(m_input);
149  remove(m_outputscrollarea);
150  remove(m_status);
151 
152  delete m_output;
153  delete m_input;
154  delete m_outputscrollarea;
155  delete m_status;
156  delete m_toolsbutton;
157  }
158 
160  std::string caption = "FIFE Console - FPS: ";
161  double fps = 1e3/TimeManager::instance()->getAverageFrameTime();
162  caption += boost::lexical_cast<std::string>(fps);
163  m_status->setCaption( caption );
164  }
165 
167  if (m_hiding){
168  setPosition(getX(), getY() - m_animationDelta);
169  if (getY() <= m_hiddenPos){
170  doHide();
171  m_animationTimer.stop();
172  }
173  }else{
174  setPosition(getX(), getY() + m_animationDelta);
175  if (getY() >= 0){
176  setPosition(getX(), 0);
177  m_animationTimer.stop();
178  }
179  }
180  }
181 
182  void Console::clear() {
183  m_output->setText("");
184  }
185 
186  void Console::doShow() {
187  if (m_isAttached)
188  return;
189  m_isAttached = true;
190  GUIChanManager::instance()->add(this);
191  GUIChanManager::instance()->getTopContainer()->moveToTop(this);
192  // Assure the input field is focused when shown.
193  m_input->requestFocus();
194 
195  m_fpsTimer.start();
196  }
197 
198  void Console::doHide() {
199  if (!m_isAttached)
200  return;
201  m_isAttached = false;
202  GUIChanManager::instance()->remove(this);
203  m_fpsTimer.stop();
204  }
205 
206  void Console::show() {
207  if(m_hiding) {
208  m_hiding = false;
209  doShow();
210  m_animationTimer.start();
211  }
212  }
213 
214  void Console::hide() {
215  if(!m_hiding) {
216  m_hiding = true;
217  m_animationTimer.start();
218  }
219  }
220 
222  m_hiding = !m_hiding;
223  if(!m_hiding)
224  doShow();
225  m_animationTimer.start();
226  }
227 
228  void Console::execute(std::string cmd) {
229  FL_DBG(_log, LMsg("in execute with command ") << cmd);
230  if (cmd.empty())
231  return;
232 
233  // copy input to output
234  println(m_prompt + cmd);
235 
236  // run the command
237  try {
238  if (m_consoleexec) {
239  std::string resp = m_consoleexec->onConsoleCommand(cmd);
240  println(resp);
241  } else {
242  FL_WARN(_log, LMsg("ConsoleExecuter not bind, but command received: ") << cmd.c_str());
243  }
244  }
245  catch (const FIFE::Exception & e) {
246  FL_WARN(_log, LMsg("Console caught exception: ") << e.what());
247  println(e.what());
248  }
249  }
250 
251  void Console::println(const std::string & s) {
252  assert(m_output);
253 
254  // Add the text in rows
255  boost::char_separator<char> separator("\n");
256  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
257  tokenizer tokens(s,separator);
258  for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i) {
259  m_output->addRow(*i);
260  }
261 
262  // Assure the maximum number of rows
263  if( m_output->getNumberOfRows() > m_maxOutputRows ) {
264  unsigned rows = m_output->getNumberOfRows();
265  int32_t delta_rows = rows - m_maxOutputRows;
266  std::vector<std::string> rows_text;
267  for(size_t i=delta_rows; i != rows; ++i) {
268  rows_text.push_back(m_output->getTextRow(i));
269  }
270  m_output->setText("");
271  for(size_t i=0; i != rows_text.size(); ++i) {
272  m_output->addRow(rows_text[i]);
273  }
274  }
275 
276  // Assure the new text is visible
277  gcn::Rectangle rect(0,m_output->getHeight(),0,0);
278  m_outputscrollarea->showWidgetPart(m_output,rect);
279  }
280 
281  void Console::action(const gcn::ActionEvent & event) {
282  if (m_consoleexec) {
283  m_consoleexec->onToolsClick();
284  } else {
285  FL_WARN(_log, "ConsoleExecuter not bind, but tools button clicked");
286  }
287  }
288 
289  void Console::setConsoleExecuter(ConsoleExecuter* const consoleexec) {
290  m_consoleexec = consoleexec;
291  }
292 
294  m_consoleexec = NULL;
295  }
296 
297  void Console::setIOFont(GuiFont* font) {
298  m_input->setFont(font);
299  m_output->setFont(font);
300  }
301 
302  void Console::focusLost(const gcn::Event& ) {
303  hide();
304  }
305 }
306 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
virtual void onToolsClick()=0
virtual const char * what() const
Definition: exception.cpp:41
void setConsoleExecuter(ConsoleExecuter *const consoleexec)
Definition: console.cpp:289
virtual std::string onConsoleCommand(const std::string &command)=0
void execute(std::string cmd)
Definition: console.cpp:228
void hide()
Definition: console.cpp:214
void setCallback(const type_callback &cb)
void updateAnimation()
Definition: console.cpp:166
void setIOFont(GuiFont *font)
Definition: console.cpp:297
void removeConsoleExecuter()
Definition: console.cpp:293
void focusLost(const gcn::Event &event)
Definition: console.cpp:302
void println(const std::string &s)
Definition: console.cpp:251
void show()
Definition: console.cpp:206
void toggleShowHide()
Definition: console.cpp:221
virtual ~Console()
Definition: console.cpp:145
void updateCaption()
Definition: console.cpp:159
void reLayout()
Definition: console.cpp:90
void action(const gcn::ActionEvent &event)
Definition: console.cpp:281
credit to phoku for his NodeDisplay example which the visitor code is adapted from ( he coded the qua...
Definition: soundclip.cpp:39
void clear()
Definition: console.cpp:182