diff options
Diffstat (limited to 'src/guiTable.h')
-rw-r--r-- | src/guiTable.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/guiTable.h b/src/guiTable.h new file mode 100644 index 000000000..4d5b39166 --- /dev/null +++ b/src/guiTable.h @@ -0,0 +1,269 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#ifndef GUITABLE_HEADER +#define GUITABLE_HEADER + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <iostream> + +#include "irrlichttypes_extrabloated.h" + +class ISimpleTextureSource; + +/* + A table GUI element for GUIFormSpecMenu. + + Sends a EGET_TABLE_CHANGED event to the parent when + an item is selected or double-clicked. + Call checkEvent() to get info. + + Credits: The interface and implementation of this class are (very) + loosely based on the Irrlicht classes CGUITable and CGUIListBox. + CGUITable and CGUIListBox are licensed under the Irrlicht license; + they are Copyright (C) 2002-2012 Nikolaus Gebhardt +*/ +class GUITable : public gui::IGUIElement +{ +public: + /* + Stores dynamic data that should be preserved + when updating a formspec + */ + struct DynamicData + { + s32 selected; + s32 scrollpos; + s32 keynav_time; + core::stringw keynav_buffer; + std::set<s32> opened_trees; + + DynamicData() + { + selected = 0; + scrollpos = 0; + keynav_time = 0; + } + }; + + /* + An option of the form <name>=<value> + */ + struct Option + { + std::string name; + std::string value; + + Option(const std::string &name_, const std::string &value_) + { + name = name_; + value = value_; + } + }; + + /* + A list of options that concern the entire table + */ + typedef std::vector<Option> TableOptions; + + /* + A column with options + */ + struct TableColumn + { + std::string type; + std::vector<Option> options; + }; + typedef std::vector<TableColumn> TableColumns; + + + GUITable(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, s32 id, + core::rect<s32> rectangle, + ISimpleTextureSource *tsrc); + + virtual ~GUITable(); + + /* Split a string of the form "name=value" into name and value */ + static Option splitOption(const std::string &str); + + /* Set textlist-like options, columns and data */ + void setTextList(const std::vector<std::string> &content, + bool transparent); + + /* Set generic table options, columns and content */ + // Adds empty strings to end of content if there is an incomplete row + void setTable(const TableOptions &options, + const TableColumns &columns, + std::vector<std::string> &content); + + /* Clear the table */ + void clear(); + + /* Get info about last event (string such as "CHG:1:2") */ + // Call this after EGET_TABLE_CHANGED + std::string checkEvent(); + + /* Get index of currently selected row (first=1; 0 if none selected) */ + s32 getSelected() const; + + /* Set currently selected row (first=1; 0 if none selected) */ + // If given index is not visible at the moment, select its parent + // Autoscroll to make the selected row fully visible + void setSelected(s32 index); + + /* Get selection, scroll position and opened (sub)trees */ + DynamicData getDynamicData() const; + + /* Set selection, scroll position and opened (sub)trees */ + void setDynamicData(const DynamicData &dyndata); + + /* Returns "GUITable" */ + virtual const c8* getTypeName() const; + + /* Must be called when position or size changes */ + virtual void updateAbsolutePosition(); + + /* Irrlicht draw method */ + virtual void draw(); + + /* Irrlicht event handler */ + virtual bool OnEvent(const SEvent &event); + +protected: + enum ColumnType { + COLUMN_TYPE_TEXT, + COLUMN_TYPE_IMAGE, + COLUMN_TYPE_COLOR, + COLUMN_TYPE_INDENT, + COLUMN_TYPE_TREE, + }; + + struct Cell { + s32 xmin; + s32 xmax; + s32 xpos; + ColumnType content_type; + s32 content_index; + s32 tooltip_index; + video::SColor color; + bool color_defined; + s32 reported_column; + }; + + struct Row { + Cell *cells; + s32 cellcount; + s32 indent; + // visible_index >= 0: is index of row in m_visible_rows + // visible_index == -1: parent open but other ancestor closed + // visible_index == -2: parent closed + s32 visible_index; + }; + + // Texture source + ISimpleTextureSource *m_tsrc; + + // Table content (including hidden rows) + std::vector<Row> m_rows; + // Table content (only visible; indices into m_rows) + std::vector<s32> m_visible_rows; + bool m_is_textlist; + bool m_has_tree_column; + + // Selection status + s32 m_selected; // index of row (1...n), or 0 if none selected + s32 m_sel_column; + bool m_sel_doubleclick; + + // Keyboard navigation stuff + s32 m_keynav_time; + core::stringw m_keynav_buffer; + + // Drawing and geometry information + bool m_border; + video::SColor m_color; + video::SColor m_background; + video::SColor m_highlight; + video::SColor m_highlight_text; + s32 m_rowheight; + gui::IGUIFont *m_font; + gui::IGUIScrollBar *m_scrollbar; + + // Allocated strings and images + std::vector<core::stringw> m_strings; + std::vector<video::ITexture*> m_images; + std::map<std::string, s32> m_alloc_strings; + std::map<std::string, s32> m_alloc_images; + + s32 allocString(const std::string &text); + s32 allocImage(const std::string &imagename); + void allocationComplete(); + + // Helper for draw() that draws a single cell + void drawCell(const Cell *cell, video::SColor color, + const core::rect<s32> &rowrect, + const core::rect<s32> &client_clip); + + // Returns the i-th visible row (NULL if i is invalid) + const Row *getRow(s32 i) const; + + // Key navigation helper + bool doesRowStartWith(const Row *row, const core::stringw &str) const; + + // Returns the row at a given screen Y coordinate + // Returns index i such that m_rows[i] is valid (or -1 on error) + s32 getRowAt(s32 y, bool &really_hovering) const; + + // Returns the cell at a given screen X coordinate within m_rows[row_i] + // Returns index j such that m_rows[row_i].cells[j] is valid + // (or -1 on error) + s32 getCellAt(s32 x, s32 row_i) const; + + // Make the selected row fully visible + void autoScroll(); + + // Should be called when m_rowcount or m_rowheight changes + void updateScrollBar(); + + // Sends EET_GUI_EVENT / EGET_TABLE_CHANGED to parent + void sendTableEvent(s32 column, bool doubleclick); + + // Functions that help deal with hidden rows + // The following functions take raw row indices (hidden rows not skipped) + void getOpenedTrees(std::set<s32> &opened_trees) const; + void setOpenedTrees(const std::set<s32> &opened_trees); + void openTree(s32 to_open); + void closeTree(s32 to_close); + // The following function takes a visible row index (hidden rows skipped) + // dir: -1 = left (close), 0 = auto (toggle), 1 = right (open) + void toggleVisibleTree(s32 row_i, int dir, bool move_selection); + + // Aligns cell content in column according to alignment specification + // align = 0: left aligned, 1: centered, 2: right aligned, 3: inline + static void alignContent(Cell *cell, s32 xmax, s32 content_width, + s32 align); +}; + +#endif + |