00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cassert>
00024
00025
00026 #include <boost/bind.hpp>
00027 #include <boost/lexical_cast.hpp>
00028 #include <boost/regex.hpp>
00029 #include <boost/tokenizer.hpp>
00030
00031
00032
00033
00034
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/guichan/guichanmanager.h"
00040 #include "gui/guichan/base/gui_font.h"
00041 #include "gui/guichan/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 = GUIChanManager::instance()->createFont();
00086 font->setColor(255,255,255);
00087 setIOFont(font);
00088 }
00089
00090 void Console::reLayout() {
00091 int32_t w, h, b, input_h, bbar_h, button_w;
00092 w = RenderBackend::instance()->getScreenWidth() * 4/5;
00093 h = RenderBackend::instance()->getScreenHeight() * 4/5;
00094 b = 0;
00095 input_h = getFont()->getHeight();
00096 bbar_h = input_h;
00097 button_w = 80;
00098
00099 gcn::Color black(0x00,0,0,0xff);
00100 gcn::Color white(0xff,0xff,0xff,0xff);
00101 gcn::Color dark(50,60,50,0xff);
00102
00103 setSize(w, h);
00104 setPosition((RenderBackend::instance()->getScreenWidth() - w) / 2,-h);
00105 setFrameSize(0);
00106
00107 setForegroundColor(white);
00108 setBackgroundColor(black);
00109 setBaseColor(dark);
00110
00111 setSize(w, h);
00112
00113 m_outputscrollarea->setSize(w - 2*b, h - input_h - 3*b - bbar_h);
00114 m_outputscrollarea->setPosition(b,0);
00115
00116 m_input->setPosition(b, h - input_h - b - bbar_h);
00117 m_input->setSize(w - 2*b, input_h);
00118
00119 m_status->setPosition(b, h - b - bbar_h);
00120 m_status->setSize(w - 2*b, bbar_h);
00121
00122 m_toolsbutton->setPosition(w - button_w, h - b - bbar_h);
00123 m_toolsbutton->setSize(button_w, bbar_h);
00124
00125 m_output->setBackgroundColor(black);
00126 m_output->setFocusable(false);
00127
00128 m_outputscrollarea->setBackgroundColor(black);
00129 m_outputscrollarea->setBaseColor(dark);
00130
00131 m_input->setForegroundColor(white);
00132 m_input->setBackgroundColor(black);
00133
00134 m_status->setForegroundColor(white);
00135 m_status->setBackgroundColor(black);
00136
00137 m_toolsbutton->setForegroundColor(white);
00138 m_toolsbutton->setBackgroundColor(black);
00139 m_toolsbutton->setBaseColor(dark);
00140
00141 m_hiddenPos = -h;
00142 m_animationDelta = h/6;
00143 }
00144
00145 Console::~Console() {
00146 doHide();
00147
00148 remove(m_input);
00149 remove(m_outputscrollarea);
00150 remove(m_status);
00151
00152 delete m_output;
00153 delete m_input;
00154 delete m_outputscrollarea;
00155 delete m_status;
00156 delete m_toolsbutton;
00157 }
00158
00159 void Console::updateCaption() {
00160 std::string caption = "FIFE Console - FPS: ";
00161 double fps = 1e3/TimeManager::instance()->getAverageFrameTime();
00162 caption += boost::lexical_cast<std::string>(fps);
00163 m_status->setCaption( caption );
00164 }
00165
00166 void Console::updateAnimation() {
00167 if (m_hiding){
00168 setPosition(getX(), getY() - m_animationDelta);
00169 if (getY() <= m_hiddenPos){
00170 doHide();
00171 m_animationTimer.stop();
00172 }
00173 }else{
00174 setPosition(getX(), getY() + m_animationDelta);
00175 if (getY() >= 0){
00176 setPosition(getX(), 0);
00177 m_animationTimer.stop();
00178 }
00179 }
00180 }
00181
00182 void Console::clear() {
00183 m_output->setText("");
00184 }
00185
00186 void Console::doShow() {
00187 if (m_isAttached)
00188 return;
00189 m_isAttached = true;
00190 GUIChanManager::instance()->add(this);
00191 GUIChanManager::instance()->getTopContainer()->moveToTop(this);
00192
00193 m_input->requestFocus();
00194
00195 m_fpsTimer.start();
00196 }
00197
00198 void Console::doHide() {
00199 if (!m_isAttached)
00200 return;
00201 m_isAttached = false;
00202 GUIChanManager::instance()->remove(this);
00203 m_fpsTimer.stop();
00204 }
00205
00206 void Console::show() {
00207 if(m_hiding) {
00208 m_hiding = false;
00209 doShow();
00210 m_animationTimer.start();
00211 }
00212 }
00213
00214 void Console::hide() {
00215 if(!m_hiding) {
00216 m_hiding = true;
00217 m_animationTimer.start();
00218 }
00219 }
00220
00221 void Console::toggleShowHide() {
00222 m_hiding = !m_hiding;
00223 if(!m_hiding)
00224 doShow();
00225 m_animationTimer.start();
00226 }
00227
00228 void Console::execute(std::string cmd) {
00229 FL_DBG(_log, LMsg("in execute with command ") << cmd);
00230 if (cmd.empty())
00231 return;
00232
00233
00234 println(m_prompt + cmd);
00235
00236
00237 try {
00238 if (m_consoleexec) {
00239 std::string resp = m_consoleexec->onConsoleCommand(cmd);
00240 println(resp);
00241 } else {
00242 FL_WARN(_log, LMsg("ConsoleExecuter not bind, but command received: ") << cmd.c_str());
00243 }
00244 }
00245 catch (const FIFE::Exception & e) {
00246 FL_WARN(_log, LMsg("Console caught exception: ") << e.what());
00247 println(e.what());
00248 }
00249 }
00250
00251 void Console::println(const std::string & s) {
00252 assert(m_output);
00253
00254
00255 boost::char_separator<char> separator("\n");
00256 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00257 tokenizer tokens(s,separator);
00258 for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i) {
00259 m_output->addRow(*i);
00260 }
00261
00262
00263 if( m_output->getNumberOfRows() > m_maxOutputRows ) {
00264 unsigned rows = m_output->getNumberOfRows();
00265 int32_t delta_rows = rows - m_maxOutputRows;
00266 std::vector<std::string> rows_text;
00267 for(size_t i=delta_rows; i != rows; ++i) {
00268 rows_text.push_back(m_output->getTextRow(i));
00269 }
00270 m_output->setText("");
00271 for(size_t i=0; i != rows_text.size(); ++i) {
00272 m_output->addRow(rows_text[i]);
00273 }
00274 }
00275
00276
00277 gcn::Rectangle rect(0,m_output->getHeight(),0,0);
00278 m_outputscrollarea->showWidgetPart(m_output,rect);
00279 }
00280
00281 void Console::action(const gcn::ActionEvent & event) {
00282 if (m_consoleexec) {
00283 m_consoleexec->onToolsClick();
00284 } else {
00285 FL_WARN(_log, "ConsoleExecuter not bind, but tools button clicked");
00286 }
00287 }
00288
00289 void Console::setConsoleExecuter(ConsoleExecuter* const consoleexec) {
00290 m_consoleexec = consoleexec;
00291 }
00292
00293 void Console::removeConsoleExecuter() {
00294 m_consoleexec = NULL;
00295 }
00296
00297 void Console::setIOFont(GuiFont* font) {
00298 m_input->setFont(font);
00299 m_output->setFont(font);
00300 }
00301
00302 void Console::focusLost(const gcn::Event& ) {
00303 hide();
00304 }
00305 }
00306