FIFE 2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2008 by the FIFE team * 00003 * http://www.fifengine.de * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 // Standard C++ library includes 00023 #include <cassert> 00024 00025 // 3rd party library includes 00026 #include <boost/bind.hpp> 00027 #include <boost/lexical_cast.hpp> 00028 #include <boost/regex.hpp> 00029 #include <boost/tokenizer.hpp> 00030 00031 // FIFE includes 00032 // These includes are split up in two parts, separated by one empty line 00033 // First block: files included from the FIFE root src directory 00034 // Second block: files included from the same folder 00035 #include "video/renderbackend.h" 00036 #include "util/time/timemanager.h" 00037 #include "util/log/logger.h" 00038 #include "util/base/exception.h" 00039 #include "gui/guimanager.h" 00040 #include "gui/base/gui_font.h" 00041 #include "gui/widgets/utf8textbox.h" 00042 00043 #include "commandline.h" 00044 #include "console.h" 00045 00046 namespace FIFE { 00047 const unsigned Console::m_maxOutputRows = 50; 00048 static Logger _log(LM_CONSOLE); 00049 00050 Console::Console() 00051 : gcn::Container(), 00052 m_consoleexec(0), 00053 m_input(new CommandLine()), 00054 m_output(new gcn::UTF8TextBox()), 00055 m_outputscrollarea(new gcn::ScrollArea(m_output)), 00056 m_status(new gcn::Label()), 00057 m_toolsbutton(new gcn::Button("Tools")) 00058 { 00059 reLayout(); 00060 00061 add(m_outputscrollarea); 00062 add(m_input); 00063 add(m_status); 00064 add(m_toolsbutton); 00065 00066 setOpaque(true); 00067 00068 m_input->setCallback( std::bind1st( std::mem_fun(&Console::execute), this) ); 00069 m_prompt = "-- "; 00070 00071 m_isAttached = false; 00072 00073 m_fpsTimer.setInterval(500); 00074 m_fpsTimer.setCallback( boost::bind(&Console::updateCaption, this) ); 00075 00076 m_hiding = true; 00077 00078 m_animationTimer.setInterval(20); 00079 m_animationTimer.setCallback( boost::bind(&Console::updateAnimation, this) ); 00080 00081 m_toolsbutton->addActionListener(this); 00082 m_toolsbutton->setFocusable(false); 00083 m_input->addFocusListener(this); 00084 00085 GuiFont* font = GUIManager::instance()->createFont(); 00086 font->setColor(255,255,255); 00087 setIOFont(font); 00088 } 00089 00090 void Console::reLayout() { 00091 Image* screen = RenderBackend::instance()->getScreenImage(); 00092 assert(screen); 00093 00094 int w, h, b, input_h, bbar_h, button_w; 00095 w = screen->getWidth() * 4/5; 00096 h = screen->getHeight() * 4/5; 00097 b = 0; 00098 input_h = getFont()->getHeight(); 00099 bbar_h = input_h; 00100 button_w = 80; 00101 00102 gcn::Color black(0x00,0,0,0xff); 00103 gcn::Color white(0xff,0xff,0xff,0xff); 00104 gcn::Color dark(50,60,50,0xff); 00105 00106 setSize(w, h); 00107 setPosition((screen->getWidth() - w) / 2,-h); 00108 setFrameSize(0); 00109 00110 setForegroundColor(white); 00111 setBackgroundColor(black); 00112 setBaseColor(dark); 00113 00114 setSize(w, h); 00115 00116 m_outputscrollarea->setSize(w - 2*b, h - input_h - 3*b - bbar_h); 00117 m_outputscrollarea->setPosition(b,0); 00118 00119 m_input->setPosition(b, h - input_h - b - bbar_h); 00120 m_input->setSize(w - 2*b, input_h); 00121 00122 m_status->setPosition(b, h - b - bbar_h); 00123 m_status->setSize(w - 2*b, bbar_h); 00124 00125 m_toolsbutton->setPosition(w - button_w, h - b - bbar_h); 00126 m_toolsbutton->setSize(button_w, bbar_h); 00127 00128 m_output->setBackgroundColor(black); 00129 m_output->setFocusable(false); 00130 00131 m_outputscrollarea->setBackgroundColor(black); 00132 m_outputscrollarea->setBaseColor(dark); 00133 00134 m_input->setForegroundColor(white); 00135 m_input->setBackgroundColor(black); 00136 00137 m_status->setForegroundColor(white); 00138 m_status->setBackgroundColor(black); 00139 00140 m_toolsbutton->setForegroundColor(white); 00141 m_toolsbutton->setBackgroundColor(black); 00142 m_toolsbutton->setBaseColor(dark); 00143 00144 m_hiddenPos = -h; 00145 m_animationDelta = h/6; 00146 } 00147 00148 Console::~Console() { 00149 doHide(); 00150 00151 remove(m_input); 00152 remove(m_outputscrollarea); 00153 remove(m_status); 00154 00155 delete m_output; 00156 delete m_input; 00157 delete m_outputscrollarea; 00158 delete m_status; 00159 delete m_toolsbutton; 00160 } 00161 00162 void Console::updateCaption() { 00163 std::string caption = "FIFE Console - FPS: "; 00164 float fps = 1e3/double(TimeManager::instance()->getAverageFrameTime()); 00165 caption += boost::lexical_cast<std::string>(fps); 00166 m_status->setCaption( caption ); 00167 } 00168 00169 void Console::updateAnimation() { 00170 if (m_hiding){ 00171 setPosition(getX(), getY() - m_animationDelta); 00172 if (getY() <= m_hiddenPos){ 00173 doHide(); 00174 m_animationTimer.stop(); 00175 } 00176 }else{ 00177 setPosition(getX(), getY() + m_animationDelta); 00178 if (getY() >= 0){ 00179 setPosition(getX(), 0); 00180 m_animationTimer.stop(); 00181 } 00182 } 00183 } 00184 00185 void Console::clear() { 00186 m_output->setText(""); 00187 } 00188 00189 void Console::doShow() { 00190 if (m_isAttached) 00191 return; 00192 m_isAttached = true; 00193 GUIManager::instance()->add(this); 00194 GUIManager::instance()->getTopContainer()->moveToTop(this); 00195 // Assure the input field is focused when shown. 00196 m_input->requestFocus(); 00197 00198 m_fpsTimer.start(); 00199 } 00200 00201 void Console::doHide() { 00202 if (!m_isAttached) 00203 return; 00204 m_isAttached = false; 00205 GUIManager::instance()->remove(this); 00206 m_fpsTimer.stop(); 00207 } 00208 00209 void Console::show() { 00210 if(m_hiding) { 00211 m_hiding = false; 00212 doShow(); 00213 m_animationTimer.start(); 00214 } 00215 } 00216 00217 void Console::hide() { 00218 if(!m_hiding) { 00219 m_hiding = true; 00220 m_animationTimer.start(); 00221 } 00222 } 00223 00224 void Console::toggleShowHide() { 00225 m_hiding = !m_hiding; 00226 if(!m_hiding) 00227 doShow(); 00228 m_animationTimer.start(); 00229 } 00230 00231 void Console::execute(std::string cmd) { 00232 FL_DBG(_log, LMsg("in execute with command ") << cmd); 00233 if (cmd.empty()) 00234 return; 00235 00236 // copy input to output 00237 println(m_prompt + cmd); 00238 00239 // run the command 00240 try { 00241 if (m_consoleexec) { 00242 std::string resp = m_consoleexec->onConsoleCommand(cmd); 00243 println(resp); 00244 } else { 00245 FL_WARN(_log, LMsg("ConsoleExecuter not bind, but command received: ") << cmd.c_str()); 00246 } 00247 } 00248 catch (const FIFE::Exception & e) { 00249 FL_WARN(_log, LMsg("Console caught exception: ") << e.what()); 00250 println(e.what()); 00251 } 00252 } 00253 00254 void Console::println(const std::string & s) { 00255 assert(m_output); 00256 00257 // Add the text in rows 00258 boost::char_separator<char> separator("\n"); 00259 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 00260 tokenizer tokens(s,separator); 00261 for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i) { 00262 m_output->addRow(*i); 00263 } 00264 00265 // Assure the maximum number of rows 00266 if( m_output->getNumberOfRows() > m_maxOutputRows ) { 00267 unsigned rows = m_output->getNumberOfRows(); 00268 int delta_rows = rows - m_maxOutputRows; 00269 std::vector<std::string> rows_text; 00270 for(size_t i=delta_rows; i != rows; ++i) { 00271 rows_text.push_back(m_output->getTextRow(i)); 00272 } 00273 m_output->setText(""); 00274 for(size_t i=0; i != rows_text.size(); ++i) { 00275 m_output->addRow(rows_text[i]); 00276 } 00277 } 00278 00279 // Assure the new text is visible 00280 gcn::Rectangle rect(0,m_output->getHeight(),0,0); 00281 m_outputscrollarea->showWidgetPart(m_output,rect); 00282 } 00283 00284 void Console::action(const gcn::ActionEvent & event) { 00285 if (m_consoleexec) { 00286 m_consoleexec->onToolsClick(); 00287 } else { 00288 FL_WARN(_log, "ConsoleExecuter not bind, but tools button clicked"); 00289 } 00290 } 00291 00292 void Console::setConsoleExecuter(ConsoleExecuter* const consoleexec) { 00293 m_consoleexec = consoleexec; 00294 } 00295 00296 void Console::removeConsoleExecuter() { 00297 m_consoleexec = NULL; 00298 } 00299 00300 void Console::setIOFont(GuiFont* font) { 00301 m_input->setFont(font); 00302 m_output->setFont(font); 00303 } 00304 00305 void Console::focusLost(const gcn::Event& ) { 00306 hide(); 00307 } 00308 } 00309 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */