Console can be toggled with Tab key / Receives chars while open
authorChristoph Sommer <mail@christoph-sommer.de>
Thu, 6 Apr 2006 14:06:48 +0000 (14:06 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Thu, 6 Apr 2006 14:06:48 +0000 (14:06 +0000)
SVN-Revision: 3251

src/console.cpp
src/console.hpp
src/control/joystickkeyboardcontroller.cpp

index d5e34d9..6da3a36 100644 (file)
@@ -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<std::string>::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<std::string> Console::lines;
+ConsoleStreamBuffer Console::inputBuffer;
 ConsoleStreamBuffer Console::outputBuffer;
+std::ostream Console::input(&Console::inputBuffer);
 std::ostream Console::output(&Console::outputBuffer);
 
index 880ccb7..0b119f3 100644 (file)
@@ -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<std::string> lines;
-    DrawingContext* context;
-    Surface* background;
-    static int height;
+    static std::list<std::string> 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();
     }
 };
index a68d09c..a07bd4d 100644 (file)
@@ -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 {