Support for scalable font and gui elements
[oweals/minetest.git] / src / guiFormSpecMenu.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.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
21 #ifndef GUIINVENTORYMENU_HEADER
22 #define GUIINVENTORYMENU_HEADER
23
24 #include <utility>
25
26 #include "irrlichttypes_extrabloated.h"
27 #include "inventory.h"
28 #include "inventorymanager.h"
29 #include "modalMenu.h"
30 #include "guiTable.h"
31
32 class IGameDef;
33 class InventoryManager;
34 class ISimpleTextureSource;
35
36 typedef enum {
37         f_Button,
38         f_Table,
39         f_TabHeader,
40         f_CheckBox,
41         f_DropDown,
42         f_Unknown
43 } FormspecFieldType;
44
45 typedef enum {
46         quit_mode_no,
47         quit_mode_accept,
48         quit_mode_cancel
49 } FormspecQuitMode;
50
51 struct TextDest
52 {
53         virtual ~TextDest() {};
54         // This is deprecated I guess? -celeron55
55         virtual void gotText(std::wstring text){}
56         virtual void gotText(std::map<std::string, std::string> fields) = 0;
57         virtual void setFormName(std::string formname)
58         { m_formname = formname;};
59
60         std::string m_formname;
61 };
62
63 class IFormSource
64 {
65 public:
66         virtual ~IFormSource(){}
67         virtual std::string getForm() = 0;
68         // Fill in variables in field text
69         virtual std::string resolveText(std::string str){ return str; }
70 };
71
72 class GUIFormSpecMenu : public GUIModalMenu
73 {
74         struct ItemSpec
75         {
76                 ItemSpec()
77                 {
78                         i = -1;
79                 }
80                 ItemSpec(const InventoryLocation &a_inventoryloc,
81                                 const std::string &a_listname,
82                                 s32 a_i)
83                 {
84                         inventoryloc = a_inventoryloc;
85                         listname = a_listname;
86                         i = a_i;
87                 }
88                 bool isValid() const
89                 {
90                         return i != -1;
91                 }
92
93                 InventoryLocation inventoryloc;
94                 std::string listname;
95                 s32 i;
96         };
97
98         struct ListDrawSpec
99         {
100                 ListDrawSpec()
101                 {
102                 }
103                 ListDrawSpec(const InventoryLocation &a_inventoryloc,
104                                 const std::string &a_listname,
105                                 v2s32 a_pos, v2s32 a_geom, s32 a_start_item_i):
106                         inventoryloc(a_inventoryloc),
107                         listname(a_listname),
108                         pos(a_pos),
109                         geom(a_geom),
110                         start_item_i(a_start_item_i)
111                 {
112                 }
113
114                 InventoryLocation inventoryloc;
115                 std::string listname;
116                 v2s32 pos;
117                 v2s32 geom;
118                 s32 start_item_i;
119         };
120
121         struct ImageDrawSpec
122         {
123                 ImageDrawSpec()
124                 {
125                 }
126                 ImageDrawSpec(const std::string &a_name,
127                                 v2s32 a_pos, v2s32 a_geom):
128                         name(a_name),
129                         pos(a_pos),
130                         geom(a_geom)
131                 {
132                         scale = true;
133                 }
134                 ImageDrawSpec(const std::string &a_name,
135                                 v2s32 a_pos):
136                         name(a_name),
137                         pos(a_pos)
138                 {
139                         scale = false;
140                 }
141                 std::string name;
142                 v2s32 pos;
143                 v2s32 geom;
144                 bool scale;
145         };
146
147         struct FieldSpec
148         {
149                 FieldSpec()
150                 {
151                 }
152                 FieldSpec(const std::wstring &name, const std::wstring &label,
153                           const std::wstring &fdeflt, int id) :
154                         fname(name),
155                         flabel(label),
156                         fdefault(fdeflt),
157                         fid(id)
158                 {
159                         send = false;
160                         ftype = f_Unknown;
161                         is_exit = false;
162                         tooltip="";
163                 }
164                 std::wstring fname;
165                 std::wstring flabel;
166                 std::wstring fdefault;
167                 int fid;
168                 bool send;
169                 FormspecFieldType ftype;
170                 bool is_exit;
171                 core::rect<s32> rect;
172                 std::string tooltip;
173         };
174
175         struct BoxDrawSpec {
176                 BoxDrawSpec(v2s32 a_pos, v2s32 a_geom,irr::video::SColor a_color):
177                         pos(a_pos),
178                         geom(a_geom),
179                         color(a_color)
180                 {
181                 }
182                 v2s32 pos;
183                 v2s32 geom;
184                 irr::video::SColor color;
185         };
186
187 public:
188         GUIFormSpecMenu(irr::IrrlichtDevice* dev,
189                         gui::IGUIElement* parent, s32 id,
190                         IMenuManager *menumgr,
191                         InventoryManager *invmgr,
192                         IGameDef *gamedef,
193                         ISimpleTextureSource *tsrc,
194                         IFormSource* fs_src,
195                         TextDest* txt_dst,
196                         GUIFormSpecMenu** ext_ptr
197                         );
198
199         ~GUIFormSpecMenu();
200
201         void setFormSpec(const std::string &formspec_string,
202                         InventoryLocation current_inventory_location)
203         {
204                 m_formspec_string = formspec_string;
205                 m_current_inventory_location = current_inventory_location;
206                 regenerateGui(m_screensize_old);
207         }
208
209         // form_src is deleted by this GUIFormSpecMenu
210         void setFormSource(IFormSource *form_src)
211         {
212                 if (m_form_src != NULL) {
213                         delete m_form_src;
214                 }
215                 m_form_src = form_src;
216         }
217
218         // text_dst is deleted by this GUIFormSpecMenu
219         void setTextDest(TextDest *text_dst)
220         {
221                 if (m_text_dst != NULL) {
222                         delete m_text_dst;
223                 }
224                 m_text_dst = text_dst;
225         }
226
227         void allowClose(bool value)
228         {
229                 m_allowclose = value;
230         }
231
232         void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) {
233                 m_lock = lock;
234                 m_lockscreensize = basescreensize;
235         }
236
237         void removeChildren();
238         void setInitialFocus();
239         /*
240                 Remove and re-add (or reposition) stuff
241         */
242         void regenerateGui(v2u32 screensize);
243
244         ItemSpec getItemAtPos(v2s32 p) const;
245         void drawList(const ListDrawSpec &s, int phase);
246         void drawSelectedItem();
247         void drawMenu();
248         void updateSelectedItem();
249         ItemStack verifySelectedItem();
250
251         void acceptInput(FormspecQuitMode quitmode);
252         bool preprocessEvent(const SEvent& event);
253         bool OnEvent(const SEvent& event);
254         bool doPause;
255         bool pausesGame() { return doPause; }
256
257         GUITable* getTable(std::wstring tablename);
258
259         static bool parseColor(const std::string &value,
260                         video::SColor &color, bool quiet);
261
262 protected:
263         v2s32 getBasePos() const
264         {
265                         return padding + offset + AbsoluteRect.UpperLeftCorner;
266         }
267
268         v2s32 padding;
269         v2s32 spacing;
270         v2s32 imgsize;
271         v2s32 offset;
272
273         irr::IrrlichtDevice* m_device;
274         InventoryManager *m_invmgr;
275         IGameDef *m_gamedef;
276         ISimpleTextureSource *m_tsrc;
277
278         std::string m_formspec_string;
279         InventoryLocation m_current_inventory_location;
280
281         std::vector<ListDrawSpec> m_inventorylists;
282         std::vector<ImageDrawSpec> m_backgrounds;
283         std::vector<ImageDrawSpec> m_images;
284         std::vector<ImageDrawSpec> m_itemimages;
285         std::vector<BoxDrawSpec> m_boxes;
286         std::vector<FieldSpec> m_fields;
287         std::vector<std::pair<FieldSpec,GUITable*> > m_tables;
288         std::vector<std::pair<FieldSpec,gui::IGUICheckBox*> > m_checkboxes;
289
290         ItemSpec *m_selected_item;
291         u32 m_selected_amount;
292         bool m_selected_dragging;
293
294         // WARNING: BLACK MAGIC
295         // Used to guess and keep up with some special things the server can do.
296         // If name is "", no guess exists.
297         ItemStack m_selected_content_guess;
298         InventoryLocation m_selected_content_guess_inventory;
299
300         v2s32 m_pointer;
301         gui::IGUIStaticText *m_tooltip_element;
302
303         bool m_allowclose;
304         bool m_lock;
305         v2u32 m_lockscreensize;
306
307         bool m_bgfullscreen;
308         bool m_slotborder;
309         bool m_clipbackground;
310         video::SColor m_bgcolor;
311         video::SColor m_slotbg_n;
312         video::SColor m_slotbg_h;
313         video::SColor m_slotbordercolor;
314 private:
315         IFormSource      *m_form_src;
316         TextDest         *m_text_dst;
317         GUIFormSpecMenu **m_ext_ptr;
318         gui::IGUIFont    *m_font;
319
320         typedef struct {
321                 v2s32 size;
322                 core::rect<s32> rect;
323                 v2s32 basepos;
324                 int bp_set;
325                 v2u32 screensize;
326                 std::wstring focused_fieldname;
327                 GUITable::TableOptions table_options;
328                 GUITable::TableColumns table_columns;
329                 // used to restore table selection/scroll/treeview state
330                 std::map<std::wstring,GUITable::DynamicData> table_dyndata;
331         } parserData;
332
333         typedef struct {
334                 bool key_up;
335                 bool key_down;
336                 bool key_enter;
337                 bool key_escape;
338         } fs_key_pendig;
339
340         fs_key_pendig current_keys_pending;
341
342         void parseElement(parserData* data,std::string element);
343
344         void parseSize(parserData* data,std::string element);
345         void parseList(parserData* data,std::string element);
346         void parseCheckbox(parserData* data,std::string element);
347         void parseImage(parserData* data,std::string element);
348         void parseItemImage(parserData* data,std::string element);
349         void parseButton(parserData* data,std::string element,std::string typ);
350         void parseBackground(parserData* data,std::string element);
351         void parseTableOptions(parserData* data,std::string element);
352         void parseTableColumns(parserData* data,std::string element);
353         void parseTable(parserData* data,std::string element);
354         void parseTextList(parserData* data,std::string element);
355         void parseDropDown(parserData* data,std::string element);
356         void parsePwdField(parserData* data,std::string element);
357         void parseField(parserData* data,std::string element,std::string type);
358         void parseSimpleField(parserData* data,std::vector<std::string> &parts);
359         void parseTextArea(parserData* data,std::vector<std::string>& parts,
360                         std::string type);
361         void parseLabel(parserData* data,std::string element);
362         void parseVertLabel(parserData* data,std::string element);
363         void parseImageButton(parserData* data,std::string element,std::string type);
364         void parseItemImageButton(parserData* data,std::string element);
365         void parseTabHeader(parserData* data,std::string element);
366         void parseBox(parserData* data,std::string element);
367         void parseBackgroundColor(parserData* data,std::string element);
368         void parseListColors(parserData* data,std::string element);
369
370         /**
371          * check if event is part of a double click
372          * @param event event to evaluate
373          * @return true/false if a doubleclick was detected
374          */
375         bool DoubleClickDetection(const SEvent event);
376
377         struct clickpos
378         {
379                 v2s32 pos;
380                 s32 time;
381         };
382         clickpos m_doubleclickdetect[2];
383
384         int m_btn_height;
385 };
386
387 class FormspecFormSource: public IFormSource
388 {
389 public:
390         FormspecFormSource(std::string formspec)
391         {
392                 m_formspec = formspec;
393         }
394
395         ~FormspecFormSource()
396         {}
397
398         void setForm(std::string formspec) {
399                 m_formspec = formspec;
400         }
401
402         std::string getForm()
403         {
404                 return m_formspec;
405         }
406
407         std::string m_formspec;
408 };
409
410 #endif
411