]> git.lizzy.rs Git - minetest.git/blob - src/gui/guiHyperText.h
Fix core.get_player_by_name() returning unusable ObjectRef
[minetest.git] / src / gui / guiHyperText.h
1 /*
2 Minetest
3 Copyright (C) 2019 EvicenceBKidscode / Pierre-Yves Rollo <dev@pyrollo.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21
22 #include "config.h" // for USE_FREETYPE
23
24 using namespace irr;
25
26 class ISimpleTextureSource;
27 class Client;
28
29 #if USE_FREETYPE
30 #include "irrlicht_changes/CGUITTFont.h"
31 #endif
32
33 class ParsedText
34 {
35 public:
36         ParsedText(const wchar_t *text);
37         ~ParsedText();
38
39         enum ElementType
40         {
41                 ELEMENT_TEXT,
42                 ELEMENT_SEPARATOR,
43                 ELEMENT_IMAGE,
44                 ELEMENT_ITEM
45         };
46
47         enum BackgroundType
48         {
49                 BACKGROUND_NONE,
50                 BACKGROUND_COLOR
51         };
52
53         enum FloatType
54         {
55                 FLOAT_NONE,
56                 FLOAT_RIGHT,
57                 FLOAT_LEFT
58         };
59
60         enum HalignType
61         {
62                 HALIGN_CENTER,
63                 HALIGN_LEFT,
64                 HALIGN_RIGHT,
65                 HALIGN_JUSTIFY
66         };
67
68         enum ValignType
69         {
70                 VALIGN_MIDDLE,
71                 VALIGN_TOP,
72                 VALIGN_BOTTOM
73         };
74
75         typedef std::unordered_map<std::string, std::string> StyleList;
76         typedef std::unordered_map<std::string, std::string> AttrsList;
77
78         struct Tag
79         {
80                 std::string name;
81                 AttrsList attrs;
82                 StyleList style;
83         };
84
85         struct Element
86         {
87                 std::list<Tag *> tags;
88                 ElementType type;
89                 core::stringw text = "";
90
91                 core::dimension2d<u32> dim;
92                 core::position2d<s32> pos;
93                 s32 drawwidth;
94
95                 FloatType floating = FLOAT_NONE;
96
97                 ValignType valign;
98
99                 gui::IGUIFont *font;
100
101                 irr::video::SColor color;
102                 irr::video::SColor hovercolor;
103                 bool underline;
104
105                 s32 baseline = 0;
106
107                 // img & item specific attributes
108                 std::string name;
109                 v3s16 angle{0, 0, 0};
110                 v3s16 rotation{0, 0, 0};
111
112                 s32 margin = 10;
113
114                 void setStyle(StyleList &style);
115         };
116
117         struct Paragraph
118         {
119                 std::vector<Element> elements;
120                 HalignType halign;
121                 s32 margin = 10;
122
123                 void setStyle(StyleList &style);
124         };
125
126         std::vector<Paragraph> m_paragraphs;
127
128         // Element style
129         s32 margin = 3;
130         ValignType valign = VALIGN_TOP;
131         BackgroundType background_type = BACKGROUND_NONE;
132         irr::video::SColor background_color;
133
134         Tag m_root_tag;
135
136 protected:
137         // Parser functions
138         void enterElement(ElementType type);
139         void endElement();
140         void enterParagraph();
141         void endParagraph();
142         void pushChar(wchar_t c);
143         ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs);
144         ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs);
145         bool closeTag(const std::string &name);
146         void parseGenericStyleAttr(const std::string &name, const std::string &value,
147                         StyleList &style);
148         void parseStyles(const AttrsList &attrs, StyleList &style);
149         void globalTag(const ParsedText::AttrsList &attrs);
150         u32 parseTag(const wchar_t *text, u32 cursor);
151         void parse(const wchar_t *text);
152
153         std::unordered_map<std::string, StyleList> m_elementtags;
154         std::unordered_map<std::string, StyleList> m_paragraphtags;
155
156         std::vector<Tag *> m_tags;
157         std::list<Tag *> m_active_tags;
158
159         // Current values
160         StyleList m_style;
161         Element *m_element;
162         Paragraph *m_paragraph;
163 };
164
165 class TextDrawer
166 {
167 public:
168         TextDrawer(const wchar_t *text, Client *client, gui::IGUIEnvironment *environment,
169                         ISimpleTextureSource *tsrc);
170
171         void place(const core::rect<s32> &dest_rect);
172         inline s32 getHeight() { return m_height; };
173         void draw(const core::rect<s32> &dest_rect,
174                         const core::position2d<s32> &dest_offset);
175         ParsedText::Element *getElementAt(core::position2d<s32> pos);
176         ParsedText::Tag *m_hovertag;
177
178 protected:
179         struct RectWithMargin
180         {
181                 core::rect<s32> rect;
182                 s32 margin;
183         };
184
185         ParsedText m_text;
186         Client *m_client;
187         gui::IGUIEnvironment *m_environment;
188         s32 m_height;
189         s32 m_voffset;
190         std::vector<RectWithMargin> m_floating;
191 };
192
193 class GUIHyperText : public gui::IGUIElement
194 {
195 public:
196         //! constructor
197         GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment,
198                         gui::IGUIElement *parent, s32 id,
199                         const core::rect<s32> &rectangle, Client *client,
200                         ISimpleTextureSource *tsrc);
201
202         //! destructor
203         virtual ~GUIHyperText();
204
205         //! draws the element and its children
206         virtual void draw();
207
208         core::dimension2du getTextDimension();
209
210         bool OnEvent(const SEvent &event);
211
212 protected:
213         // GUI members
214         Client *m_client;
215         GUIScrollBar *m_vscrollbar;
216         TextDrawer m_drawer;
217
218         // Positioning
219         u32 m_scrollbar_width;
220         core::rect<s32> m_display_text_rect;
221         core::position2d<s32> m_text_scrollpos;
222
223         ParsedText::Element *getElementAt(s32 X, s32 Y);
224         void checkHover(s32 X, s32 Y);
225 };