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