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