]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/guiChatConsole.cpp
Make nametag removable with set_nametag_attributes (#5021)
[dragonfireclient.git] / src / guiChatConsole.cpp
index 4c0039e5ea827c96549ccc9c36e7769b7ea4d40b..86757617532fe086e7287c65d01585ae04ae2c47 100644 (file)
@@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 
 #if USE_FREETYPE
-#include "xCGUITTFont.h"
+       #include "xCGUITTFont.h"
 #endif
 
 inline u32 clamp_u8(s32 value)
@@ -46,12 +46,14 @@ GUIChatConsole::GUIChatConsole(
                gui::IGUIElement* parent,
                s32 id,
                ChatBackend* backend,
-               Client* client
+               Client* client,
+               IMenuManager* menumgr
 ):
        IGUIElement(gui::EGUIET_ELEMENT, env, parent, id,
                        core::rect<s32>(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),
@@ -120,6 +122,10 @@ void GUIChatConsole::openConsole(f32 height)
        m_desired_height_fraction = height;
        m_desired_height = height * m_screensize.Y;
        reformatConsole();
+       m_animate_time_old = getTimeMs();
+       IGUIElement::setVisible(true);
+       Environment->setFocus(this);
+       m_menumgr->createdMenu(this);
 }
 
 bool GUIChatConsole::isOpen() const
@@ -135,11 +141,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();
 }
@@ -237,6 +245,13 @@ void GUIChatConsole::animate(u32 msec)
 {
        // animate the console height
        s32 goal = m_open ? m_desired_height : 0;
+
+       // Set invisible if close animation finished (reset by openConsole)
+       // This function (animate()) is never called once its visibility becomes false so do not
+       //              actually set visible to false before the inhibited period is over
+       if (!m_open && m_height == 0 && m_open_inhibited == 0)
+               IGUIElement::setVisible(false);
+
        if (m_height != goal)
        {
                s32 max_change = msec * m_screensize.Y * (m_height_speed / 1000.0);
@@ -325,13 +340,28 @@ void GUIChatConsole::drawText()
                        s32 x = (fragment.column + 1) * m_fontsize.X;
                        core::rect<s32> destrect(
                                x, y, x + m_fontsize.X * fragment.text.size(), y + m_fontsize.Y);
-                       m_font->draw(
-                               fragment.text.c_str(),
-                               destrect,
-                               video::SColor(255, 255, 255, 255),
-                               false,
-                               false,
-                               &AbsoluteClippingRect);
+
+
+                       #if USE_FREETYPE
+                       // Draw colored text if FreeType is enabled
+                               irr::gui::CGUITTFont *tmp = static_cast<irr::gui::CGUITTFont*>(m_font);
+                               tmp->draw(
+                                       fragment.text,
+                                       destrect,
+                                       video::SColor(255, 255, 255, 255),
+                                       false,
+                                       false,
+                                       &AbsoluteClippingRect);
+                       #else
+                       // Otherwise use standard text
+                               m_font->draw(
+                                       fragment.text.c_str(),
+                                       destrect,
+                                       video::SColor(255, 255, 255, 255),
+                                       false,
+                                       false,
+                                       &AbsoluteClippingRect);
+                       #endif
                }
        }
 }
@@ -371,13 +401,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<s32> 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,
@@ -399,7 +431,6 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                if(KeyPress(event.KeyInput) == getKeySetting("keymap_console"))
                {
                        closeConsole();
-                       Environment->removeFocus(this);
 
                        // inhibit open so the_game doesn't reopen immediately
                        m_open_inhibited = 50;
@@ -409,7 +440,6 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                else if(event.KeyInput.Key == KEY_ESCAPE)
                {
                        closeConsoleAtOnce();
-                       Environment->removeFocus(this);
                        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"
@@ -432,7 +462,6 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                        m_client->typeChatMessage(text);
                        if (m_close_on_enter) {
                                closeConsoleAtOnce();
-                               Environment->removeFocus(this);
                                m_close_on_enter = false;
                        }
                        return true;
@@ -451,32 +480,20 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                        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;
-                       prompt.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;
-                       prompt.cursorOperation(
-                               ChatPrompt::CURSOROP_MOVE,
-                               ChatPrompt::CURSOROP_DIR_RIGHT,
-                               scope);
+                       prompt.cursorOperation(op, dir, scope);
                        return true;
                }
                else if(event.KeyInput.Key == KEY_HOME)
@@ -527,14 +544,59 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                                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)
-                               prompt.input(narrow_to_wide(text));
+                       if (!text)
+                               return true;
+                       std::basic_string<unsigned char> 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)
@@ -568,7 +630,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
                }
                else if(event.KeyInput.Char != 0 && !event.KeyInput.Control)
                {
-                       #if (defined(linux) || defined(__linux))
+                       #if defined(__linux__) && (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9)
                                wchar_t wc = L'_';
                                mbtowc( &wc, (char *) &event.KeyInput.Char, sizeof(event.KeyInput.Char) );
                                prompt.input(wc);
@@ -590,3 +652,13 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
        return Parent ? Parent->OnEvent(event) : false;
 }
 
+void GUIChatConsole::setVisible(bool visible)
+{
+       m_open = visible;
+       IGUIElement::setVisible(visible);
+       if (!visible) {
+               m_height = 0;
+               recalculateConsolePosition();
+       }
+}
+