]> git.lizzy.rs Git - minetest.git/blob - src/guiFormSpecMenu.h
Fix jumping at node edge
[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(const StringMap &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 ListRingSpec
125         {
126                 ListRingSpec()
127                 {
128                 }
129                 ListRingSpec(const InventoryLocation &a_inventoryloc,
130                                 const std::string &a_listname):
131                         inventoryloc(a_inventoryloc),
132                         listname(a_listname)
133                 {
134                 }
135
136                 InventoryLocation inventoryloc;
137                 std::string listname;
138         };
139
140         struct ImageDrawSpec
141         {
142                 ImageDrawSpec():
143                         parent_button(NULL)
144                 {
145                 }
146                 ImageDrawSpec(const std::string &a_name,
147                                 const std::string &a_item_name,
148                                 gui::IGUIButton *a_parent_button,
149                                 const v2s32 &a_pos, const v2s32 &a_geom):
150                         name(a_name),
151                         item_name(a_item_name),
152                         parent_button(a_parent_button),
153                         pos(a_pos),
154                         geom(a_geom),
155                         scale(true)
156                 {
157                 }
158                 ImageDrawSpec(const std::string &a_name,
159                                 const std::string &a_item_name,
160                                 const v2s32 &a_pos, const v2s32 &a_geom):
161                         name(a_name),
162                         item_name(a_item_name),
163                         parent_button(NULL),
164                         pos(a_pos),
165                         geom(a_geom),
166                         scale(true)
167                 {
168                 }
169                 ImageDrawSpec(const std::string &a_name,
170                                 const v2s32 &a_pos, const v2s32 &a_geom):
171                         name(a_name),
172                         parent_button(NULL),
173                         pos(a_pos),
174                         geom(a_geom),
175                         scale(true)
176                 {
177                 }
178                 ImageDrawSpec(const std::string &a_name,
179                                 const v2s32 &a_pos):
180                         name(a_name),
181                         parent_button(NULL),
182                         pos(a_pos),
183                         scale(false)
184                 {
185                 }
186                 std::string name;
187                 std::string item_name;
188                 gui::IGUIButton *parent_button;
189                 v2s32 pos;
190                 v2s32 geom;
191                 bool scale;
192         };
193
194         struct FieldSpec
195         {
196                 FieldSpec()
197                 {
198                 }
199                 FieldSpec(const std::string &name, const std::wstring &label,
200                                 const std::wstring &fdeflt, int id) :
201                         fname(name),
202                         flabel(label),
203                         fdefault(fdeflt),
204                         fid(id)
205                 {
206                         send = false;
207                         ftype = f_Unknown;
208                         is_exit = false;
209                 }
210                 std::string fname;
211                 std::wstring flabel;
212                 std::wstring fdefault;
213                 int fid;
214                 bool send;
215                 FormspecFieldType ftype;
216                 bool is_exit;
217                 core::rect<s32> rect;
218         };
219
220         struct BoxDrawSpec {
221                 BoxDrawSpec(v2s32 a_pos, v2s32 a_geom,irr::video::SColor a_color):
222                         pos(a_pos),
223                         geom(a_geom),
224                         color(a_color)
225                 {
226                 }
227                 v2s32 pos;
228                 v2s32 geom;
229                 irr::video::SColor color;
230         };
231
232         struct TooltipSpec {
233                 TooltipSpec()
234                 {
235                 }
236                 TooltipSpec(std::string a_tooltip, irr::video::SColor a_bgcolor,
237                                 irr::video::SColor a_color):
238                         tooltip(a_tooltip),
239                         bgcolor(a_bgcolor),
240                         color(a_color)
241                 {
242                 }
243                 std::string tooltip;
244                 irr::video::SColor bgcolor;
245                 irr::video::SColor color;
246         };
247
248         struct StaticTextSpec {
249                 StaticTextSpec():
250                         parent_button(NULL)
251                 {
252                 }
253                 StaticTextSpec(const std::wstring &a_text,
254                                 const core::rect<s32> &a_rect):
255                         text(a_text),
256                         rect(a_rect),
257                         parent_button(NULL)
258                 {
259                 }
260                 StaticTextSpec(const std::wstring &a_text,
261                                 const core::rect<s32> &a_rect,
262                                 gui::IGUIButton *a_parent_button):
263                         text(a_text),
264                         rect(a_rect),
265                         parent_button(a_parent_button)
266                 {
267                 }
268                 std::wstring text;
269                 core::rect<s32> rect;
270                 gui::IGUIButton *parent_button;
271         };
272
273 public:
274         GUIFormSpecMenu(irr::IrrlichtDevice* dev,
275                         gui::IGUIElement* parent, s32 id,
276                         IMenuManager *menumgr,
277                         InventoryManager *invmgr,
278                         IGameDef *gamedef,
279                         ISimpleTextureSource *tsrc,
280                         IFormSource* fs_src,
281                         TextDest* txt_dst,
282                         Client* client,
283                         bool remap_dbl_click = true);
284
285         ~GUIFormSpecMenu();
286
287         void setFormSpec(const std::string &formspec_string,
288                         InventoryLocation current_inventory_location)
289         {
290                 m_formspec_string = formspec_string;
291                 m_current_inventory_location = current_inventory_location;
292                 regenerateGui(m_screensize_old);
293         }
294
295         // form_src is deleted by this GUIFormSpecMenu
296         void setFormSource(IFormSource *form_src)
297         {
298                 if (m_form_src != NULL) {
299                         delete m_form_src;
300                 }
301                 m_form_src = form_src;
302         }
303
304         // text_dst is deleted by this GUIFormSpecMenu
305         void setTextDest(TextDest *text_dst)
306         {
307                 if (m_text_dst != NULL) {
308                         delete m_text_dst;
309                 }
310                 m_text_dst = text_dst;
311         }
312
313         void allowClose(bool value)
314         {
315                 m_allowclose = value;
316         }
317
318         void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0))
319         {
320                 m_lock = lock;
321                 m_lockscreensize = basescreensize;
322         }
323
324         void removeChildren();
325         void setInitialFocus();
326
327         void setFocus(std::string &elementname)
328         {
329                 m_focused_element = elementname;
330         }
331
332         /*
333                 Remove and re-add (or reposition) stuff
334         */
335         void regenerateGui(v2u32 screensize);
336
337         ItemSpec getItemAtPos(v2s32 p) const;
338         void drawList(const ListDrawSpec &s, int phase, bool &item_hovered);
339         void drawSelectedItem();
340         void drawMenu();
341         void updateSelectedItem();
342         ItemStack verifySelectedItem();
343
344         void acceptInput(FormspecQuitMode quitmode);
345         bool preprocessEvent(const SEvent& event);
346         bool OnEvent(const SEvent& event);
347         bool doPause;
348         bool pausesGame() { return doPause; }
349
350         GUITable* getTable(const std::string &tablename);
351
352 #ifdef __ANDROID__
353         bool getAndroidUIInput();
354 #endif
355
356 protected:
357         v2s32 getBasePos() const
358         {
359                         return padding + offset + AbsoluteRect.UpperLeftCorner;
360         }
361
362         v2s32 padding;
363         v2s32 spacing;
364         v2s32 imgsize;
365         v2s32 offset;
366
367         irr::IrrlichtDevice* m_device;
368         InventoryManager *m_invmgr;
369         IGameDef *m_gamedef;
370         ISimpleTextureSource *m_tsrc;
371         Client *m_client;
372
373         std::string m_formspec_string;
374         InventoryLocation m_current_inventory_location;
375
376
377         std::vector<ListDrawSpec> m_inventorylists;
378         std::vector<ListRingSpec> m_inventory_rings;
379         std::vector<ImageDrawSpec> m_backgrounds;
380         std::vector<ImageDrawSpec> m_images;
381         std::vector<ImageDrawSpec> m_itemimages;
382         std::vector<BoxDrawSpec> m_boxes;
383         std::vector<FieldSpec> m_fields;
384         std::vector<StaticTextSpec> m_static_texts;
385         std::vector<std::pair<FieldSpec,GUITable*> > m_tables;
386         std::vector<std::pair<FieldSpec,gui::IGUICheckBox*> > m_checkboxes;
387         std::map<std::string, TooltipSpec> m_tooltips;
388         std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
389
390         ItemSpec *m_selected_item;
391         f32 m_timer1;
392         f32 m_timer2;
393         u32 m_selected_amount;
394         bool m_selected_dragging;
395
396         // WARNING: BLACK MAGIC
397         // Used to guess and keep up with some special things the server can do.
398         // If name is "", no guess exists.
399         ItemStack m_selected_content_guess;
400         InventoryLocation m_selected_content_guess_inventory;
401
402         v2s32 m_pointer;
403         v2s32 m_old_pointer;  // Mouse position after previous mouse event
404         gui::IGUIStaticText *m_tooltip_element;
405
406         u32 m_tooltip_show_delay;
407         s32 m_hovered_time;
408         s32 m_old_tooltip_id;
409         std::string m_old_tooltip;
410
411         bool m_rmouse_auto_place;
412
413         bool m_allowclose;
414         bool m_lock;
415         v2u32 m_lockscreensize;
416
417         bool m_bgfullscreen;
418         bool m_slotborder;
419         bool m_clipbackground;
420         video::SColor m_bgcolor;
421         video::SColor m_slotbg_n;
422         video::SColor m_slotbg_h;
423         video::SColor m_slotbordercolor;
424         video::SColor m_default_tooltip_bgcolor;
425         video::SColor m_default_tooltip_color;
426
427 private:
428         IFormSource      *m_form_src;
429         TextDest         *m_text_dst;
430         unsigned int      m_formspec_version;
431         std::string       m_focused_element;
432
433         typedef struct {
434                 bool explicit_size;
435                 v2f invsize;
436                 v2s32 size;
437                 core::rect<s32> rect;
438                 v2s32 basepos;
439                 v2u32 screensize;
440                 std::string focused_fieldname;
441                 GUITable::TableOptions table_options;
442                 GUITable::TableColumns table_columns;
443                 // used to restore table selection/scroll/treeview state
444                 std::map<std::string, GUITable::DynamicData> table_dyndata;
445         } parserData;
446
447         typedef struct {
448                 bool key_up;
449                 bool key_down;
450                 bool key_enter;
451                 bool key_escape;
452         } fs_key_pendig;
453
454         fs_key_pendig current_keys_pending;
455
456         void parseElement(parserData* data,std::string element);
457
458         void parseSize(parserData* data,std::string element);
459         void parseList(parserData* data,std::string element);
460         void parseListRing(parserData* data,std::string element);
461         void parseCheckbox(parserData* data,std::string element);
462         void parseImage(parserData* data,std::string element);
463         void parseItemImage(parserData* data,std::string element);
464         void parseButton(parserData* data,std::string element,std::string typ);
465         void parseBackground(parserData* data,std::string element);
466         void parseTableOptions(parserData* data,std::string element);
467         void parseTableColumns(parserData* data,std::string element);
468         void parseTable(parserData* data,std::string element);
469         void parseTextList(parserData* data,std::string element);
470         void parseDropDown(parserData* data,std::string element);
471         void parsePwdField(parserData* data,std::string element);
472         void parseField(parserData* data,std::string element,std::string type);
473         void parseSimpleField(parserData* data,std::vector<std::string> &parts);
474         void parseTextArea(parserData* data,std::vector<std::string>& parts,
475                         std::string type);
476         void parseLabel(parserData* data,std::string element);
477         void parseVertLabel(parserData* data,std::string element);
478         void parseImageButton(parserData* data,std::string element,std::string type);
479         void parseItemImageButton(parserData* data,std::string element);
480         void parseTabHeader(parserData* data,std::string element);
481         void parseBox(parserData* data,std::string element);
482         void parseBackgroundColor(parserData* data,std::string element);
483         void parseListColors(parserData* data,std::string element);
484         void parseTooltip(parserData* data,std::string element);
485         bool parseVersionDirect(std::string data);
486         bool parseSizeDirect(parserData* data, std::string element);
487         void parseScrollBar(parserData* data, std::string element);
488
489         /**
490          * check if event is part of a double click
491          * @param event event to evaluate
492          * @return true/false if a doubleclick was detected
493          */
494         bool DoubleClickDetection(const SEvent event);
495
496         struct clickpos
497         {
498                 v2s32 pos;
499                 s32 time;
500         };
501         clickpos m_doubleclickdetect[2];
502
503         int m_btn_height;
504         gui::IGUIFont *m_font;
505
506         std::wstring getLabelByID(s32 id);
507         std::string getNameByID(s32 id);
508 #ifdef __ANDROID__
509         v2s32 m_down_pos;
510         std::string m_JavaDialogFieldName;
511 #endif
512
513         /* If true, remap a double-click (or double-tap) action to ESC. This is so
514          * that, for example, Android users can double-tap to close a formspec.
515         *
516          * This value can (currently) only be set by the class constructor
517          * and the default value for the setting is true.
518          */
519         bool m_remap_dbl_click;
520
521 };
522
523 class FormspecFormSource: public IFormSource
524 {
525 public:
526         FormspecFormSource(std::string formspec)
527         {
528                 m_formspec = formspec;
529         }
530
531         ~FormspecFormSource()
532         {}
533
534         void setForm(std::string formspec) {
535                 m_formspec = FORMSPEC_VERSION_STRING + formspec;
536         }
537
538         std::string getForm()
539         {
540                 return m_formspec;
541         }
542
543         std::string m_formspec;
544 };
545
546 #endif
547