Index: binaries/data/mods/mod/gui/gui.rnc =================================================================== --- binaries/data/mods/mod/gui/gui.rnc +++ binaries/data/mods/mod/gui/gui.rnc @@ -68,6 +68,7 @@ attribute maxwidth { xsd:decimal }? & attribute multiline { bool }?& attribute offset { pos }?& + attribute readonly { bool }?& attribute scrollbar { bool }?& attribute scrollbar_style { text }?& attribute scroll_bottom { bool }?& Index: binaries/data/mods/mod/gui/gui.rng =================================================================== --- binaries/data/mods/mod/gui/gui.rng +++ binaries/data/mods/mod/gui/gui.rng @@ -277,6 +277,11 @@ + + + + + Index: binaries/data/mods/public/gui/replaymenu/replay_menu.js =================================================================== --- binaries/data/mods/public/gui/replaymenu/replay_menu.js +++ binaries/data/mods/public/gui/replaymenu/replay_menu.js @@ -271,7 +271,7 @@ Engine.GetGUIObjectByName("sgVictory").caption = translateVictoryCondition(replay.attribs.settings.GameType); Engine.GetGUIObjectByName("sgNbPlayers").caption = sprintf(translate("Players: %(numberOfPlayers)s"), { "numberOfPlayers": replay.attribs.settings.PlayerData.length }); - Engine.GetGUIObjectByName("replayFilename").caption = escapeText(Engine.GetReplayDirectoryName(replay.directory)); + Engine.GetGUIObjectByName("replayFilename").caption = Engine.GetReplayDirectoryName(replay.directory); let metadata = Engine.GetReplayMetadata(replay.directory); Engine.GetGUIObjectByName("sgPlayersNames").caption = Index: binaries/data/mods/public/gui/replaymenu/replay_menu.xml =================================================================== --- binaries/data/mods/public/gui/replaymenu/replay_menu.xml +++ binaries/data/mods/public/gui/replaymenu/replay_menu.xml @@ -109,7 +109,7 @@ - + Index: source/gui/CInput.h =================================================================== --- source/gui/CInput.h +++ source/gui/CInput.h @@ -174,6 +174,8 @@ /// If the cursor should be drawn or not. bool m_CursorVisState; + + bool m_Readonly; }; #endif // INCLUDED_CINPUT Index: source/gui/CInput.cpp =================================================================== --- source/gui/CInput.cpp +++ source/gui/CInput.cpp @@ -44,7 +44,7 @@ CInput::CInput() : m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(false), m_HorizontalScroll(0.f), m_PrevTime(0.0), m_CursorVisState(true), m_CursorBlinkRate(0.5), m_ComposingText(false), - m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0) + m_iComposedLength(0), m_iComposedPos(0), m_iInsertPos(0), m_Readonly(false) { AddSetting(GUIST_int, "buffer_position"); AddSetting(GUIST_float, "buffer_zone"); @@ -55,6 +55,7 @@ AddSetting(GUIST_bool, "mask"); AddSetting(GUIST_int, "max_length"); AddSetting(GUIST_bool, "multiline"); + AddSetting(GUIST_bool, "readonly"); AddSetting(GUIST_bool, "scrollbar"); AddSetting(GUIST_CStr, "scrollbar_style"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); @@ -96,6 +97,10 @@ { ENSURE(m_iBufferPos != -1); + // Readonly mode allows to use only mouse to select and keyboard to copy the text + if (m_Readonly && ev->ev.type != SDL_HOTKEYDOWN) + return IN_PASS; + if (ev->ev.type == SDL_HOTKEYDOWN) { if (m_ComposingText) @@ -534,7 +539,9 @@ bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; std::string hotkey = static_cast(ev->ev.user.data1); - if (hotkey == "paste") + if (m_Readonly && hotkey != "copy") + return IN_PASS; + else if (hotkey == "paste") { m_WantedX = 0.0f; @@ -847,6 +854,9 @@ UpdateText(); } UpdateAutoScroll(); + + if (Message.value == CStr("readonly")) + GUI::GetSetting(this, "readonly", m_Readonly); break; } @@ -1031,6 +1041,8 @@ UpdateText(); UpdateAutoScroll(); + + GUI::GetSetting(this, "readonly", m_Readonly); break; }