X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2FguiFormSpecMenu.h;h=d08bb4ab59cdbdebed78c896365a7ea2423c3810;hb=5cc8ad946efb3612eb6ea8655780b29fe4c62e19;hp=116f7b95d54ac4cd3bf3d63523bae65d468bf4c8;hpb=88d43af276a4ed85500863b427bf370d8eca2095;p=minetest.git diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 116f7b95d..d08bb4ab5 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -22,30 +22,45 @@ with this program; if not, write to the Free Software Foundation, Inc., #define GUIINVENTORYMENU_HEADER #include +#include #include "irrlichttypes_extrabloated.h" -#include "inventory.h" #include "inventorymanager.h" #include "modalMenu.h" +#include "guiTable.h" +#include "network/networkprotocol.h" +#include "client/joystick_controller.h" +#include "util/string.h" +#include "util/enriched_string.h" -class IGameDef; class InventoryManager; +class ISimpleTextureSource; +class Client; typedef enum { f_Button, - f_ListBox, + f_Table, f_TabHeader, f_CheckBox, f_DropDown, + f_ScrollBar, f_Unknown } FormspecFieldType; +typedef enum { + quit_mode_no, + quit_mode_accept, + quit_mode_cancel +} FormspecQuitMode; + struct TextDest { - virtual ~TextDest() {}; + virtual ~TextDest() {} // This is deprecated I guess? -celeron55 - virtual void gotText(std::wstring text){} - virtual void gotText(std::map fields) = 0; + virtual void gotText(const std::wstring &text) {} + virtual void gotText(const StringMap &fields) = 0; + + std::string m_formname; }; class IFormSource @@ -54,37 +69,29 @@ class IFormSource virtual ~IFormSource(){} virtual std::string getForm() = 0; // Fill in variables in field text - virtual std::string resolveText(std::string str){ return str; } + virtual std::string resolveText(const std::string &str) { return str; } }; -void drawItemStack(video::IVideoDriver *driver, - gui::IGUIFont *font, - const ItemStack &item, - const core::rect &rect, - const core::rect *clip, - IGameDef *gamedef); - class GUIFormSpecMenu : public GUIModalMenu { struct ItemSpec { - ItemSpec() + ItemSpec() : + i(-1) { - i = -1; } + ItemSpec(const InventoryLocation &a_inventoryloc, const std::string &a_listname, - s32 a_i) - { - inventoryloc = a_inventoryloc; - listname = a_listname; - i = a_i; - } - bool isValid() const + s32 a_i) : + inventoryloc(a_inventoryloc), + listname(a_listname), + i(a_i) { - return i != -1; } + bool isValid() const { return i != -1; } + InventoryLocation inventoryloc; std::string listname; s32 i; @@ -113,49 +120,105 @@ class GUIFormSpecMenu : public GUIModalMenu s32 start_item_i; }; + struct ListRingSpec + { + ListRingSpec() + { + } + ListRingSpec(const InventoryLocation &a_inventoryloc, + const std::string &a_listname): + inventoryloc(a_inventoryloc), + listname(a_listname) + { + } + + InventoryLocation inventoryloc; + std::string listname; + }; + struct ImageDrawSpec { - ImageDrawSpec() + ImageDrawSpec(): + parent_button(NULL), + clip(false) { } + ImageDrawSpec(const std::string &a_name, - v2s32 a_pos, v2s32 a_geom): + const std::string &a_item_name, + gui::IGUIButton *a_parent_button, + const v2s32 &a_pos, const v2s32 &a_geom): name(a_name), + item_name(a_item_name), + parent_button(a_parent_button), pos(a_pos), - geom(a_geom) + geom(a_geom), + scale(true), + clip(false) { - scale = true; } + ImageDrawSpec(const std::string &a_name, - v2s32 a_pos): + const std::string &a_item_name, + const v2s32 &a_pos, const v2s32 &a_geom): name(a_name), - pos(a_pos) + item_name(a_item_name), + parent_button(NULL), + pos(a_pos), + geom(a_geom), + scale(true), + clip(false) + { + } + + ImageDrawSpec(const std::string &a_name, + const v2s32 &a_pos, const v2s32 &a_geom, bool clip=false): + name(a_name), + parent_button(NULL), + pos(a_pos), + geom(a_geom), + scale(true), + clip(clip) + { + } + + ImageDrawSpec(const std::string &a_name, + const v2s32 &a_pos): + name(a_name), + parent_button(NULL), + pos(a_pos), + scale(false), + clip(false) { - scale = false; } + std::string name; + std::string item_name; + gui::IGUIButton *parent_button; v2s32 pos; v2s32 geom; bool scale; + bool clip; }; - + struct FieldSpec { FieldSpec() { } - FieldSpec(const std::wstring name, const std::wstring label, const std::wstring fdeflt, int id): + FieldSpec(const std::string &name, const std::wstring &label, + const std::wstring &default_text, int id) : fname(name), flabel(label), - fdefault(fdeflt), - fid(id) + fdefault(unescape_enriched(default_text)), + fid(id), + send(false), + ftype(f_Unknown), + is_exit(false) { - send = false; - ftype = f_Unknown; - is_exit = false; - tooltip=""; } - std::wstring fname; + + std::string fname; std::wstring flabel; std::wstring fdefault; int fid; @@ -163,10 +226,10 @@ class GUIFormSpecMenu : public GUIModalMenu FormspecFieldType ftype; bool is_exit; core::rect rect; - std::string tooltip; }; - struct BoxDrawSpec { + struct BoxDrawSpec + { BoxDrawSpec(v2s32 a_pos, v2s32 a_geom,irr::video::SColor a_color): pos(a_pos), geom(a_geom), @@ -178,33 +241,83 @@ class GUIFormSpecMenu : public GUIModalMenu irr::video::SColor color; }; + struct TooltipSpec + { + TooltipSpec() {} + TooltipSpec(const std::string &a_tooltip, irr::video::SColor a_bgcolor, + irr::video::SColor a_color): + tooltip(utf8_to_wide(a_tooltip)), + bgcolor(a_bgcolor), + color(a_color) + { + } + + std::wstring tooltip; + irr::video::SColor bgcolor; + irr::video::SColor color; + }; + + struct StaticTextSpec + { + StaticTextSpec(): + parent_button(NULL) + { + } + + StaticTextSpec(const std::wstring &a_text, + const core::rect &a_rect): + text(a_text), + rect(a_rect), + parent_button(NULL) + { + } + + StaticTextSpec(const std::wstring &a_text, + const core::rect &a_rect, + gui::IGUIButton *a_parent_button): + text(a_text), + rect(a_rect), + parent_button(a_parent_button) + { + } + + std::wstring text; + core::rect rect; + gui::IGUIButton *parent_button; + }; + public: GUIFormSpecMenu(irr::IrrlichtDevice* dev, + JoystickController *joystick, gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, - InventoryManager *invmgr, - IGameDef *gamedef - ); + Client *client, + ISimpleTextureSource *tsrc, + IFormSource* fs_src, + TextDest* txt_dst, + bool remap_dbl_click = true); ~GUIFormSpecMenu(); void setFormSpec(const std::string &formspec_string, - InventoryLocation current_inventory_location) + const InventoryLocation ¤t_inventory_location) { m_formspec_string = formspec_string; m_current_inventory_location = current_inventory_location; regenerateGui(m_screensize_old); } - + // form_src is deleted by this GUIFormSpecMenu void setFormSource(IFormSource *form_src) { + delete m_form_src; m_form_src = form_src; } // text_dst is deleted by this GUIFormSpecMenu void setTextDest(TextDest *text_dst) { + delete m_text_dst; m_text_dst = text_dst; } @@ -213,32 +326,44 @@ class GUIFormSpecMenu : public GUIModalMenu m_allowclose = value; } - void useGettext(bool value) { - m_use_gettext = true; - } - - void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) { + void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) + { m_lock = lock; m_lockscreensize = basescreensize; } void removeChildren(); + void setInitialFocus(); + + void setFocus(const std::string &elementname) + { + m_focused_element = elementname; + } + /* Remove and re-add (or reposition) stuff */ void regenerateGui(v2u32 screensize); - + ItemSpec getItemAtPos(v2s32 p) const; - void drawList(const ListDrawSpec &s, int phase); + void drawList(const ListDrawSpec &s, int phase, bool &item_hovered); void drawSelectedItem(); void drawMenu(); void updateSelectedItem(); ItemStack verifySelectedItem(); - void acceptInput(int evttype=-1); + void acceptInput(FormspecQuitMode quitmode); + bool preprocessEvent(const SEvent& event); bool OnEvent(const SEvent& event); - - int getListboxIndex(std::string listboxname); + bool doPause; + bool pausesGame() { return doPause; } + + GUITable* getTable(const std::string &tablename); + std::vector* getDropDownValues(const std::string &name); + +#ifdef __ANDROID__ + bool getAndroidUIInput(); +#endif protected: v2s32 getBasePos() const @@ -250,29 +375,37 @@ class GUIFormSpecMenu : public GUIModalMenu v2s32 spacing; v2s32 imgsize; v2s32 offset; - + v2s32 pos_offset; + std::stack container_stack; + irr::IrrlichtDevice* m_device; InventoryManager *m_invmgr; - IGameDef *m_gamedef; + ISimpleTextureSource *m_tsrc; + Client *m_client; std::string m_formspec_string; InventoryLocation m_current_inventory_location; - IFormSource *m_form_src; - TextDest *m_text_dst; + std::vector m_inventorylists; + std::vector m_inventory_rings; std::vector m_backgrounds; std::vector m_images; std::vector m_itemimages; std::vector m_boxes; + std::unordered_map field_close_on_enter; std::vector m_fields; - std::vector > m_listboxes; + std::vector m_static_texts; + std::vector > m_tables; std::vector > m_checkboxes; + std::map m_tooltips; + std::vector > m_scrollbars; + std::vector > > m_dropdowns; ItemSpec *m_selected_item; u32 m_selected_amount; bool m_selected_dragging; - + // WARNING: BLACK MAGIC // Used to guess and keep up with some special things the server can do. // If name is "", no guess exists. @@ -280,21 +413,50 @@ class GUIFormSpecMenu : public GUIModalMenu InventoryLocation m_selected_content_guess_inventory; v2s32 m_pointer; + v2s32 m_old_pointer; // Mouse position after previous mouse event gui::IGUIStaticText *m_tooltip_element; + u64 m_tooltip_show_delay; + u64 m_hovered_time; + s32 m_old_tooltip_id; + std::wstring m_old_tooltip; + + bool m_rmouse_auto_place; + bool m_allowclose; - bool m_use_gettext; bool m_lock; v2u32 m_lockscreensize; + + bool m_bgfullscreen; + bool m_slotborder; + video::SColor m_bgcolor; + video::SColor m_slotbg_n; + video::SColor m_slotbg_h; + video::SColor m_slotbordercolor; + video::SColor m_default_tooltip_bgcolor; + video::SColor m_default_tooltip_color; + private: + IFormSource *m_form_src; + TextDest *m_text_dst; + unsigned int m_formspec_version; + std::string m_focused_element; + JoystickController *m_joystick; + typedef struct { + bool explicit_size; + v2f invsize; v2s32 size; - s32 helptext_h; + v2f32 offset; + v2f32 anchor; core::rect rect; v2s32 basepos; - int bp_set; v2u32 screensize; - std::map listbox_selections; + std::string focused_fieldname; + GUITable::TableOptions table_options; + GUITable::TableColumns table_columns; + // used to restore table selection/scroll/treeview state + std::unordered_map table_dyndata; } parserData; typedef struct { @@ -304,61 +466,110 @@ class GUIFormSpecMenu : public GUIModalMenu bool key_escape; } fs_key_pendig; - std::vector m_Textures; - fs_key_pendig current_keys_pending; - - void parseElement(parserData* data,std::string element); - - void parseSize(parserData* data,std::string element); - void parseList(parserData* data,std::string element); - void parseCheckbox(parserData* data,std::string element); - void parseImage(parserData* data,std::string element); - void parseItemImage(parserData* data,std::string element); - void parseButton(parserData* data,std::string element,std::string typ); - void parseBackground(parserData* data,std::string element); - void parseTextList(parserData* data,std::string element); - void parseDropDown(parserData* data,std::string element); - void parsePwdField(parserData* data,std::string element); - void parseField(parserData* data,std::string element,std::string type); + std::string current_field_enter_pending; + + void parseElement(parserData* data, const std::string &element); + + void parseSize(parserData* data, const std::string &element); + void parseContainer(parserData* data, const std::string &element); + void parseContainerEnd(parserData* data); + void parseList(parserData* data, const std::string &element); + void parseListRing(parserData* data, const std::string &element); + void parseCheckbox(parserData* data, const std::string &element); + void parseImage(parserData* data, const std::string &element); + void parseItemImage(parserData* data, const std::string &element); + void parseButton(parserData* data, const std::string &element, + const std::string &typ); + void parseBackground(parserData* data, const std::string &element); + void parseTableOptions(parserData* data, const std::string &element); + void parseTableColumns(parserData* data, const std::string &element); + void parseTable(parserData* data, const std::string &element); + void parseTextList(parserData* data, const std::string &element); + void parseDropDown(parserData* data, const std::string &element); + void parseFieldCloseOnEnter(parserData *data, const std::string &element); + void parsePwdField(parserData* data, const std::string &element); + void parseField(parserData* data, const std::string &element, const std::string &type); void parseSimpleField(parserData* data,std::vector &parts); - void parseTextArea(parserData* data,std::vector& parts,std::string type); - void parseLabel(parserData* data,std::string element); - void parseVertLabel(parserData* data,std::string element); - void parseImageButton(parserData* data,std::string element,std::string type); - void parseItemImageButton(parserData* data,std::string element); - void parseTabHeader(parserData* data,std::string element); - void parseBox(parserData* data,std::string element); - - bool parseColor(std::string color, irr::video::SColor& outcolor); + void parseTextArea(parserData* data,std::vector& parts, + const std::string &type); + void parseLabel(parserData* data, const std::string &element); + void parseVertLabel(parserData* data, const std::string &element); + void parseImageButton(parserData* data, const std::string &element, + const std::string &type); + void parseItemImageButton(parserData* data, const std::string &element); + void parseTabHeader(parserData* data, const std::string &element); + void parseBox(parserData* data, const std::string &element); + void parseBackgroundColor(parserData* data, const std::string &element); + void parseListColors(parserData* data, const std::string &element); + void parseTooltip(parserData* data, const std::string &element); + bool parseVersionDirect(const std::string &data); + bool parseSizeDirect(parserData* data, const std::string &element); + void parseScrollBar(parserData* data, const std::string &element); + bool parsePositionDirect(parserData *data, const std::string &element); + void parsePosition(parserData *data, const std::string &element); + bool parseAnchorDirect(parserData *data, const std::string &element); + void parseAnchor(parserData *data, const std::string &element); + + void tryClose(); + + void showTooltip(const std::wstring &text, const irr::video::SColor &color, + const irr::video::SColor &bgcolor); + + /** + * check if event is part of a double click + * @param event event to evaluate + * @return true/false if a doubleclick was detected + */ + bool DoubleClickDetection(const SEvent event); + + struct clickpos + { + v2s32 pos; + s64 time; + }; + clickpos m_doubleclickdetect[2]; + + int m_btn_height; + gui::IGUIFont *m_font; + + std::wstring getLabelByID(s32 id); + std::string getNameByID(s32 id); +#ifdef __ANDROID__ + v2s32 m_down_pos; + std::string m_JavaDialogFieldName; +#endif + + /* If true, remap a double-click (or double-tap) action to ESC. This is so + * that, for example, Android users can double-tap to close a formspec. + * + * This value can (currently) only be set by the class constructor + * and the default value for the setting is true. + */ + bool m_remap_dbl_click; + }; class FormspecFormSource: public IFormSource { public: - FormspecFormSource(std::string formspec,FormspecFormSource** game_formspec) + FormspecFormSource(const std::string &formspec): + m_formspec(formspec) { - m_formspec = formspec; - m_game_formspec = game_formspec; } ~FormspecFormSource() { - *m_game_formspec = 0; - } - - void setForm(std::string formspec) { - m_formspec = formspec; } - std::string getForm() + void setForm(const std::string &formspec) { - return m_formspec; + m_formspec = FORMSPEC_VERSION_STRING + formspec; } + std::string getForm() { return m_formspec; } + std::string m_formspec; - FormspecFormSource** m_game_formspec; }; #endif -