guiTable.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #ifndef GUITABLE_HEADER
  17. #define GUITABLE_HEADER
  18. #include <map>
  19. #include <set>
  20. #include <string>
  21. #include <vector>
  22. #include <iostream>
  23. #include "irrlichttypes_extrabloated.h"
  24. class ISimpleTextureSource;
  25. /*
  26. A table GUI element for GUIFormSpecMenu.
  27. Sends a EGET_TABLE_CHANGED event to the parent when
  28. an item is selected or double-clicked.
  29. Call checkEvent() to get info.
  30. Credits: The interface and implementation of this class are (very)
  31. loosely based on the Irrlicht classes CGUITable and CGUIListBox.
  32. CGUITable and CGUIListBox are licensed under the Irrlicht license;
  33. they are Copyright (C) 2002-2012 Nikolaus Gebhardt
  34. */
  35. class GUITable : public gui::IGUIElement
  36. {
  37. public:
  38. /*
  39. Stores dynamic data that should be preserved
  40. when updating a formspec
  41. */
  42. struct DynamicData
  43. {
  44. s32 selected;
  45. s32 scrollpos;
  46. s32 keynav_time;
  47. core::stringw keynav_buffer;
  48. std::set<s32> opened_trees;
  49. DynamicData()
  50. {
  51. selected = 0;
  52. scrollpos = 0;
  53. keynav_time = 0;
  54. }
  55. };
  56. /*
  57. An option of the form <name>=<value>
  58. */
  59. struct Option
  60. {
  61. std::string name;
  62. std::string value;
  63. Option(const std::string &name_, const std::string &value_)
  64. {
  65. name = name_;
  66. value = value_;
  67. }
  68. };
  69. /*
  70. A list of options that concern the entire table
  71. */
  72. typedef std::vector<Option> TableOptions;
  73. /*
  74. A column with options
  75. */
  76. struct TableColumn
  77. {
  78. std::string type;
  79. std::vector<Option> options;
  80. };
  81. typedef std::vector<TableColumn> TableColumns;
  82. GUITable(gui::IGUIEnvironment *env,
  83. gui::IGUIElement *parent, s32 id,
  84. core::rect<s32> rectangle,
  85. ISimpleTextureSource *tsrc);
  86. virtual ~GUITable();
  87. /* Split a string of the form "name=value" into name and value */
  88. static Option splitOption(const std::string &str);
  89. /* Set textlist-like options, columns and data */
  90. void setTextList(const std::vector<std::string> &content,
  91. bool transparent);
  92. /* Set generic table options, columns and content */
  93. // Adds empty strings to end of content if there is an incomplete row
  94. void setTable(const TableOptions &options,
  95. const TableColumns &columns,
  96. std::vector<std::string> &content);
  97. /* Clear the table */
  98. void clear();
  99. /* Get info about last event (string such as "CHG:1:2") */
  100. // Call this after EGET_TABLE_CHANGED
  101. std::string checkEvent();
  102. /* Get index of currently selected row (first=1; 0 if none selected) */
  103. s32 getSelected() const;
  104. /* Set currently selected row (first=1; 0 if none selected) */
  105. // If given index is not visible at the moment, select its parent
  106. // Autoscroll to make the selected row fully visible
  107. void setSelected(s32 index);
  108. /* Get selection, scroll position and opened (sub)trees */
  109. DynamicData getDynamicData() const;
  110. /* Set selection, scroll position and opened (sub)trees */
  111. void setDynamicData(const DynamicData &dyndata);
  112. /* Returns "GUITable" */
  113. virtual const c8* getTypeName() const;
  114. /* Must be called when position or size changes */
  115. virtual void updateAbsolutePosition();
  116. /* Irrlicht draw method */
  117. virtual void draw();
  118. /* Irrlicht event handler */
  119. virtual bool OnEvent(const SEvent &event);
  120. protected:
  121. enum ColumnType {
  122. COLUMN_TYPE_TEXT,
  123. COLUMN_TYPE_IMAGE,
  124. COLUMN_TYPE_COLOR,
  125. COLUMN_TYPE_INDENT,
  126. COLUMN_TYPE_TREE,
  127. };
  128. struct Cell {
  129. s32 xmin;
  130. s32 xmax;
  131. s32 xpos;
  132. ColumnType content_type;
  133. s32 content_index;
  134. s32 tooltip_index;
  135. video::SColor color;
  136. bool color_defined;
  137. s32 reported_column;
  138. };
  139. struct Row {
  140. Cell *cells;
  141. s32 cellcount;
  142. s32 indent;
  143. // visible_index >= 0: is index of row in m_visible_rows
  144. // visible_index == -1: parent open but other ancestor closed
  145. // visible_index == -2: parent closed
  146. s32 visible_index;
  147. };
  148. // Texture source
  149. ISimpleTextureSource *m_tsrc;
  150. // Table content (including hidden rows)
  151. std::vector<Row> m_rows;
  152. // Table content (only visible; indices into m_rows)
  153. std::vector<s32> m_visible_rows;
  154. bool m_is_textlist;
  155. bool m_has_tree_column;
  156. // Selection status
  157. s32 m_selected; // index of row (1...n), or 0 if none selected
  158. s32 m_sel_column;
  159. bool m_sel_doubleclick;
  160. // Keyboard navigation stuff
  161. s32 m_keynav_time;
  162. core::stringw m_keynav_buffer;
  163. // Drawing and geometry information
  164. bool m_border;
  165. video::SColor m_color;
  166. video::SColor m_background;
  167. video::SColor m_highlight;
  168. video::SColor m_highlight_text;
  169. s32 m_rowheight;
  170. gui::IGUIFont *m_font;
  171. gui::IGUIScrollBar *m_scrollbar;
  172. // Allocated strings and images
  173. std::vector<core::stringw> m_strings;
  174. std::vector<video::ITexture*> m_images;
  175. std::map<std::string, s32> m_alloc_strings;
  176. std::map<std::string, s32> m_alloc_images;
  177. s32 allocString(const std::string &text);
  178. s32 allocImage(const std::string &imagename);
  179. void allocationComplete();
  180. // Helper for draw() that draws a single cell
  181. void drawCell(const Cell *cell, video::SColor color,
  182. const core::rect<s32> &rowrect,
  183. const core::rect<s32> &client_clip);
  184. // Returns the i-th visible row (NULL if i is invalid)
  185. const Row *getRow(s32 i) const;
  186. // Key navigation helper
  187. bool doesRowStartWith(const Row *row, const core::stringw &str) const;
  188. // Returns the row at a given screen Y coordinate
  189. // Returns index i such that m_rows[i] is valid (or -1 on error)
  190. s32 getRowAt(s32 y, bool &really_hovering) const;
  191. // Returns the cell at a given screen X coordinate within m_rows[row_i]
  192. // Returns index j such that m_rows[row_i].cells[j] is valid
  193. // (or -1 on error)
  194. s32 getCellAt(s32 x, s32 row_i) const;
  195. // Make the selected row fully visible
  196. void autoScroll();
  197. // Should be called when m_rowcount or m_rowheight changes
  198. void updateScrollBar();
  199. // Sends EET_GUI_EVENT / EGET_TABLE_CHANGED to parent
  200. void sendTableEvent(s32 column, bool doubleclick);
  201. // Functions that help deal with hidden rows
  202. // The following functions take raw row indices (hidden rows not skipped)
  203. void getOpenedTrees(std::set<s32> &opened_trees) const;
  204. void setOpenedTrees(const std::set<s32> &opened_trees);
  205. void openTree(s32 to_open);
  206. void closeTree(s32 to_close);
  207. // The following function takes a visible row index (hidden rows skipped)
  208. // dir: -1 = left (close), 0 = auto (toggle), 1 = right (open)
  209. void toggleVisibleTree(s32 row_i, int dir, bool move_selection);
  210. // Aligns cell content in column according to alignment specification
  211. // align = 0: left aligned, 1: centered, 2: right aligned, 3: inline
  212. static void alignContent(Cell *cell, s32 xmax, s32 content_width,
  213. s32 align);
  214. };
  215. #endif