diff --git a/src/chat.cpp b/src/chat.cpp index 50391d39b..d8cf3efd9 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -417,20 +417,18 @@ void ChatPrompt::input(const std::wstring &str) m_nick_completion_end = 0; } -std::wstring ChatPrompt::submit() +void ChatPrompt::addToHistory(std::wstring line) { - std::wstring line = m_line; - m_line.clear(); if (!line.empty()) m_history.push_back(line); if (m_history.size() > m_history_limit) m_history.erase(m_history.begin()); m_history_index = m_history.size(); - m_view = 0; - m_cursor = 0; - m_nick_completion_start = 0; - m_nick_completion_end = 0; - return line; +} + +std::wstring ChatPrompt::getLine() +{ + return m_line; } void ChatPrompt::clear() @@ -442,13 +440,15 @@ void ChatPrompt::clear() m_nick_completion_end = 0; } -void ChatPrompt::replace(std::wstring line) +std::wstring ChatPrompt::replace(std::wstring line) { + std::wstring old_line = m_line; m_line = line; m_view = m_cursor = line.size(); clampView(); m_nick_completion_start = 0; m_nick_completion_end = 0; + return old_line; } void ChatPrompt::historyPrev() diff --git a/src/chat.h b/src/chat.h index 5d26baf7b..367baaaf2 100644 --- a/src/chat.h +++ b/src/chat.h @@ -146,14 +146,17 @@ public: void input(wchar_t ch); void input(const std::wstring &str); - // Submit, clear and return current line - std::wstring submit(); + // Add a string to the history + void addToHistory(std::wstring line); + + // Get current line + std::wstring getLine(); // Clear the current line void clear(); // Replace the current line with the given text - void replace(std::wstring line); + std::wstring replace(std::wstring line); // Select previous command from history void historyPrev(); diff --git a/src/game.cpp b/src/game.cpp index 18ca11d6f..3d5f86e21 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -176,19 +176,6 @@ struct LocalFormspecHandler : public TextDest { } } - if (m_formname == "MT_CHAT_MENU") { - assert(m_client != 0); - - if ((fields.find("btn_send") != fields.end()) || - (fields.find("quit") != fields.end())) { - StringMap::const_iterator it = fields.find("f_text"); - if (it != fields.end()) - m_client->typeChatMessage(utf8_to_wide(it->second)); - - return; - } - } - if (m_formname == "MT_DEATH_SCREEN") { assert(m_client != 0); @@ -1097,27 +1084,6 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec, #define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop #endif -static void show_chat_menu(GUIFormSpecMenu **cur_formspec, - InventoryManager *invmgr, IGameDef *gamedef, - IWritableTextureSource *tsrc, IrrlichtDevice *device, - Client *client, std::string text) -{ - std::string formspec = - FORMSPEC_VERSION_STRING - SIZE_TAG - "field[3,2.35;6,0.5;f_text;;" + text + "]" - "button_exit[4,3;3,0.5;btn_send;" + strgettext("Proceed") + "]" - ; - - /* Create menu */ - /* Note: FormspecFormSource and LocalFormspecHandler - * are deleted by guiFormSpecMenu */ - FormspecFormSource *fs_src = new FormspecFormSource(formspec); - LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_CHAT_MENU", client); - - create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL); -} - static void show_deathscreen(GUIFormSpecMenu **cur_formspec, InventoryManager *invmgr, IGameDef *gamedef, IWritableTextureSource *tsrc, IrrlichtDevice *device, Client *client) @@ -1548,7 +1514,7 @@ protected: void dropSelectedItem(); void openInventory(); - void openConsole(); + void openConsole(float height, const wchar_t *line=NULL); void toggleFreeMove(float *statustext_time); void toggleFreeMoveAlt(float *statustext_time, float *jump_timer); void toggleFast(float *statustext_time); @@ -2683,16 +2649,16 @@ void Game::processKeyboardInput(VolatileRunFlags *flags, } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INVENTORY])) { openInventory(); } else if (input->wasKeyDown(EscapeKey) || input->wasKeyDown(CancelKey)) { - show_pause_menu(¤t_formspec, client, gamedef, texture_src, device, - simple_singleplayer_mode); + if (!gui_chat_console->isOpenInhibited()) { + show_pause_menu(¤t_formspec, client, gamedef, + texture_src, device, simple_singleplayer_mode); + } } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CHAT])) { - show_chat_menu(¤t_formspec, client, gamedef, texture_src, device, - client, ""); + openConsole(0.2, L""); } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CMD])) { - show_chat_menu(¤t_formspec, client, gamedef, texture_src, device, - client, "/"); + openConsole(0.2, L"/"); } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CONSOLE])) { - openConsole(); + openConsole(1); } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_FREEMOVE])) { toggleFreeMove(statustext_time); } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP])) { @@ -2727,15 +2693,15 @@ void Game::processKeyboardInput(VolatileRunFlags *flags, decreaseViewRange(statustext_time); } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_RANGESELECT])) { toggleFullViewRange(statustext_time); - } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_NEXT])) + } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_NEXT])) { quicktune->next(); - else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_PREV])) + } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_PREV])) { quicktune->prev(); - else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_INC])) + } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_INC])) { quicktune->inc(); - else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_DEC])) + } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_DEC])) { quicktune->dec(); - else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DEBUG_STACKS])) { + } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DEBUG_STACKS])) { // Print debug stacks dstream << "-----------------------------------------" << std::endl; @@ -2835,11 +2801,14 @@ void Game::openInventory() } -void Game::openConsole() +void Game::openConsole(float height, const wchar_t *line) { if (!gui_chat_console->isOpenInhibited()) { - // Open up to over half of the screen - gui_chat_console->openConsole(0.6); + gui_chat_console->openConsole(height); + if (line) { + gui_chat_console->setCloseOnEnter(true); + gui_chat_console->replaceAndAddToHistory(line); + } guienv->setFocus(gui_chat_console); } } diff --git a/src/guiChatConsole.cpp b/src/guiChatConsole.cpp index 3937e405c..4c0039e5e 100644 --- a/src/guiChatConsole.cpp +++ b/src/guiChatConsole.cpp @@ -55,6 +55,7 @@ GUIChatConsole::GUIChatConsole( m_screensize(v2u32(0,0)), m_animate_time_old(0), m_open(false), + m_close_on_enter(false), m_height(0), m_desired_height(0), m_desired_height_fraction(0.0), @@ -148,6 +149,14 @@ f32 GUIChatConsole::getDesiredHeight() const return m_desired_height_fraction; } +void GUIChatConsole::replaceAndAddToHistory(std::wstring line) +{ + ChatPrompt& prompt = m_chat_backend->getPrompt(); + prompt.addToHistory(prompt.getLine()); + prompt.replace(line); +} + + void GUIChatConsole::setCursor( bool visible, bool blinking, f32 blink_speed, f32 relative_height) { @@ -381,6 +390,9 @@ void GUIChatConsole::drawPrompt() bool GUIChatConsole::OnEvent(const SEvent& event) { + + ChatPrompt &prompt = m_chat_backend->getPrompt(); + if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown) { // Key input @@ -391,13 +403,16 @@ bool GUIChatConsole::OnEvent(const SEvent& event) // inhibit open so the_game doesn't reopen immediately m_open_inhibited = 50; + m_close_on_enter = false; return true; } else if(event.KeyInput.Key == KEY_ESCAPE) { closeConsoleAtOnce(); Environment->removeFocus(this); - // the_game will open the pause menu + m_close_on_enter = false; + // inhibit open so the_game doesn't reopen immediately + m_open_inhibited = 1; // so the ESCAPE button doesn't open the "pause menu" return true; } else if(event.KeyInput.Key == KEY_PRIOR) @@ -412,22 +427,28 @@ bool GUIChatConsole::OnEvent(const SEvent& event) } else if(event.KeyInput.Key == KEY_RETURN) { - std::wstring text = m_chat_backend->getPrompt().submit(); + prompt.addToHistory(prompt.getLine()); + std::wstring text = prompt.replace(L""); m_client->typeChatMessage(text); + if (m_close_on_enter) { + closeConsoleAtOnce(); + Environment->removeFocus(this); + m_close_on_enter = false; + } return true; } else if(event.KeyInput.Key == KEY_UP) { // Up pressed // Move back in history - m_chat_backend->getPrompt().historyPrev(); + prompt.historyPrev(); return true; } else if(event.KeyInput.Key == KEY_DOWN) { // Down pressed // Move forward in history - m_chat_backend->getPrompt().historyNext(); + prompt.historyNext(); return true; } else if(event.KeyInput.Key == KEY_LEFT) @@ -438,7 +459,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) event.KeyInput.Control ? ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, scope); @@ -452,7 +473,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) event.KeyInput.Control ? ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, scope); @@ -462,7 +483,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // Home pressed // move to beginning of line - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -472,7 +493,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // End pressed // move to end of line - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -486,7 +507,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) event.KeyInput.Control ? ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, scope); @@ -500,7 +521,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) event.KeyInput.Control ? ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, scope); @@ -513,17 +534,14 @@ bool GUIChatConsole::OnEvent(const SEvent& event) IOSOperator *os_operator = Environment->getOSOperator(); const c8 *text = os_operator->getTextFromClipboard(); if (text) - { - std::wstring wtext = narrow_to_wide(text); - m_chat_backend->getPrompt().input(wtext); - } + prompt.input(narrow_to_wide(text)); return true; } else if(event.KeyInput.Key == KEY_KEY_U && event.KeyInput.Control) { // Ctrl-U pressed // kill line to left end - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -533,7 +551,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // Ctrl-K pressed // kill line to right end - m_chat_backend->getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -545,7 +563,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) // Nick completion std::list names = m_client->getConnectedPlayerNames(); bool backwards = event.KeyInput.Shift; - m_chat_backend->getPrompt().nickCompletion(names, backwards); + prompt.nickCompletion(names, backwards); return true; } else if(event.KeyInput.Char != 0 && !event.KeyInput.Control) @@ -553,9 +571,9 @@ bool GUIChatConsole::OnEvent(const SEvent& event) #if (defined(linux) || defined(__linux)) wchar_t wc = L'_'; mbtowc( &wc, (char *) &event.KeyInput.Char, sizeof(event.KeyInput.Char) ); - m_chat_backend->getPrompt().input(wc); + prompt.input(wc); #else - m_chat_backend->getPrompt().input(event.KeyInput.Char); + prompt.input(event.KeyInput.Char); #endif return true; } diff --git a/src/guiChatConsole.h b/src/guiChatConsole.h index 652b265a4..7b9fc6732 100644 --- a/src/guiChatConsole.h +++ b/src/guiChatConsole.h @@ -51,11 +51,16 @@ public: void closeConsole(); // Close the console immediately, without animation. void closeConsoleAtOnce(); + // Set whether to close the console after the user presses enter. + void setCloseOnEnter(bool close) { m_close_on_enter = close; } // Return the desired height (fraction of screen size) // Zero if the console is closed or getting closed f32 getDesiredHeight() const; + // Replace actual line when adding the actual to the history (if there is any) + void replaceAndAddToHistory(std::wstring line); + // Change how the cursor looks void setCursor( bool visible, @@ -95,6 +100,8 @@ private: // should the console be opened or closed? bool m_open; + // should it close after you press enter? + bool m_close_on_enter; // current console height [pixels] s32 m_height; // desired height [pixels] diff --git a/src/terminal_chat_console.cpp b/src/terminal_chat_console.cpp index ac06285eb..c86a960fa 100644 --- a/src/terminal_chat_console.cpp +++ b/src/terminal_chat_console.cpp @@ -146,6 +146,7 @@ void TerminalChatConsole::typeChatMessage(const std::wstring &msg) void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) { + ChatPrompt &prompt = m_chat_backend.getPrompt(); // Helpful if you want to collect key codes that aren't documented /*if (ch != ERR) { m_chat_backend.addMessage(L"", @@ -177,20 +178,20 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_ENTER: case '\r': case '\n': { - std::wstring text = m_chat_backend.getPrompt().submit(); - typeChatMessage(text); + prompt.addToHistory(prompt.getLine()); + typeChatMessage(prompt.replace(L"")); break; } case KEY_UP: - m_chat_backend.getPrompt().historyPrev(); + prompt.historyPrev(); break; case KEY_DOWN: - m_chat_backend.getPrompt().historyNext(); + prompt.historyNext(); break; case KEY_LEFT: // Left pressed // move character to the left - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); @@ -198,7 +199,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 545: // Ctrl-Left pressed // move word to the left - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_WORD); @@ -206,7 +207,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_RIGHT: // Right pressed // move character to the right - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); @@ -214,7 +215,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 560: // Ctrl-Right pressed // move word to the right - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_WORD); @@ -222,7 +223,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_HOME: // Home pressed // move to beginning of line - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -230,7 +231,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_END: // End pressed // move to end of line - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -240,7 +241,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 127: // Backspace pressed // delete character to the left - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); @@ -248,7 +249,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_DC: // Delete pressed // delete character to the right - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); @@ -256,7 +257,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 519: // Ctrl-Delete pressed // delete word to the right - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_WORD); @@ -264,7 +265,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 21: // Ctrl-U pressed // kill line to left end - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -272,7 +273,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case 11: // Ctrl-K pressed // kill line to right end - m_chat_backend.getPrompt().cursorOperation( + prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); @@ -280,7 +281,7 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) case KEY_TAB: // Tab pressed // Nick completion - m_chat_backend.getPrompt().nickCompletion(m_nicks, false); + prompt.nickCompletion(m_nicks, false); break; default: // Add character to the prompt, @@ -296,11 +297,11 @@ void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) m_pending_utf8_bytes = ""; // hopefully only one char in the wstring... for (size_t i = 0; i < w.size(); i++) { - m_chat_backend.getPrompt().input(w.c_str()[i]); + prompt.input(w.c_str()[i]); } } } else if (IS_ASCII_PRINTABLE_CHAR(ch)) { - m_chat_backend.getPrompt().input(ch); + prompt.input(ch); } else { // Silently ignore characters we don't handle