FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
console.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2017 by the FIFE team *
3  * http://www.fifengine.net *
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/tokenizer.hpp>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #include "video/renderbackend.h"
35 #include "util/time/timemanager.h"
36 #include "util/log/logger.h"
37 #include "util/base/exception.h"
40 
41 #include "commandline.h"
42 #include "console.h"
43 
44 namespace FIFE {
45  const unsigned Console::m_maxOutputRows = 50;
46  static Logger _log(LM_CONSOLE);
47 
49  : fcn::Container(),
50  m_consoleexec(0),
51  m_input(new CommandLine()),
52  m_output(new fcn::TextBox()),
53  m_outputscrollarea(new fcn::ScrollArea(m_output)),
54  m_status(new fcn::Label()),
55  m_toolsbutton(new fcn::Button("Tools"))
56  {
57  reLayout();
58 
59  add(m_outputscrollarea);
60  add(m_input);
61  add(m_status);
62  add(m_toolsbutton);
63 
64  setOpaque(true);
65 
66  m_input->setCallback( std::bind1st( std::mem_fun(&Console::execute), this) );
67  m_prompt = "-- ";
68 
69  m_isAttached = false;
70 
72  m_fpsTimer.setCallback( boost::bind(&Console::updateCaption, this) );
73 
74  m_hiding = true;
75 
78 
79  m_toolsbutton->addActionListener(this);
80  m_toolsbutton->setFocusable(false);
81  m_input->addFocusListener(this);
82 
84  font->setColor(255,255,255);
85  setIOFont(font);
86  }
87 
89  int32_t w, h, b, input_h, bbar_h, button_w;
92  b = 0;
93  input_h = getFont()->getHeight();
94  bbar_h = input_h;
95  button_w = 80;
96 
97  fcn::Color black(0x00,0,0,0xff);
98  fcn::Color white(0xff,0xff,0xff,0xff);
99  fcn::Color dark(50,60,50,0xff);
100 
101  setSize(w, h);
102  setPosition((RenderBackend::instance()->getScreenWidth() - w) / 2,-h);
103  setBorderSize(0);
104 
105  setForegroundColor(white);
106  setBackgroundColor(black);
107  setBaseColor(dark);
108 
109  setSize(w, h);
110 
111  m_outputscrollarea->setSize(w - 2*b, h - input_h - 3*b - bbar_h);
112  m_outputscrollarea->setPosition(b,0);
113 
114  m_input->setPosition(b, h - input_h - b - bbar_h);
115  m_input->setSize(w - 2*b, input_h);
116 
117  m_status->setPosition(b, h - b - bbar_h);
118  m_status->setSize(w - 2*b, bbar_h);
119 
120  m_toolsbutton->setPosition(w - button_w, h - b - bbar_h);
121  m_toolsbutton->setSize(button_w, bbar_h);
122 
123  m_output->setBackgroundColor(black);
124  m_output->setFocusable(false);
125 
126  m_outputscrollarea->setBackgroundColor(black);
127  m_outputscrollarea->setBaseColor(dark);
128 
129  m_input->setForegroundColor(white);
130  m_input->setBackgroundColor(black);
131 
132  m_status->setForegroundColor(white);
133  m_status->setBackgroundColor(black);
134 
135  m_toolsbutton->setForegroundColor(white);
136  m_toolsbutton->setBackgroundColor(black);
137  m_toolsbutton->setBaseColor(dark);
138 
139  m_hiddenPos = -h;
140  m_animationDelta = h/6;
141  }
142 
144  doHide();
145 
146  remove(m_input);
147  remove(m_outputscrollarea);
148  remove(m_status);
149 
150  delete m_output;
151  delete m_input;
152  delete m_outputscrollarea;
153  delete m_status;
154  delete m_toolsbutton;
155  }
156 
158  std::string caption = "FIFE Console - FPS: ";
159  double fps = 1e3/TimeManager::instance()->getAverageFrameTime();
160  caption += boost::lexical_cast<std::string>(fps);
161  m_status->setCaption( caption );
162  }
163 
165  if (m_hiding){
166  setPosition(getX(), getY() - m_animationDelta);
167  if (getY() <= m_hiddenPos){
168  doHide();
170  }
171  }else{
172  setPosition(getX(), getY() + m_animationDelta);
173  if (getY() >= 0){
174  setPosition(getX(), 0);
176  }
177  }
178  }
179 
180  void Console::clear() {
181  m_output->setText("");
182  }
183 
185  if (m_isAttached)
186  return;
187  m_isAttached = true;
189  FifechanManager::instance()->getTopContainer()->moveToTop(this);
190  // Assure the input field is focused when shown.
191  m_input->requestFocus();
192 
193  m_fpsTimer.start();
194  }
195 
197  if (!m_isAttached)
198  return;
199  m_isAttached = false;
201  m_fpsTimer.stop();
202  }
203 
204  void Console::show() {
205  if(m_hiding) {
206  m_hiding = false;
207  doShow();
209  }
210  }
211 
212  void Console::hide() {
213  if(!m_hiding) {
214  m_hiding = true;
216  }
217  }
218 
220  m_hiding = !m_hiding;
221  if(!m_hiding)
222  doShow();
224  }
225 
226  void Console::execute(std::string cmd) {
227  FL_DBG(_log, LMsg("in execute with command ") << cmd);
228  if (cmd.empty())
229  return;
230 
231  // copy input to output
232  println(m_prompt + cmd);
233 
234  // run the command
235  try {
236  if (m_consoleexec) {
237  std::string resp = m_consoleexec->onConsoleCommand(cmd);
238  println(resp);
239  } else {
240  FL_WARN(_log, LMsg("ConsoleExecuter not bind, but command received: ") << cmd.c_str());
241  }
242  }
243  catch (const FIFE::Exception & e) {
244  FL_WARN(_log, LMsg("Console caught exception: ") << e.what());
245  println(e.what());
246  }
247  }
248 
249  void Console::println(const std::string & s) {
250  assert(m_output);
251 
252  // Add the text in rows
253  boost::char_separator<char> separator("\n");
254  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
255  tokenizer tokens(s,separator);
256  for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i) {
257  m_output->addRow(*i);
258  }
259 
260  // Assure the maximum number of rows
261  if( m_output->getNumberOfRows() > m_maxOutputRows ) {
262  unsigned rows = m_output->getNumberOfRows();
263  int32_t delta_rows = rows - m_maxOutputRows;
264  std::vector<std::string> rows_text;
265  for(size_t i=delta_rows; i != rows; ++i) {
266  rows_text.push_back(m_output->getTextRow(i));
267  }
268  m_output->setText("");
269  for(size_t i=0; i != rows_text.size(); ++i) {
270  m_output->addRow(rows_text[i]);
271  }
272  }
273 
274  // Assure the new text is visible
275  fcn::Rectangle rect(0,m_output->getHeight(),0,0);
276  m_outputscrollarea->showWidgetPart(m_output,rect);
277  }
278 
279  void Console::action(const fcn::ActionEvent & event) {
280  if (m_consoleexec) {
282  } else {
283  FL_WARN(_log, "ConsoleExecuter not bind, but tools button clicked");
284  }
285  }
286 
287  void Console::setConsoleExecuter(ConsoleExecuter* const consoleexec) {
288  m_consoleexec = consoleexec;
289  }
290 
292  m_consoleexec = NULL;
293  }
294 
296  m_input->setFont(font);
297  m_output->setFont(font);
298  }
299 
300  void Console::focusLost(const fcn::Event& ) {
301  hide();
302  }
303 }
#define FL_WARN(logger, msg)
Definition: logger.h:72
virtual void onToolsClick()=0
Called when console tools button is clicked.
void focusLost(const fcn::Event &event)
Hide if we loose focus.
Definition: console.cpp:300
void add(fcn::Widget *widget)
Adds a new widget.
virtual const char * what() const
Returns the error message.
Definition: exception.cpp:41
uint32_t getScreenHeight() const
void setConsoleExecuter(ConsoleExecuter *const consoleexec)
Sets executer for the console.
Definition: console.cpp:287
CommandLine * m_input
Definition: console.h:149
virtual std::string onConsoleCommand(const std::string &command)=0
Called when user has typed command to console and pressed enter.
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
Definition: logger.h:82
void execute(std::string cmd)
Execute a command Normally just sends the command to runString() Checks whether the cmd is just one t...
Definition: console.cpp:226
void hide()
Hide the console Removes itself from the toplevel container and pops it&#39;s input context.
Definition: console.cpp:212
void setCallback(const type_callback &cb)
Set callback on pressing the ENTER key.
void updateAnimation()
Update the scroll in/out animation.
Definition: console.cpp:164
A Command line widget.
Definition: commandline.h:43
static Logger _log(LM_AUDIO)
void setInterval(int32_t msec)
Set the interval in milliseconds.
Definition: timer.cpp:60
void setIOFont(GuiFont *font)
Sets the font used for the input and output areas.
Definition: console.cpp:295
void removeConsoleExecuter()
Removes executer for the console.
Definition: console.cpp:291
Exception base class.
Definition: exception.h:43
void start()
Start the timer.
Definition: timer.cpp:45
GuiFont * createFont(const std::string &path="", uint32_t size=0, const std::string &glyphs="")
Gets font with given properties.
Timer m_animationTimer
Definition: console.h:164
static FifechanManager * instance()
Definition: singleton.h:84
int32_t m_hiddenPos
Definition: console.h:158
std::string m_prompt
Definition: console.h:156
Console executer is listener interface for console activity.
Definition: console.h:45
fcn::Button * m_toolsbutton
Definition: console.h:153
void doShow()
Definition: console.cpp:184
uint32_t getScreenWidth() const
void remove(fcn::Widget *widget)
Removes a widget.
double getAverageFrameTime() const
Gets average frame time.
Console()
Constructor.
Definition: console.cpp:48
void println(const std::string &s)
Print one or more lines to the console output.
Definition: console.cpp:249
void show()
Show the console Adds the Console to the fifechan toplevel container and pushes an input Context so t...
Definition: console.cpp:204
void toggleShowHide()
Toggle the console Toggles whether the Console is shown or not.
Definition: console.cpp:219
bool m_hiding
Definition: console.h:161
fcn::Label * m_status
Definition: console.h:152
virtual ~Console()
Destructor.
Definition: console.cpp:143
void stop()
Stop the timer.
Definition: timer.cpp:53
static const unsigned m_maxOutputRows
Definition: console.h:154
void updateCaption()
Update the FPS caption.
Definition: console.cpp:157
fcn::Container * getTopContainer() const
Gets the top container.
void doHide()
Definition: console.cpp:196
Timer m_fpsTimer
Definition: console.h:163
void reLayout()
Layouts the console to match e.g.
Definition: console.cpp:88
ConsoleExecuter * m_consoleexec
Definition: console.h:147
fcn::ScrollArea * m_outputscrollarea
Definition: console.h:151
bool m_isAttached
Definition: console.h:146
int32_t m_animationDelta
Definition: console.h:159
#define FL_DBG(logger, msg)
Definition: logger.h:70
void setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Set the color the text should be rendered in.
Definition: gui_font.cpp:186
void setCallback(const type_callback &callback)
Set the callback that will be called.
Definition: timer.cpp:64
fcn::TextBox * m_output
Definition: console.h:150
void action(const fcn::ActionEvent &event)
Callback from fifechan to respond to button press.
Definition: console.cpp:279
void clear()
Clear the console output.
Definition: console.cpp:180