]> git.lizzy.rs Git - minetest.git/blob - src/gui/guiHyperText.h
Add crosshair support for Android (#7865)
[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 <vector>
23 #include <list>
24 #include <unordered_map>
25 #include <string>
26 #include "irrlichttypes_extrabloated.h"
27
28 using namespace irr;
29
30 class ISimpleTextureSource;
31 class Client;
32 class GUIScrollBar;
33
34 class ParsedText
35 {
36 public:
37         ParsedText(const wchar_t *text);
38         ~ParsedText();
39
40         enum ElementType
41         {
42                 ELEMENT_TEXT,
43                 ELEMENT_SEPARATOR,
44                 ELEMENT_IMAGE,
45                 ELEMENT_ITEM
46         };
47
48         enum BackgroundType
49         {
50                 BACKGROUND_NONE,
51                 BACKGROUND_COLOR
52         };
53
54         enum FloatType
55         {
56                 FLOAT_NONE,
57                 FLOAT_RIGHT,
58                 FLOAT_LEFT
59         };
60
61         enum HalignType
62         {
63                 HALIGN_CENTER,
64                 HALIGN_LEFT,
65                 HALIGN_RIGHT,
66                 HALIGN_JUSTIFY
67         };
68
69         enum ValignType
70         {
71                 VALIGN_MIDDLE,
72                 VALIGN_TOP,
73                 VALIGN_BOTTOM
74         };
75
76         typedef std::unordered_map<std::string, std::string> StyleList;
77         typedef std::unordered_map<std::string, std::string> AttrsList;
78
79         struct Tag
80         {
81                 std::string name;
82                 AttrsList attrs;
83                 StyleList style;
84         };
85
86         struct Element
87         {
88                 std::list<Tag *> tags;
89                 ElementType type;
90                 core::stringw text = "";
91
92                 core::dimension2d<u32> dim;
93                 core::position2d<s32> pos;
94                 s32 drawwidth;
95
96                 FloatType floating = FLOAT_NONE;
97
98                 ValignType valign;
99
100                 gui::IGUIFont *font;
101
102                 irr::video::SColor color;
103                 irr::video::SColor hovercolor;
104                 bool underline;
105
106                 s32 baseline = 0;
107
108                 // img & item specific attributes
109                 std::string name;
110                 v3s16 angle{0, 0, 0};
111                 v3s16 rotation{0, 0, 0};
112
113                 s32 margin = 10;
114
115                 void setStyle(StyleList &style);
116         };
117
118         struct Paragraph
119         {
120                 std::vector<Element> elements;
121                 HalignType halign;
122                 s32 margin = 10;
123
124                 void setStyle(StyleList &style);
125         };
126
127         std::vector<Paragraph> m_paragraphs;
128
129         // Element style
130         s32 margin = 3;
131         ValignType valign = VALIGN_TOP;
132         BackgroundType background_type = BACKGROUND_NONE;
133         irr::video::SColor background_color;
134
135         Tag m_root_tag;
136
137 protected:
138         typedef enum { ER_NONE, ER_TAG, ER_NEWLINE } EndReason;
139
140         // Parser functions
141         void enterElement(ElementType type);
142         void endElement();
143         void enterParagraph();
144         void endParagraph(EndReason reason);
145         void pushChar(wchar_t c);
146         ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs);
147         ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs);
148         bool closeTag(const std::string &name);
149         void parseGenericStyleAttr(const std::string &name, const std::string &value,
150                         StyleList &style);
151         void parseStyles(const AttrsList &attrs, StyleList &style);
152         void globalTag(const ParsedText::AttrsList &attrs);
153         u32 parseTag(const wchar_t *text, u32 cursor);
154         void parse(const wchar_t *text);
155
156         std::unordered_map<std::string, StyleList> m_elementtags;
157         std::unordered_map<std::string, StyleList> m_paragraphtags;
158
159         std::vector<Tag *> m_not_root_tags;
160         std::list<Tag *> m_active_tags;
161
162         // Current values
163         StyleList m_style;
164         Element *m_element;
165         Paragraph *m_paragraph;
166         bool m_empty_paragraph;
167         EndReason m_end_paragraph_reason;
168 };
169
170 class TextDrawer
171 {
172 public:
173         TextDrawer(const wchar_t *text, Client *client, gui::IGUIEnvironment *environment,
174                         ISimpleTextureSource *tsrc);
175
176         void place(const core::rect<s32> &dest_rect);
177         inline s32 getHeight() { return m_height; };
178         void draw(const core::rect<s32> &clip_rect,
179                         const core::position2d<s32> &dest_offset);
180         ParsedText::Element *getElementAt(core::position2d<s32> pos);
181         ParsedText::Tag *m_hovertag;
182
183 protected:
184         struct RectWithMargin
185         {
186                 core::rect<s32> rect;
187                 s32 margin;
188         };
189
190         ParsedText m_text;
191         Client *m_client;
192         gui::IGUIEnvironment *m_environment;
193         s32 m_height;
194         s32 m_voffset;
195         std::vector<RectWithMargin> m_floating;
196 };
197
198 class GUIHyperText : public gui::IGUIElement
199 {
200 public:
201         //! constructor
202         GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment,
203                         gui::IGUIElement *parent, s32 id,
204                         const core::rect<s32> &rectangle, Client *client,
205                         ISimpleTextureSource *tsrc);
206
207         //! destructor
208         virtual ~GUIHyperText();
209
210         //! draws the element and its children
211         virtual void draw();
212
213         core::dimension2du getTextDimension();
214
215         bool OnEvent(const SEvent &event);
216
217 protected:
218         // GUI members
219         Client *m_client;
220         GUIScrollBar *m_vscrollbar;
221         TextDrawer m_drawer;
222
223         // Positioning
224         u32 m_scrollbar_width;
225         core::rect<s32> m_display_text_rect;
226         core::position2d<s32> m_text_scrollpos;
227
228         ParsedText::Element *getElementAt(s32 X, s32 Y);
229         void checkHover(s32 X, s32 Y);
230 };