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