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