From: Christoph Sommer Date: Thu, 6 Apr 2006 14:06:48 +0000 (+0000) Subject: Console can be toggled with Tab key / Receives chars while open X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=1aee62827ba3b70b885a9319a8997babf0413d52;p=supertux.git Console can be toggled with Tab key / Receives chars while open SVN-Revision: 3251 --- diff --git a/src/console.cpp b/src/console.cpp index d5e34d928..6da3a364e 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -30,7 +30,7 @@ namespace { int ticks; // TODO: use a clock? } -Console::Console(DrawingContext* context) : context(context) +Console::Console(DrawingContext* context) : context(context) { background = new Surface("images/engine/console.jpg"); } @@ -41,43 +41,102 @@ Console::~Console() } void -Console::flush() +Console::flush(ConsoleStreamBuffer* buffer) { - lines.push_front(outputBuffer.str()); - if (lines.size() >= 256) lines.pop_back(); - if (height < 64) { - if (height < 4) height=4; - height+=9; - } - ticks=120; - std::cerr << outputBuffer.str() << std::flush; - outputBuffer.str(std::string()); + if (buffer == &outputBuffer) { + std::string s = outputBuffer.str(); + if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) { + while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1); + addLine(s); + outputBuffer.str(std::string()); + } + } + if (buffer == &inputBuffer) { + std::string s = inputBuffer.str(); + if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) { + while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1); + addLine("> "+s); + parse(s); + inputBuffer.str(std::string()); + } + } +} + +void +Console::addLine(std::string s) +{ + lines.push_front(s); + if (lines.size() >= 256) lines.pop_back(); + if (height < 64) { + if (height < 4+9) height=4+9; + height+=9; + } + ticks=120; + std::cerr << s << std::endl; +} + +void +Console::parse(std::string s) +{ + addLine("unknown command: \"" + s + "\""); +} + +bool +Console::hasFocus() +{ + return focused; +} + +void +Console::show() +{ + focused = true; + height = 128; +} + +void +Console::hide() +{ + focused = false; + ticks = 0; } void Console::draw() { if (height == 0) return; - if (ticks-- < 0) { - height-=1; - ticks=0; - if (height < 0) height=0; + if (!focused) { + if (ticks-- < 0) { + height-=1; + ticks=0; + if (height < 0) height=0; + } + if (height == 0) return; } - if (height == 0) return; context->draw_surface(background, Vector(SCREEN_WIDTH/2 - background->get_width()/2, height - background->get_height()), LAYER_FOREGROUND1+1); int lineNo = 0; + + if (focused) { + lineNo++; + float py = height-4-1*9; + context->draw_text(white_small_text, "> "+inputBuffer.str(), Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1); + } + for (std::list::iterator i = lines.begin(); i != lines.end(); i++) { lineNo++; float py = height-4-lineNo*9; if (py < -9) break; - context->draw_text(white_small_text, *i, Vector(BORDER_X, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1); + context->draw_text(white_small_text, *i, Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1); } } int Console::height = 0; +bool Console::focused = false; std::list Console::lines; +ConsoleStreamBuffer Console::inputBuffer; ConsoleStreamBuffer Console::outputBuffer; +std::ostream Console::input(&Console::inputBuffer); std::ostream Console::output(&Console::outputBuffer); diff --git a/src/console.hpp b/src/console.hpp index 880ccb7fd..0b119f379 100644 --- a/src/console.hpp +++ b/src/console.hpp @@ -36,19 +36,28 @@ class Console Console(DrawingContext* context); ~Console(); - static std::ostream output; + static std::ostream input; /**< stream of keyboard input to send to the console. Do not forget to send std::endl or to flush the stream. */ + static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */ - static void flush(); + static void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a stream, normally called by the stream itself */ - void draw(); + void draw(); /**< draw the console to its */ + static void show(); /**< display the console */ + static void hide(); /**< hide the console */ + static bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */ protected: - static std::list lines; - DrawingContext* context; - Surface* background; - static int height; + static std::list lines; /**< backbuffer of lines sent to the console */ + DrawingContext* context; /**< context to draw to */ + Surface* background; /**< console background image */ + static int height; /**< height of the console in px */ + static bool focused; /**< true if console has input focus */ - static ConsoleStreamBuffer outputBuffer; + static ConsoleStreamBuffer inputBuffer; /**< stream buffer used by input stream */ + static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */ + + static void addLine(std::string s); /**< display a line in the console */ + static void parse(std::string s); /**< react to a given command */ }; class ConsoleStreamBuffer : public std::stringbuf @@ -56,7 +65,7 @@ class ConsoleStreamBuffer : public std::stringbuf public: int sync() { - Console::flush(); + Console::flush(this); return std::stringbuf::sync(); } }; diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp index a68d09c7d..a07bd4d5f 100644 --- a/src/control/joystickkeyboardcontroller.cpp +++ b/src/control/joystickkeyboardcontroller.cpp @@ -27,6 +27,7 @@ #include "lisp/lisp.hpp" #include "lisp/list_iterator.hpp" #include "game_session.hpp" +#include "console.hpp" class JoystickKeyboardController::JoystickMenu : public Menu { @@ -254,12 +255,35 @@ JoystickKeyboardController::process_event(const SDL_Event& event) (event.key.keysym.unicode & 0xFF80) == 0) { memmove(last_keys, last_keys+1, sizeof(last_keys)-1); last_keys[sizeof(last_keys)-1] = event.key.keysym.unicode; + + if (Console::hasFocus()) { + // if the Console is open, send keys there + char c = event.key.keysym.unicode; + if ((c >= 32) && (c <= 126)) { + Console::input << c; + } + if ((c == '\n') || (c == '\r')) { + Console::input << std::endl; + } + if (c == '\t') { + Console::hide(); + } + } else { + char c = event.key.keysym.unicode; + if (c == '\t') { + Console::show(); + } + } + if(GameSession::current() != NULL) GameSession::current()->try_cheats(); } - - // menu mode? - if(Menu::current()) { // menu mode + + if(Console::hasFocus()) { + // console is open - ignore key + } + else if(Menu::current()) { + // menu mode process_menu_key_event(event); return; } else {