guiTable.h 7.1 KB

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