X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2FguiChatConsole.cpp;h=d59937c31df3f9367218e88c2600c3ddfb30a833;hb=48a718e715710c9cb7edd6ad8e1cd7a0ed416908;hp=5fc576cf8315f83c8a5b6268a83b79c507c43660;hpb=a0566270d9fa075afa36a7e3e68c690b1b23ba90;p=dragonfireclient.git diff --git a/src/guiChatConsole.cpp b/src/guiChatConsole.cpp index 5fc576cf8..d59937c31 100644 --- a/src/guiChatConsole.cpp +++ b/src/guiChatConsole.cpp @@ -24,13 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettime.h" #include "keycode.h" #include "settings.h" -#include "main.h" // for g_settings #include "porting.h" -#include "tile.h" -#include "IGUIFont.h" -#include - +#include "client/tile.h" +#include "fontengine.h" +#include "log.h" #include "gettext.h" +#include #if USE_FREETYPE #include "xCGUITTFont.h" @@ -47,15 +46,18 @@ GUIChatConsole::GUIChatConsole( gui::IGUIElement* parent, s32 id, ChatBackend* backend, - Client* client + Client* client, + IMenuManager* menumgr ): IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, core::rect(0,0,100,100)), m_chat_backend(backend), m_client(client), + m_menumgr(menumgr), 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), @@ -72,45 +74,34 @@ GUIChatConsole::GUIChatConsole( m_animate_time_old = getTimeMs(); // load background settings - bool console_color_set = !g_settings->get("console_color").empty(); s32 console_alpha = g_settings->getS32("console_alpha"); + m_background_color.setAlpha(clamp_u8(console_alpha)); // load the background texture depending on settings - m_background_color.setAlpha(clamp_u8(console_alpha)); - if (console_color_set) - { + ITextureSource *tsrc = client->getTextureSource(); + if (tsrc->isKnownSourceImage("background_chat.jpg")) { + m_background = tsrc->getTexture("background_chat.jpg"); + m_background_color.setRed(255); + m_background_color.setGreen(255); + m_background_color.setBlue(255); + } else { v3f console_color = g_settings->getV3F("console_color"); m_background_color.setRed(clamp_u8(myround(console_color.X))); m_background_color.setGreen(clamp_u8(myround(console_color.Y))); m_background_color.setBlue(clamp_u8(myround(console_color.Z))); } - else - { - m_background = env->getVideoDriver()->getTexture(getTexturePath("background_chat.jpg").c_str()); - m_background_color.setRed(255); - m_background_color.setGreen(255); - m_background_color.setBlue(255); - } - // load the font - // FIXME should a custom texture_path be searched too? - #if USE_FREETYPE - std::string font_name = g_settings->get("mono_font_path"); - u16 font_size = g_settings->getU16("mono_font_size"); - m_font = gui::CGUITTFont::createTTFont(env, font_name.c_str(), font_size); - #else - std::string font_name = "fontdejavusansmono.png"; - m_font = env->getFont(getTexturePath(font_name).c_str()); - #endif + m_font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED, FM_Mono); + if (m_font == NULL) { - dstream << "Unable to load font: " << font_name << std::endl; + errorstream << "GUIChatConsole: Unable to load mono font "; } else { core::dimension2d dim = m_font->getDimension(L"M"); m_fontsize = v2u32(dim.Width, dim.Height); - dstream << "Font size: " << m_fontsize.X << " " << m_fontsize.Y << std::endl; + m_font->grab(); } m_fontsize.X = MYMAX(m_fontsize.X, 1); m_fontsize.Y = MYMAX(m_fontsize.Y, 1); @@ -121,6 +112,8 @@ GUIChatConsole::GUIChatConsole( GUIChatConsole::~GUIChatConsole() { + if (m_font) + m_font->drop(); } void GUIChatConsole::openConsole(f32 height) @@ -129,6 +122,13 @@ void GUIChatConsole::openConsole(f32 height) m_desired_height_fraction = height; m_desired_height = height * m_screensize.Y; reformatConsole(); + Environment->setFocus(this); + m_menumgr->createdMenu(this); +} + +bool GUIChatConsole::isOpen() const +{ + return m_open; } bool GUIChatConsole::isOpenInhibited() const @@ -139,11 +139,13 @@ bool GUIChatConsole::isOpenInhibited() const void GUIChatConsole::closeConsole() { m_open = false; + Environment->removeFocus(this); + m_menumgr->deletingMenu(this); } void GUIChatConsole::closeConsoleAtOnce() { - m_open = false; + closeConsole(); m_height = 0; recalculateConsolePosition(); } @@ -153,6 +155,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) { @@ -367,13 +377,15 @@ void GUIChatConsole::drawPrompt() s32 cursor_pos = prompt.getVisibleCursorPosition(); if (cursor_pos >= 0) { + s32 cursor_len = prompt.getCursorLength(); video::IVideoDriver* driver = Environment->getVideoDriver(); s32 x = (1 + cursor_pos) * m_fontsize.X; core::rect destrect( x, - y + (1.0-m_cursor_height) * m_fontsize.Y, - x + m_fontsize.X, - y + m_fontsize.Y); + y + m_fontsize.Y * (1.0 - m_cursor_height), + x + m_fontsize.X * MYMAX(cursor_len, 1), + y + m_fontsize.Y * (cursor_len ? m_cursor_height+1 : 1) + ); video::SColor cursor_color(255,255,255,255); driver->draw2DRectangle( cursor_color, @@ -386,23 +398,27 @@ 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 if(KeyPress(event.KeyInput) == getKeySetting("keymap_console")) { closeConsole(); - Environment->removeFocus(this); // 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) @@ -417,57 +433,50 @@ 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(); + 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) + else if(event.KeyInput.Key == KEY_LEFT || event.KeyInput.Key == KEY_RIGHT) { - // Left or Ctrl-Left pressed - // move character / word to the left - ChatPrompt::CursorOpScope scope = - event.KeyInput.Control ? - ChatPrompt::CURSOROP_SCOPE_WORD : - ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( - ChatPrompt::CURSOROP_MOVE, - ChatPrompt::CURSOROP_DIR_LEFT, - scope); - return true; - } - else if(event.KeyInput.Key == KEY_RIGHT) - { - // Right or Ctrl-Right pressed - // move character / word to the right - ChatPrompt::CursorOpScope scope = - event.KeyInput.Control ? + // Left/right pressed + // Move/select character/word to the left depending on control and shift keys + ChatPrompt::CursorOp op = event.KeyInput.Shift ? + ChatPrompt::CURSOROP_SELECT : + ChatPrompt::CURSOROP_MOVE; + ChatPrompt::CursorOpDir dir = event.KeyInput.Key == KEY_LEFT ? + ChatPrompt::CURSOROP_DIR_LEFT : + ChatPrompt::CURSOROP_DIR_RIGHT; + ChatPrompt::CursorOpScope scope = event.KeyInput.Control ? ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CURSOROP_SCOPE_CHARACTER; - m_chat_backend->getPrompt().cursorOperation( - ChatPrompt::CURSOROP_MOVE, - ChatPrompt::CURSOROP_DIR_RIGHT, - scope); + prompt.cursorOperation(op, dir, scope); return true; } else if(event.KeyInput.Key == 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); @@ -477,7 +486,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); @@ -491,7 +500,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); @@ -505,17 +514,72 @@ 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); return true; } + else if(event.KeyInput.Key == KEY_KEY_A && event.KeyInput.Control) + { + // Ctrl-A pressed + // Select all text + prompt.cursorOperation( + ChatPrompt::CURSOROP_SELECT, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_C && event.KeyInput.Control) + { + // Ctrl-C pressed + // Copy text to clipboard + if (prompt.getCursorLength() <= 0) + return true; + std::wstring wselected = prompt.getSelection(); + std::string selected(wselected.begin(), wselected.end()); + Environment->getOSOperator()->copyToClipboard(selected.c_str()); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_V && event.KeyInput.Control) + { + // Ctrl-V pressed + // paste text from clipboard + if (prompt.getCursorLength() > 0) { + // Delete selected section of text + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_SELECTION); + } + IOSOperator *os_operator = Environment->getOSOperator(); + const c8 *text = os_operator->getTextFromClipboard(); + if (!text) + return true; + std::basic_string str((const unsigned char*)text); + prompt.input(std::wstring(str.begin(), str.end())); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_X && event.KeyInput.Control) + { + // Ctrl-X pressed + // Cut text to clipboard + if (prompt.getCursorLength() <= 0) + return true; + std::wstring wselected = prompt.getSelection(); + std::string selected(wselected.begin(), wselected.end()); + Environment->getOSOperator()->copyToClipboard(selected.c_str()); + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_SELECTION); + 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); @@ -525,7 +589,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); @@ -535,14 +599,20 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // Tab or Shift-Tab pressed // Nick completion - std::list names = m_client->getConnectedPlayerNames(); + 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) { - m_chat_backend->getPrompt().input(event.KeyInput.Char); + #if (defined(linux) || defined(__linux)) + wchar_t wc = L'_'; + mbtowc( &wc, (char *) &event.KeyInput.Char, sizeof(event.KeyInput.Char) ); + prompt.input(wc); + #else + prompt.input(event.KeyInput.Char); + #endif return true; } }