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