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