Change mainmenu texture handling + small misc changes
[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
31 class IGameDef;
32 class InventoryManager;
33 class ISimpleTextureSource;
34
35 typedef enum {
36         f_Button,
37         f_ListBox,
38         f_TabHeader,
39         f_CheckBox,
40         f_DropDown,
41         f_Unknown
42 } FormspecFieldType;
43
44 struct TextDest
45 {
46         virtual ~TextDest() {};
47         // This is deprecated I guess? -celeron55
48         virtual void gotText(std::wstring text){}
49         virtual void gotText(std::map<std::string, std::string> fields) = 0;
50 };
51
52 class IFormSource
53 {
54 public:
55         virtual ~IFormSource(){}
56         virtual std::string getForm() = 0;
57         // Fill in variables in field text
58         virtual std::string resolveText(std::string str){ return str; }
59 };
60
61 class GUIFormSpecMenu : public GUIModalMenu
62 {
63         struct ItemSpec
64         {
65                 ItemSpec()
66                 {
67                         i = -1;
68                 }
69                 ItemSpec(const InventoryLocation &a_inventoryloc,
70                                 const std::string &a_listname,
71                                 s32 a_i)
72                 {
73                         inventoryloc = a_inventoryloc;
74                         listname = a_listname;
75                         i = a_i;
76                 }
77                 bool isValid() const
78                 {
79                         return i != -1;
80                 }
81
82                 InventoryLocation inventoryloc;
83                 std::string listname;
84                 s32 i;
85         };
86
87         struct ListDrawSpec
88         {
89                 ListDrawSpec()
90                 {
91                 }
92                 ListDrawSpec(const InventoryLocation &a_inventoryloc,
93                                 const std::string &a_listname,
94                                 v2s32 a_pos, v2s32 a_geom, s32 a_start_item_i):
95                         inventoryloc(a_inventoryloc),
96                         listname(a_listname),
97                         pos(a_pos),
98                         geom(a_geom),
99                         start_item_i(a_start_item_i)
100                 {
101                 }
102
103                 InventoryLocation inventoryloc;
104                 std::string listname;
105                 v2s32 pos;
106                 v2s32 geom;
107                 s32 start_item_i;
108         };
109
110         struct ImageDrawSpec
111         {
112                 ImageDrawSpec()
113                 {
114                 }
115                 ImageDrawSpec(const std::string &a_name,
116                                 v2s32 a_pos, v2s32 a_geom):
117                         name(a_name),
118                         pos(a_pos),
119                         geom(a_geom)
120                 {
121                         scale = true;
122                 }
123                 ImageDrawSpec(const std::string &a_name,
124                                 v2s32 a_pos):
125                         name(a_name),
126                         pos(a_pos)
127                 {
128                         scale = false;
129                 }
130                 std::string name;
131                 v2s32 pos;
132                 v2s32 geom;
133                 bool scale;
134         };
135         
136         struct FieldSpec
137         {
138                 FieldSpec()
139                 {
140                 }
141                 FieldSpec(const std::wstring name, const std::wstring label, const std::wstring fdeflt, int id):
142                         fname(name),
143                         flabel(label),
144                         fdefault(fdeflt),
145                         fid(id)
146                 {
147                         send = false;
148                         ftype = f_Unknown;
149                         is_exit = false;
150                         tooltip="";
151                 }
152                 std::wstring fname;
153                 std::wstring flabel;
154                 std::wstring fdefault;
155                 int fid;
156                 bool send;
157                 FormspecFieldType ftype;
158                 bool is_exit;
159                 core::rect<s32> rect;
160                 std::string tooltip;
161         };
162
163         struct BoxDrawSpec {
164                 BoxDrawSpec(v2s32 a_pos, v2s32 a_geom,irr::video::SColor a_color):
165                         pos(a_pos),
166                         geom(a_geom),
167                         color(a_color)
168                 {
169                 }
170                 v2s32 pos;
171                 v2s32 geom;
172                 irr::video::SColor color;
173         };
174
175 public:
176         GUIFormSpecMenu(irr::IrrlichtDevice* dev,
177                         gui::IGUIElement* parent, s32 id,
178                         IMenuManager *menumgr,
179                         InventoryManager *invmgr,
180                         IGameDef *gamedef,
181                         ISimpleTextureSource *tsrc
182                         );
183
184         ~GUIFormSpecMenu();
185
186         void setFormSpec(const std::string &formspec_string,
187                         InventoryLocation current_inventory_location)
188         {
189                 m_formspec_string = formspec_string;
190                 m_current_inventory_location = current_inventory_location;
191                 regenerateGui(m_screensize_old);
192         }
193         
194         // form_src is deleted by this GUIFormSpecMenu
195         void setFormSource(IFormSource *form_src)
196         {
197                 m_form_src = form_src;
198         }
199
200         // text_dst is deleted by this GUIFormSpecMenu
201         void setTextDest(TextDest *text_dst)
202         {
203                 m_text_dst = text_dst;
204         }
205
206         void allowClose(bool value)
207         {
208                 m_allowclose = value;
209         }
210
211         void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) {
212                 m_lock = lock;
213                 m_lockscreensize = basescreensize;
214         }
215
216         void removeChildren();
217         void setInitialFocus();
218         /*
219                 Remove and re-add (or reposition) stuff
220         */
221         void regenerateGui(v2u32 screensize);
222         
223         ItemSpec getItemAtPos(v2s32 p) const;
224         void drawList(const ListDrawSpec &s, int phase);
225         void drawSelectedItem();
226         void drawMenu();
227         void updateSelectedItem();
228         ItemStack verifySelectedItem();
229
230         void acceptInput();
231         bool preprocessEvent(const SEvent& event);
232         bool OnEvent(const SEvent& event);
233
234         int getListboxIndex(std::string listboxname);
235
236 protected:
237         v2s32 getBasePos() const
238         {
239                         return padding + offset + AbsoluteRect.UpperLeftCorner;
240         }
241
242         v2s32 padding;
243         v2s32 spacing;
244         v2s32 imgsize;
245         v2s32 offset;
246         
247         irr::IrrlichtDevice* m_device;
248         InventoryManager *m_invmgr;
249         IGameDef *m_gamedef;
250         ISimpleTextureSource *m_tsrc;
251
252         std::string m_formspec_string;
253         InventoryLocation m_current_inventory_location;
254         IFormSource *m_form_src;
255         TextDest *m_text_dst;
256
257         std::vector<ListDrawSpec> m_inventorylists;
258         std::vector<ImageDrawSpec> m_backgrounds;
259         std::vector<ImageDrawSpec> m_images;
260         std::vector<ImageDrawSpec> m_itemimages;
261         std::vector<BoxDrawSpec> m_boxes;
262         std::vector<FieldSpec> m_fields;
263         std::vector<std::pair<FieldSpec,gui::IGUIListBox*> > m_listboxes;
264         std::vector<std::pair<FieldSpec,gui::IGUICheckBox*> > m_checkboxes;
265
266         ItemSpec *m_selected_item;
267         u32 m_selected_amount;
268         bool m_selected_dragging;
269         
270         // WARNING: BLACK MAGIC
271         // Used to guess and keep up with some special things the server can do.
272         // If name is "", no guess exists.
273         ItemStack m_selected_content_guess;
274         InventoryLocation m_selected_content_guess_inventory;
275
276         // WARNING: BLACK IRRLICHT MAGIC, see checkListboxClick()
277         std::wstring m_listbox_click_fname;
278         int m_listbox_click_index;
279         u32 m_listbox_click_time;
280         bool m_listbox_doubleclick;
281
282         v2s32 m_pointer;
283         gui::IGUIStaticText *m_tooltip_element;
284
285         bool m_allowclose;
286         bool m_lock;
287         v2u32 m_lockscreensize;
288 private:
289         typedef struct {
290                 v2s32 size;
291                 s32 helptext_h;
292                 core::rect<s32> rect;
293                 v2s32 basepos;
294                 int bp_set;
295                 v2u32 screensize;
296                 std::wstring focused_fieldname;
297                 std::map<std::wstring,int> listbox_selections;
298                 std::map<std::wstring,int> listbox_scroll;
299         } parserData;
300
301         typedef struct {
302                 bool key_up;
303                 bool key_down;
304                 bool key_enter;
305                 bool key_escape;
306         } fs_key_pendig;
307
308         fs_key_pendig current_keys_pending;
309
310         // Determine whether listbox click was double click
311         // (Using some black Irrlicht magic)
312         bool checkListboxClick(std::wstring wlistboxname, int eventtype);
313
314         gui::IGUIScrollBar* getListboxScrollbar(gui::IGUIListBox *listbox);
315
316         void parseElement(parserData* data,std::string element);
317
318         void parseSize(parserData* data,std::string element);
319         void parseList(parserData* data,std::string element);
320         void parseCheckbox(parserData* data,std::string element);
321         void parseImage(parserData* data,std::string element);
322         void parseItemImage(parserData* data,std::string element);
323         void parseButton(parserData* data,std::string element,std::string typ);
324         void parseBackground(parserData* data,std::string element);
325         void parseTextList(parserData* data,std::string element);
326         void parseDropDown(parserData* data,std::string element);
327         void parsePwdField(parserData* data,std::string element);
328         void parseField(parserData* data,std::string element,std::string type);
329         void parseSimpleField(parserData* data,std::vector<std::string> &parts);
330         void parseTextArea(parserData* data,std::vector<std::string>& parts,std::string type);
331         void parseLabel(parserData* data,std::string element);
332         void parseVertLabel(parserData* data,std::string element);
333         void parseImageButton(parserData* data,std::string element,std::string type);
334         void parseItemImageButton(parserData* data,std::string element);
335         void parseTabHeader(parserData* data,std::string element);
336         void parseBox(parserData* data,std::string element);
337
338         bool parseColor(std::string color, irr::video::SColor& outcolor); 
339 };
340
341 class FormspecFormSource: public IFormSource
342 {
343 public:
344         FormspecFormSource(std::string formspec,FormspecFormSource** game_formspec)
345         {
346                 m_formspec = formspec;
347                 m_game_formspec = game_formspec;
348         }
349
350         ~FormspecFormSource()
351         {
352                 *m_game_formspec = 0;
353         }
354
355         void setForm(std::string formspec) {
356                 m_formspec = formspec;
357         }
358
359         std::string getForm()
360         {
361                 return m_formspec;
362         }
363
364         std::string m_formspec;
365         FormspecFormSource** m_game_formspec;
366 };
367
368 #endif
369