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/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
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
00237 println(m_prompt + cmd);
00238
00239
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.getMessage());
00250 println(e.getMessage());
00251 }
00252 }
00253
00254 void Console::println(const std::string & s) {
00255 assert(m_output);
00256
00257
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
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
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