diff --git a/binaries/data/mods/mod/gui/gui.rnc b/binaries/data/mods/mod/gui/gui.rnc index 7c328c681d..7360956f05 100644 --- a/binaries/data/mods/mod/gui/gui.rnc +++ b/binaries/data/mods/mod/gui/gui.rnc @@ -71,6 +71,8 @@ ex_settings = attribute maxwidth { xsd:decimal }? & attribute multiline { bool }?& attribute offset { pos }?& + attribute placeholder_text { text }?& + attribute placeholder_color { ccolor }?& attribute readonly { bool }?& attribute scrollbar { bool }?& attribute scrollbar_style { text }?& diff --git a/binaries/data/mods/mod/gui/gui.rng b/binaries/data/mods/mod/gui/gui.rng index d6daaedb4b..fc26588bc2 100644 --- a/binaries/data/mods/mod/gui/gui.rng +++ b/binaries/data/mods/mod/gui/gui.rng @@ -434,6 +434,14 @@ + + + + + + + + diff --git a/binaries/data/mods/mod/gui/modmod/modmod.js b/binaries/data/mods/mod/gui/modmod/modmod.js index 35a66b2dba..69258a30fc 100644 --- a/binaries/data/mods/mod/gui/modmod/modmod.js +++ b/binaries/data/mods/mod/gui/modmod/modmod.js @@ -104,7 +104,6 @@ function validateMods() function initGUIFilters() { Engine.GetGUIObjectByName("negateFilter").checked = false; - Engine.GetGUIObjectByName("modGenericFilter").caption = translate("Filter"); displayModLists(); } @@ -251,7 +250,6 @@ function filterMod(folder) let searchText = Engine.GetGUIObjectByName("modGenericFilter").caption; if (searchText && - searchText != translate("Filter") && folder.indexOf(searchText) == -1 && mod.name.indexOf(searchText) == -1 && mod.label.indexOf(searchText) == -1 && diff --git a/binaries/data/mods/mod/gui/modmod/modmod.xml b/binaries/data/mods/mod/gui/modmod/modmod.xml index 258030ec01..598bacd18b 100644 --- a/binaries/data/mods/mod/gui/modmod/modmod.xml +++ b/binaries/data/mods/mod/gui/modmod/modmod.xml @@ -18,9 +18,11 @@ type="input" style="ModernInput" size="16 0 176 100%" + placeholder_color="gray" > applyFilters(); applyFilters(); + Filter diff --git a/source/gui/ObjectTypes/CInput.cpp b/source/gui/ObjectTypes/CInput.cpp index a69a1aaf13..e68f0fb0c5 100644 --- a/source/gui/ObjectTypes/CInput.cpp +++ b/source/gui/ObjectTypes/CInput.cpp @@ -52,6 +52,7 @@ CInput::CInput(CGUI& pGUI) m_CursorVisState(true), m_CursorBlinkRate(0.5), m_ComposingText(), + m_GeneratedPlaceholderTextValid(false), m_iComposedLength(), m_iComposedPos(), m_iInsertPos(), @@ -88,6 +89,8 @@ CInput::CInput(CGUI& pGUI) RegisterSetting("sprite_selectarea", m_SpriteSelectArea); RegisterSetting("textcolor", m_TextColor); RegisterSetting("textcolor_selected", m_TextColorSelected); + RegisterSetting("placeholder_text", m_PlaceholderText); + RegisterSetting("placeholder_color", m_PlaceholderColor); CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate); @@ -598,6 +601,12 @@ void CInput::ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode) } } +void CInput::SetupGeneratedPlaceholderText() +{ + m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, this); + m_GeneratedPlaceholderTextValid = true; +} + InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) { bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; @@ -921,6 +930,15 @@ void CInput::HandleMessage(SGUIMessage& Message) UpdateText(); } + if (Message.value == "placeholder_text" || + Message.value == "size" || + Message.value == "font" || + Message.value == "z" || + Message.value == "text_valign") + { + m_GeneratedPlaceholderTextValid = false; + } + UpdateAutoScroll(); break; @@ -1156,6 +1174,8 @@ void CInput::UpdateCachedSize() GetScrollBar(0).SetZ(GetBufferedZ()); GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); } + + m_GeneratedPlaceholderTextValid = false; } void CInput::Draw() @@ -1500,6 +1520,17 @@ void CInput::Draw() glDisable(GL_SCISSOR_TEST); tech->EndPass(); + + if (m_Caption.empty() && !m_PlaceholderText.GetRawString().empty()) + DrawPlaceholderText(bz, cliparea); +} + +void CInput::DrawPlaceholderText(float z, const CRect& clipping) +{ + if (!m_GeneratedPlaceholderTextValid) + SetupGeneratedPlaceholderText(); + + m_GeneratedPlaceholderText.Draw(m_pGUI, m_PlaceholderColor, m_CachedActualSize.TopLeft(), z, clipping); } void CInput::UpdateText(int from, int to_before, int to_after) diff --git a/source/gui/ObjectTypes/CInput.h b/source/gui/ObjectTypes/CInput.h index e8a91b1331..3501456b0e 100644 --- a/source/gui/ObjectTypes/CInput.h +++ b/source/gui/ObjectTypes/CInput.h @@ -21,6 +21,7 @@ #include "gui/CGUISprite.h" #include "gui/ObjectBases/IGUIObject.h" #include "gui/ObjectBases/IGUIScrollBarOwner.h" +#include "gui/SettingTypes/CGUIString.h" #include "lib/external_libraries/libsdl.h" #include @@ -58,6 +59,9 @@ public: int GetXTextPosition(const std::list::const_iterator& c, const float& x, float& wanted) const; protected: + + void SetupGeneratedPlaceholderText(); + /** * @see IGUIObject#HandleMessage() */ @@ -105,6 +109,15 @@ protected: */ void UpdateText(int from = 0, int to_before = -1, int to_after = -1); + /** + * Draws the text generated for placeholder. + * + * @param z Z value + * @param clipping Clipping rectangle, don't even add a parameter + * to get no clipping. + */ + virtual void DrawPlaceholderText(float z, const CRect& clipping = CRect()); + /** * Delete the current selection. Also places the pointer at the * crack between the two segments kept. @@ -180,6 +193,13 @@ protected: */ bool m_SelectingText; + /** + * Whether the cached text is currently valid (if not then SetupText will be called by Draw) + */ + bool m_GeneratedPlaceholderTextValid; + + CGUIText m_GeneratedPlaceholderText; + // *** Things for one-line input control *** // float m_HorizontalScroll; @@ -200,6 +220,7 @@ protected: i32 m_BufferPosition; float m_BufferZone; CStrW m_Caption; + CGUIString m_PlaceholderText; i32 m_CellID; CStrW m_Font; CStrW m_MaskChar; @@ -213,6 +234,7 @@ protected: CGUISpriteInstance m_SpriteSelectArea; CGUIColor m_TextColor; CGUIColor m_TextColorSelected; + CGUIColor m_PlaceholderColor; }; #endif // INCLUDED_CINPUT