]> git.lizzy.rs Git - dragonfireclient.git/blob - src/irrlicht_changes/static_text.h
StaticText/EnrichedString: Styling support (#9187)
[dragonfireclient.git] / src / irrlicht_changes / static_text.h
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // Copyright (C) 2016 NathanaĆ«l Courant
3 //   Modified this class to work with EnrichedStrings too
4 // This file is part of the "Irrlicht Engine".
5 // For conditions of distribution and use, see copyright notice in irrlicht.h
6
7 #pragma once
8
9 #include "IrrCompileConfig.h"
10 #ifdef _IRR_COMPILE_WITH_GUI_
11
12 #include "IGUIStaticText.h"
13 #include "irrArray.h"
14
15 #include "log.h"
16
17 #include <vector>
18
19 #include "util/enriched_string.h"
20 #include "config.h"
21 #include <IGUIEnvironment.h>
22
23 #if USE_FREETYPE
24
25 namespace irr
26 {
27
28 namespace gui
29 {
30
31         const EGUI_ELEMENT_TYPE EGUIET_ENRICHED_STATIC_TEXT = (EGUI_ELEMENT_TYPE)(0x1000);
32
33         class StaticText : public IGUIStaticText
34         {
35         public:
36
37                 // StaticText is translated by EnrichedString.
38                 // No need to use translate_string()
39                 StaticText(const EnrichedString &text, bool border, IGUIEnvironment* environment,
40                         IGUIElement* parent, s32 id, const core::rect<s32>& rectangle,
41                         bool background = false);
42
43                 //! destructor
44                 virtual ~StaticText();
45
46                 static irr::gui::IGUIStaticText *add(
47                         irr::gui::IGUIEnvironment *guienv,
48                         const EnrichedString &text,
49                         const core::rect< s32 > &rectangle,
50                         bool border = false,
51                         bool wordWrap = true,
52                         irr::gui::IGUIElement *parent = NULL,
53                         s32 id = -1,
54                         bool fillBackground = false)
55                 {
56                         if (parent == NULL) {
57                                 // parent is NULL, so we must find one, or we need not to drop
58                                 // result, but then there will be a memory leak.
59                                 //
60                                 // What Irrlicht does is to use guienv as a parent, but the problem
61                                 // is that guienv is here only an IGUIEnvironment, while it is a
62                                 // CGUIEnvironment in Irrlicht, which inherits from both IGUIElement
63                                 // and IGUIEnvironment.
64                                 //
65                                 // A solution would be to dynamic_cast guienv to a
66                                 // IGUIElement*, but Irrlicht is shipped without rtti support
67                                 // in some distributions, causing the dymanic_cast to segfault.
68                                 //
69                                 // Thus, to find the parent, we create a dummy StaticText and ask
70                                 // for its parent, and then remove it.
71                                 irr::gui::IGUIStaticText *dummy_text =
72                                         guienv->addStaticText(L"", rectangle, border, wordWrap,
73                                                 parent, id, fillBackground);
74                                 parent = dummy_text->getParent();
75                                 dummy_text->remove();
76                         }
77                         irr::gui::IGUIStaticText *result = new irr::gui::StaticText(
78                                 text, border, guienv, parent,
79                                 id, rectangle, fillBackground);
80
81                         result->setWordWrap(wordWrap);
82                         result->drop();
83                         return result;
84                 }
85
86                 static irr::gui::IGUIStaticText *add(
87                         irr::gui::IGUIEnvironment *guienv,
88                         const wchar_t *text,
89                         const core::rect< s32 > &rectangle,
90                         bool border = false,
91                         bool wordWrap = true,
92                         irr::gui::IGUIElement *parent = NULL,
93                         s32 id = -1,
94                         bool fillBackground = false)
95                 {
96                         return add(guienv, EnrichedString(text), rectangle, border, wordWrap, parent,
97                                 id, fillBackground);
98                 }
99
100                 //! draws the element and its children
101                 virtual void draw();
102
103                 //! Sets another skin independent font.
104                 virtual void setOverrideFont(IGUIFont* font=0);
105
106                 //! Gets the override font (if any)
107                 virtual IGUIFont* getOverrideFont() const;
108
109                 //! Get the font which is used right now for drawing
110                 virtual IGUIFont* getActiveFont() const;
111
112                 //! Sets another color for the text.
113                 virtual void setOverrideColor(video::SColor color);
114
115                 //! Sets another color for the background.
116                 virtual void setBackgroundColor(video::SColor color);
117
118                 //! Sets whether to draw the background
119                 virtual void setDrawBackground(bool draw);
120
121                 //! Gets the background color
122                 virtual video::SColor getBackgroundColor() const;
123
124                 //! Checks if background drawing is enabled
125                 virtual bool isDrawBackgroundEnabled() const;
126
127                 //! Sets whether to draw the border
128                 virtual void setDrawBorder(bool draw);
129
130                 //! Checks if border drawing is enabled
131                 virtual bool isDrawBorderEnabled() const;
132
133                 //! Sets alignment mode for text
134                 virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical);
135
136                 //! Gets the override color
137                 #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
138                 virtual const video::SColor& getOverrideColor() const;
139                 #else
140                 virtual video::SColor getOverrideColor() const;
141                 #endif
142
143                 //! Sets if the static text should use the overide color or the
144                 //! color in the gui skin.
145                 virtual void enableOverrideColor(bool enable);
146
147                 //! Checks if an override color is enabled
148                 virtual bool isOverrideColorEnabled() const;
149
150                 //! Set whether the text in this label should be clipped if it goes outside bounds
151                 virtual void setTextRestrainedInside(bool restrainedInside);
152
153                 //! Checks if the text in this label should be clipped if it goes outside bounds
154                 virtual bool isTextRestrainedInside() const;
155
156                 //! Enables or disables word wrap for using the static text as
157                 //! multiline text control.
158                 virtual void setWordWrap(bool enable);
159
160                 //! Checks if word wrap is enabled
161                 virtual bool isWordWrapEnabled() const;
162
163                 //! Sets the new caption of this element.
164                 virtual void setText(const wchar_t* text);
165
166                 //! Returns the height of the text in pixels when it is drawn.
167                 virtual s32 getTextHeight() const;
168
169                 //! Returns the width of the current text, in the current font
170                 virtual s32 getTextWidth() const;
171
172                 //! Updates the absolute position, splits text if word wrap is enabled
173                 virtual void updateAbsolutePosition();
174
175                 //! Set whether the string should be interpreted as right-to-left (RTL) text
176                 /** \note This component does not implement the Unicode bidi standard, the
177                 text of the component should be already RTL if you call this. The
178                 main difference when RTL is enabled is that the linebreaks for multiline
179                 elements are performed starting from the end.
180                 */
181                 virtual void setRightToLeft(bool rtl);
182
183                 //! Checks if the text should be interpreted as right-to-left text
184                 virtual bool isRightToLeft() const;
185
186                 //! Writes attributes of the element.
187                 virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
188
189                 //! Reads attributes of the element
190                 virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
191
192                 virtual bool hasType(EGUI_ELEMENT_TYPE t) const {
193                         return (t == EGUIET_ENRICHED_STATIC_TEXT) || (t == EGUIET_STATIC_TEXT);
194                 };
195
196                 virtual bool hasType(EGUI_ELEMENT_TYPE t) {
197                         return (t == EGUIET_ENRICHED_STATIC_TEXT) || (t == EGUIET_STATIC_TEXT);
198                 };
199
200                 void setText(const EnrichedString &text);
201
202         private:
203
204                 //! Breaks the single text line.
205                 void updateText();
206
207                 EGUI_ALIGNMENT HAlign, VAlign;
208                 bool Border;
209                 bool WordWrap;
210                 bool Background;
211                 bool RestrainTextInside;
212                 bool RightToLeft;
213
214                 gui::IGUIFont* OverrideFont;
215                 gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated.
216
217                 EnrichedString ColoredText;
218                 std::vector<EnrichedString> BrokenText;
219         };
220
221
222 } // end namespace gui
223
224 } // end namespace irr
225
226 inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedString &text)
227 {
228         // dynamic_cast not possible due to some distributions shipped
229         // without rtti support in irrlicht
230         if (static_text->hasType(irr::gui::EGUIET_ENRICHED_STATIC_TEXT)) {
231                 irr::gui::StaticText* stext = static_cast<irr::gui::StaticText*>(static_text);
232                 stext->setText(text);
233         } else {
234                 static_text->setText(text.c_str());
235         }
236 }
237
238 #else // USE_FREETYPE
239
240 namespace irr
241 {
242 namespace gui
243 {
244
245 class StaticText
246 {
247 public:
248         static irr::gui::IGUIStaticText *add(
249                 irr::gui::IGUIEnvironment *guienv,
250                 const EnrichedString &text,
251                 const core::rect< s32 > &rectangle,
252                 bool border = false,
253                 bool wordWrap = true,
254                 irr::gui::IGUIElement *parent = NULL,
255                 s32 id = -1,
256                 bool fillBackground = false)
257         {
258                 return guienv->addStaticText(text.c_str(), rectangle, border, wordWrap, parent, id, fillBackground);
259         }
260 };
261
262 } // end namespace gui
263
264 } // end namespace irr
265
266 inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedString &text)
267 {
268         static_text->setText(text.c_str());
269 }
270
271 #endif
272
273 inline void setStaticText(irr::gui::IGUIStaticText *static_text, const wchar_t *text)
274 {
275         setStaticText(static_text, EnrichedString(text, static_text->getOverrideColor()));
276 }
277
278 #endif // _IRR_COMPILE_WITH_GUI_