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