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