1 #ifndef _LinkText_h_ 2 #define _LinkText_h_ 3 4 #include <GG/TextControl.h> 5 6 #include <boost/signals2/signal.hpp> 7 8 9 /// A class that can be subclassed to give types of links decorations in link text. 10 /// "Decorations" here mean mostly wrapping the text in some styling tag or other, 11 /// but a decorator is free to manipulate the decorated text in any way. 12 class LinkDecorator { 13 public: 14 /** \name Structors */ //@{ LinkDecorator()15 LinkDecorator() {}; ~LinkDecorator()16 virtual ~LinkDecorator() {}; 17 //@} 18 19 /// Gets called for each link of the type this decorator is assigned to. 20 /// The return value is shown to the user as the link. 21 /// The default implementation wraps content in an rgba tag that colors it by ClientUI::DefaultLinkColor 22 /// \param target The target of the link. Usually an id of something or the name of an encyclopedia entry. 23 /// \param content The text the link tag was wrapped around. 24 /// \returns The text that should be shown to the user in the place of content 25 virtual std::string Decorate(const std::string& target, const std::string& content) const; 26 27 /// Gets called when the mouse hovers over a link of the type this decorator is assigned to. 28 /// The return value is shown to the user as the link. 29 /// The default implementation wraps content in an rgba tag that colors it by ClientUI::RolloverLinkColor 30 /// \param target The target of the link. Usually an id of something or the name of an encyclopedia entry. 31 /// \param content The text the link tag was wrapped around. 32 /// \returns The text that should be shown to the user in the place of content 33 virtual std::string DecorateRollover(const std::string& target, const std::string& content) const; 34 35 protected: 36 /// Try to convert str to int. Returns -1 if \param str conversion to an 37 /// int fails. Helper for interpreting \param str as an ID of an object 38 /// in the game universe. 39 static int CastStringToInt(const std::string& str); 40 }; 41 42 // Should be unique_ptr, but we don't have c++11 43 typedef std::shared_ptr<LinkDecorator> LinkDecoratorPtr; 44 45 class ColorByOwner: public LinkDecorator { 46 public: 47 std::string Decorate(const std::string& object_id_str, const std::string& content) const override; 48 }; 49 50 class PathTypeDecorator : public LinkDecorator { 51 public: 52 std::string Decorate(const std::string& path_type, const std::string& content) const override; 53 std::string DecorateRollover(const std::string& path_type, const std::string& content) const override; 54 }; 55 56 class TextLinker { 57 public: 58 /** \name Structors */ //@{ 59 TextLinker(); 60 virtual ~TextLinker(); 61 //@} 62 63 /// Sets the link decorator for a link type. 64 /// \param link_type The link type (tag) to be decorated. Eg. "planet" 65 /// \param decorator The decorator to use. Assumes ownership. 66 void SetDecorator(const std::string& link_type, LinkDecorator* decorator); 67 68 ///< link clicked signals: first string is the link type, second string is the specific item clicked 69 mutable boost::signals2::signal<void (const std::string&, const std::string&)> LinkClickedSignal; 70 mutable boost::signals2::signal<void (const std::string&, const std::string&)> LinkDoubleClickedSignal; 71 mutable boost::signals2::signal<void (const std::string&, const std::string&)> LinkRightClickedSignal; 72 73 static const std::string ENCYCLOPEDIA_TAG; 74 static const std::string GRAPH_TAG; 75 static const std::string URL_TAG; 76 /** Tag for clickable link to open users file manager at a specified directory */ 77 static const std::string BROWSE_PATH_TAG; 78 79 protected: 80 void Render_(); 81 void LClick_(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys); 82 void RClick_(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys); 83 void LDoubleClick_(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys); 84 void MouseHere_(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys); 85 void MouseLeave_(); 86 87 virtual const std::vector<GG::Font::LineData>& GetLineData() const = 0; 88 virtual const std::shared_ptr<GG::Font>& GetFont() const = 0; 89 90 virtual GG::Pt TextUpperLeft() const = 0; 91 virtual GG::Pt TextLowerRight() const = 0; 92 virtual void SetLinkedText(const std::string& str) = 0; 93 virtual const std::string& RawText() const = 0; ///< returns text being displayed before any link formatting is added 94 95 void FindLinks(); ///< finds the links in the text, with which to populate m_links. 96 void LocateLinks(); ///< calculates the physical locations of the links in m_links 97 void MarkLinks(); ///< wraps text for each link in text formatting tags so that the links appear visually distinct from other text 98 int GetLinkUnderPt(const GG::Pt& pt); ///< returns the index of the link under screen coordinate \a pt, or -1 if none 99 private: 100 struct Link; 101 102 std::string LinkDefaultFormatTag(const Link& link, const std::string& content) const; 103 std::string LinkRolloverFormatTag(const Link& link, const std::string& content) const; 104 105 std::vector<Link> m_links; 106 int m_rollover_link; 107 std::map<std::string, LinkDecoratorPtr> m_decorators; 108 static const LinkDecorator DEFAULT_DECORATOR; 109 }; 110 111 /** Allows text that the user sees to emit signals when clicked, and indicates 112 * to the user visually which text represents a link. There is one type of 113 * signal for each type of ZoomTo*() method in ClientUI. This allows any text 114 * that refers to game elements to be tagged as such and clicked by the user, 115 * with the appropriate ClientUI response function called. 116 * The followig tags are currently supported: 117 * \verbatim 118 * <planet ID> 119 * <system ID> 120 * <fleet ID> 121 * <ship ID> 122 * <building ID> 123 * <empire ID> 124 * <tech [string]> 125 * <buildingtype [string]> 126 * <special [string]> 127 * <shiphull [string]> 128 * <shippart [string]> 129 * <species [string]> 130 * <encyclopedia [string]>\endverbatim 131 * The ID parameters refer to the UniverseObjects that should be zoomed to for 132 * each link. Encyclopedia entries and content items are referred to by strings. 133 * <br><br>Note that for link tags to be correctly handled, they must not 134 * overlap each other at all, even though overlap with regular GG::Font tags 135 * is fine. */ 136 class LinkText : public GG::TextControl, public TextLinker { 137 public: 138 /** \name Structors */ //@{ 139 LinkText(GG::X x, GG::Y y, GG::X w, const std::string& str, const std::shared_ptr<GG::Font>& font, GG::Flags<GG::TextFormat> format = GG::FORMAT_NONE, GG::Clr color = GG::CLR_BLACK); ///< ctor taking a font directly 140 141 /** ctor that does not require window size. 142 Window size is determined from the string and font; the window will be large enough to fit the text as rendered, 143 and no larger. \see DynamicText::DynamicText() */ 144 LinkText(GG::X x, GG::Y y, const std::string& str, const std::shared_ptr<GG::Font>& font, GG::Clr color = GG::CLR_BLACK); 145 //@} 146 147 /** \name Accessors */ //@{ 148 GG::Pt TextUpperLeft() const override; 149 GG::Pt TextLowerRight() const override; 150 151 const std::vector<GG::Font::LineData>& GetLineData() const override; 152 const std::shared_ptr<GG::Font>& GetFont() const override; 153 154 /** Returns text displayed before link formatting is added. */ 155 const std::string& RawText() const override; 156 //@} 157 158 /** \name Mutators */ //@{ 159 void Render() override; 160 void LClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override; 161 void RClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override; 162 void MouseHere(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) override; 163 void MouseLeave() override; 164 void SizeMove(const GG::Pt& ul, const GG::Pt& lr) override; 165 166 /** sets the text to \a str; may resize the window. If the window was 167 constructed to fit the size of the text (i.e. if the second ctor type 168 was used), calls to this function cause the window to be resized to 169 whatever space the newly rendered text occupies. */ 170 void SetText(const std::string& str) override; 171 //@} 172 173 private: 174 void SetLinkedText(const std::string& str) override; 175 176 std::string m_raw_text; 177 }; 178 179 180 /// Helper for generating a link string with content from a stringtable entry 181 std::string LinkTaggedText(const std::string& tag, const std::string& stringtable_entry); 182 183 /// Helper for generating a link string 184 std::string LinkTaggedIDText(const std::string& tag, int id, const std::string& text); 185 186 /// Helper for generating a link string with preset display text (not to be looked up in stringtable) 187 std::string LinkTaggedPresetText(const std::string& tag, const std::string& stringtable_entry, const std::string& display_text); 188 189 /// Free function to register link tags that TextLinker knows of. This allows GG::Font to remove 190 /// them so that they will not be rendered. Must be called at least once before text with embedded 191 /// XML tags is handled by GG::Font 192 void RegisterLinkTags(); 193 194 #endif // _LinkText_h_ 195