Console toggle key is now read from config (control "console"). Hint: key 94 is the caret character /
Console now accepts multiple ConsoleCommandListeners per command. Will only call the most recently registered one /
Autocomplete only completes unambiguous commands /
"End" key scrolls to backbuffer end
SVN-Revision: 3272
std::string cmdList = "";
int cmdListLen = 0;
- for (std::map<std::string, ConsoleCommandReceiver*>::iterator i = commands.begin(); i != commands.end(); i++) {
+ for (std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.begin(); i != commands.end(); i++) {
std::string cmdKnown = i->first;
if (cmdKnown.substr(0, cmdPart.length()) == cmdPart) {
- if (cmdListLen == 0) {
- inputBuffer.str(cmdKnown);
- inputBuffer.pubseekoff(0, std::ios_base::end, std::ios_base::out);
- } else {
- cmdList = cmdList + ", ";
- }
+ if (cmdListLen > 0) cmdList = cmdList + ", ";
cmdList = cmdList + cmdKnown;
cmdListLen++;
}
}
if (cmdListLen == 0) addLine("No known command starts with \""+cmdPart+"\"");
+ if (cmdListLen == 1) {
+ inputBuffer.str(cmdList);
+ inputBuffer.pubseekoff(0, std::ios_base::end, std::ios_base::out);
+ }
if (cmdListLen > 1) addLine(cmdList);
}
Console::addLine(std::string s)
{
lines.push_front(s);
- if (lines.size() >= 256) lines.pop_back();
+ if (lines.size() >= 65535) lines.pop_back();
if (height < 64) {
if (height < 4+9) height=4+9;
height+=9;
void
Console::parse(std::string s)
{
- if (commands.find(s) == commands.end()) {
+ std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(s);
+ if ((i == commands.end()) || (i->second.size() == 0)) {
addLine("unknown command: \"" + s + "\"");
return;
}
- ConsoleCommandReceiver* ccr = commands[s];
+
+ // send command to the most recently registered ccr
+ ConsoleCommandReceiver* ccr = i->second.front();
if (ccr->consoleCommand(s) != true) msg_warning("Sent command to registered ccr, but command was unhandled");
}
{
focused = false;
height = 0;
+
+ // clear input buffer
+ inputBuffer.str(std::string());
+}
+
+void
+Console::toggle()
+{
+ if (Console::hasFocus()) {
+ Console::hide();
+ }
+ else {
+ Console::show();
+ }
}
void
void
Console::registerCommand(std::string command, ConsoleCommandReceiver* ccr)
{
- if (commands.find(command) != commands.end()) {
- msg_warning("Command \"" << command << "\" already associated with a command receiver. Not associated.");
- return;
- }
- commands[command] = ccr;
+ commands[command].push_front(ccr);
}
void
Console::unregisterCommand(std::string command, ConsoleCommandReceiver* ccr)
{
- if (commands.find(command) == commands.end()) {
+ std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(command);
+ if ((i == commands.end()) || (i->second.size() == 0)) {
msg_warning("Command \"" << command << "\" not associated with a command receiver. Not dissociated.");
return;
}
- if (commands[command] != ccr) {
- msg_warning("Command \"" << command << "\" associated with another command receiver. Not dissociated.");
+ std::list<ConsoleCommandReceiver*>::iterator j = find(i->second.begin(), i->second.end(), ccr);
+ if (j == i->second.end()) {
+ msg_warning("Command \"" << command << "\" not associated with given command receiver. Not dissociated.");
return;
}
- commands.erase(command);
+ i->second.erase(j);
}
int Console::height = 0;
bool Console::focused = false;
std::list<std::string> Console::lines;
-std::map<std::string, ConsoleCommandReceiver*> Console::commands;
+std::map<std::string, std::list<ConsoleCommandReceiver*> > Console::commands;
ConsoleStreamBuffer Console::inputBuffer;
ConsoleStreamBuffer Console::outputBuffer;
std::ostream Console::input(&Console::inputBuffer);
void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
static void show(); /**< display the console */
static void hide(); /**< hide the console */
+ static void toggle(); /**< display the console if hidden, hide otherwise */
+
static bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
static void registerCommand(std::string command, ConsoleCommandReceiver* ccr); /**< associate command with the given CCR */
static void unregisterCommand(std::string command, ConsoleCommandReceiver* ccr); /**< dissociate command and CCR */
protected:
static std::list<std::string> lines; /**< backbuffer of lines sent to the console */
- static std::map<std::string, ConsoleCommandReceiver*> commands; /**< map of console commands and their associated ConsoleCommandReceivers */
+ static std::map<std::string, std::list<ConsoleCommandReceiver*> > commands; /**< map of console commands and a list of associated ConsoleCommandReceivers */
Surface* background; /**< console background image */
static int height; /**< height of the console in px */
static int offset; /**< decrease to scroll text up */
"action",
"pause-menu",
"menu-select",
+ "console",
0
};
ACTION,
PAUSE_MENU,
MENU_SELECT,
+ CONSOLE,
CONTROLCOUNT
};
keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU));
keymap.insert(std::make_pair(SDLK_RETURN, MENU_SELECT));
keymap.insert(std::make_pair(SDLK_KP_ENTER, MENU_SELECT));
+ keymap.insert(std::make_pair(SDLK_CARET, CONSOLE));
int joystick_count = SDL_NumJoysticks();
min_joybuttons = -1;
switch(event.type) {
case SDL_KEYUP:
case SDL_KEYDOWN:
- if (event.key.keysym.scancode == 49) {
- // console key was pressed - toggle console
- if (event.type == SDL_KEYDOWN) {
- if (Console::hasFocus()) {
- Console::hide();
- } else {
- Console::show();
- }
- }
- } else if (Console::hasFocus()) {
- // console is open - send key there
- if (event.type == SDL_KEYDOWN) {
- int c = event.key.keysym.unicode;
- if ((c >= 32) && (c <= 126)) {
- Console::input << (char)c;
- }
- switch (event.key.keysym.sym) {
- case SDLK_RETURN:
- Console::input << std::endl;
- break;
- case SDLK_BACKSPACE:
- Console::backspace();
- break;
- case SDLK_TAB:
- Console::autocomplete();
- break;
- case SDLK_PAGEUP:
- Console::scroll(-1);
- break;
- case SDLK_PAGEDOWN:
- Console::scroll(+1);
- break;
- default:
- break;
- }
- }
- }
- else if (Menu::current()) {
- // menu mode - send key there
- process_menu_key_event(event);
- return;
- } else {
- // normal mode - find key in keymap
- KeyMap::iterator i = keymap.find(event.key.keysym.sym);
- if(i == keymap.end()) {
- msg_debug("Pressed key without mapping");
- return;
- }
- Control control = i->second;
- controls[control] = event.type == SDL_KEYDOWN ? true : false;
- }
+ process_key_event(event);
break;
case SDL_JOYAXISMOTION:
}
void
+JoystickKeyboardController::process_key_event(const SDL_Event& event)
+{
+ KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
+
+ // if console key was pressed: toggle console
+ if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
+ if (event.type != SDL_KEYDOWN) return;
+ Console::toggle();
+ return;
+ }
+
+ // if console is open: send key there
+ if (Console::hasFocus()) {
+ process_console_key_event(event);
+ return;
+ }
+
+ // if menu mode: send key there
+ if (Menu::current()) {
+ process_menu_key_event(event);
+ return;
+ }
+
+ // default action: update controls
+ if(key_mapping == keymap.end()) {
+ msg_debug("Key " << event.key.keysym.sym << " is unbound");
+ return;
+ }
+ Control control = key_mapping->second;
+ controls[control] = event.type == SDL_KEYDOWN ? true : false;
+}
+
+void
+JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
+{
+ if (event.type != SDL_KEYDOWN) return;
+
+ switch (event.key.keysym.sym) {
+ case SDLK_RETURN:
+ Console::input << std::endl;
+ break;
+ case SDLK_BACKSPACE:
+ Console::backspace();
+ break;
+ case SDLK_TAB:
+ Console::autocomplete();
+ break;
+ case SDLK_PAGEUP:
+ Console::scroll(-1);
+ break;
+ case SDLK_PAGEDOWN:
+ Console::scroll(+1);
+ break;
+ case SDLK_END:
+ Console::scroll(+65535);
+ break;
+ default:
+ int c = event.key.keysym.unicode;
+ if ((c >= 32) && (c <= 126)) {
+ Console::input << (char)c;
+ }
+ break;
+ }
+}
+
+void
JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
{
// wait for key mode?
Menu* get_joystick_options_menu();
private:
+ void process_key_event(const SDL_Event& event);
+ void process_console_key_event(const SDL_Event& event);
void process_menu_key_event(const SDL_Event& event);
typedef std::map<SDLKey, Control> KeyMap;
int min_joybuttons;
/// the max number of buttons a joystick has
int max_joybuttons;
-
+/*
enum {
MNID_KEY_UP,
MNID_KEY_DOWN,
MNID_KEY_LEFT,
MNID_KEY_RIGHT,
MNID_KEY_JUMP,
- MNID_KEY_ACTION
+ MNID_KEY_ACTION,
+ MNID_KEY_CONSOLE
};
enum {
MNID_JS_JUMP,
MNID_JS_MENU,
MNID_JS_PAUSE
};
+ */
SDLKey reversemap_key(Control c);
int reversemap_joybutton(Control c);
void reset_joybutton(int button, Control c);