The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
listbox.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef GUI_WIDGETS_LISTBOX_HPP_INCLUDED
16 #define GUI_WIDGETS_LISTBOX_HPP_INCLUDED
17 
18 #ifndef GUI2_EXPERIMENTAL_LISTBOX
19 
22 
25 
26 namespace gui2
27 {
28 
29 // ------------ WIDGET -----------{
30 
31 class tselectable_;
32 namespace implementation
33 {
34 struct tbuilder_listbox;
35 struct tbuilder_horizontal_listbox;
36 }
37 
38 /** The listbox class. */
40 {
43  friend class tdebug_layout_graph;
44 
45 public:
46  /**
47  * Constructor.
48  *
49  * @param has_minimum Does the listbox need to have one item
50  * selected.
51  * @param has_maximum Can the listbox only have one item
52  * selected.
53  * @param placement How are the items placed.
54  * @param select Select an item when selected, if false it
55  * changes the visible state instead.
56  */
57  tlistbox(const bool has_minimum,
58  const bool has_maximum,
59  const tgenerator_::tplacement placement,
60  const bool select);
61 
62  /***** ***** ***** ***** Row handling. ***** ***** ****** *****/
63  /**
64  * When an item in the list is selected by the user we need to
65  * update the state. We installed a callback handler which
66  * calls us.
67  *
68  * @param item The data send to the set_members of the
69  * widgets.
70  * @param index The item before which to add the new item,
71  * 0 == begin, -1 == end.
72  */
73  void add_row(const string_map& item, const int index = -1);
74 
75  /**
76  * Adds single row to the grid.
77  *
78  * This function expect a row to have multiple widgets (either multiple
79  * columns or one column with multiple widgets).
80  *
81  *
82  * @param data The data to send to the set_members of the
83  * widgets. If the member id is not an empty
84  * string it is only send to the widget that has
85  * the wanted id (if any). If the member id is an
86  * empty string, it is send to all members.
87  * Having both empty and non-empty id's gives
88  * undefined behavior.
89  * @param index The item before which to add the new item,
90  * 0 == begin, -1 == end.
91  */
92  void add_row(const std::map<std::string /* widget id */, string_map>& data,
93  const int index = -1);
94 
95  /**
96  * Removes a row in the listbox.
97  *
98  * @param row The row to remove, when not in
99  * range the function is ignored.
100  * @param count The number of rows to remove, 0 means all
101  * rows (starting from row).
102  */
103  void remove_row(const unsigned row, unsigned count = 1);
104 
105  /** Removes all the rows in the listbox, clearing it. */
106  void clear();
107 
108  /** Returns the number of items in the listbox. */
109  unsigned get_item_count() const;
110 
111  /**
112  * Makes a row active or inactive.
113  *
114  * NOTE this doesn't change the select status of the row.
115  *
116  * @param row The row to (de)activate.
117  * @param active true activate, false deactivate.
118  */
119  void set_row_active(const unsigned row, const bool active);
120 
121  /**
122  * Makes a row visible or invisible.
123  *
124  * @param row The row to show or hide.
125  * @param shown true visible, false invisible.
126  */
127  void set_row_shown(const unsigned row, const bool shown);
128 
129  /**
130  * Makes a row visible or invisible.
131  *
132  * Use this version if you want to show hide multiple items since it's
133  * optimized for that purpose, for one it calls the selection changed
134  * callback only once instead of several times.
135  *
136  * @param shown A vector with the show hide status for every
137  * row. The number of items in the vector must
138  * be equal to the number of items in the
139  * listbox.
140  */
141  void set_row_shown(const std::vector<bool>& shown);
142 
143  /**
144  * Returns the grid of the wanted row.
145  *
146  * There's only a const version since allowing callers to modify the grid
147  * behind our backs might give problems. We return a pointer instead of a
148  * reference since dynamic casting of pointers is easier (no try catch
149  * needed).
150  *
151  * @param row The row to get the grid from, the caller has
152  * to make sure the row is a valid row.
153  * @returns The grid of the wanted row.
154  */
155  const tgrid* get_row_grid(const unsigned row) const;
156 
157  /**
158  * The possibly-giving-problems nonconst version of get_row_grid
159  *
160  * @param row The row to get the grid from, the caller has
161  * to make sure the row is a valid row.
162  * @returns The grid of the wanted row.
163  */
164  tgrid* get_row_grid(const unsigned row);
165 
166  /**
167  * Selectes a row.
168  *
169  * @param row The row to select.
170  * @param select Select or deselect the row.
171  */
172  bool select_row(const unsigned row, const bool select = true);
173 
174  /**
175  * Returns the first selected row
176  *
177  * @returns The first selected row.
178  * @retval -1 No row selected.
179  */
180  int get_selected_row() const;
181 
182  /** Function to call after the user clicked on a row. */
183  void list_item_clicked(twidget& caller);
184 
185  /** See @ref tcontainer_::set_self_active. */
186  virtual void set_self_active(const bool active) override;
187 
188  /**
189  * Request to update the size of the content after changing the content.
190  *
191  * When a resize is required the container first can try to handle it
192  * itself. If it can't honor the request the function will call @ref
193  * twindow::invalidate_layout().
194  *
195  * @note Calling this function on a widget with size == (0, 0) results
196  * false but doesn't call invalidate_layout, the engine expects to be in
197  * build up phase with the layout already invalidated.
198  *
199  * @returns True if the resizing succeeded, false
200  * otherwise.
201  */
202  bool update_content_size();
203 
204  /***** ***** ***** ***** inherited ***** ***** ****** *****/
205 
206  /** See @ref twidget::place. */
207  virtual void place(const tpoint& origin, const tpoint& size) override;
208 
209  /** See @ref twidget::layout_children. */
210  virtual void layout_children() override;
211 
212  /** See @ref twidget::child_populate_dirty_list. */
213  virtual void
215  const std::vector<twidget*>& call_stack) override;
216 
217  /***** ***** ***** setters / getters for members ***** ****** *****/
218  void
219  set_callback_item_change(const std::function<void(size_t)>& callback)
220  {
221  callback_item_changed_ = callback;
222  }
223 
224  void
225  set_callback_value_change(const std::function<void(twidget&)>& callback)
226  {
227  callback_value_changed_ = callback;
228  }
229 
231  {
232  list_builder_ = list_builder;
233  }
234 
235  void order_by(const tgenerator_::torder_func& func);
236 
237  void set_column_order(unsigned col, const std::vector<tgenerator_::torder_func>& func);
238 protected:
239  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
240 
241  /** Inherited from tscrollbar_container. */
242  void handle_key_up_arrow(SDLMod modifier, bool& handled);
243 
244  /** Inherited from tscrollbar_container. */
245  void handle_key_down_arrow(SDLMod modifier, bool& handled);
246 
247  /** Inherited from tscrollbar_container. */
248  void handle_key_left_arrow(SDLMod modifier, bool& handled);
249 
250  /** Inherited from tscrollbar_container. */
251  void handle_key_right_arrow(SDLMod modifier, bool& handled);
252 
253 private:
254  /**
255  * @todo A listbox must have the following config parameters in the
256  * instantiation:
257  * - fixed row height?
258  * - fixed column width?
259  * and if so the following ways to set them
260  * - fixed depending on header ids
261  * - fixed depending on footer ids
262  * - fixed depending on first row ids
263  * - fixed depending on list (the user has to enter a list of ids)
264  *
265  * For now it's always fixed width depending on the first row.
266  */
267 
268 
269  /**
270  * Finishes the building initialization of the widget.
271  *
272  * @param header Builder for the header.
273  * @param footer Builder for the footer.
274  * @param list_data The initial data to fill the listbox with.
275  */
276  void finalize(tbuilder_grid_const_ptr header,
278  const std::vector<string_map>& list_data);
279  /**
280  * Contains a pointer to the generator.
281  *
282  * The pointer is not owned by this class, it's stored in the content_grid_
283  * of the tscrollbar_container super class and freed when it's grid is
284  * freed.
285  */
287 
288  const bool is_horizonal_;
289 
290  /** Contains the builder for the new items. */
292 
293  /**
294  * This callback is called when a list item is clicked (toggled).
295  *
296  * The function is passed the index of the toggled item.
297  */
298  std::function<void(size_t)> callback_item_changed_;
299 
300  /**
301  * This callback is called when the value in the listbox changes.
302  *
303  * @todo the implementation of the callback hasn't been tested a lot and
304  * there might be too many calls. That might happen if an arrow up didn't
305  * change the selected item.
306  */
307  std::function<void(twidget&)> callback_value_changed_;
308 
310 
311  typedef std::vector<std::pair<tselectable_*, std::vector<tgenerator_::torder_func> > > torder_list;
312  torder_list orders_;
313  /**
314  * Resizes the content.
315  *
316  * The resize either happens due to resizing the content or invalidate the
317  * layout of the window.
318  *
319  * @param width_modification The wanted modification to the width:
320  * * negative values reduce width.
321  * * zero leave width as is.
322  * * positive values increase width.
323  * @param height_modification The wanted modification to the height:
324  * * negative values reduce height.
325  * * zero leave height as is.
326  * * positive values increase height.
327  */
328  void resize_content(const int width_modification,
329  const int height_modification,
330  const int width__modification_pos = -1,
331  const int height_modification_pos = -1);
332 
333  /**
334  * Resizes the content.
335  *
336  * The resize happens when a new row is added to the contents.
337  *
338  * @param row The new row added to the listbox.
339  */
340  void resize_content(const twidget& row);
341 
342  /** Layouts the children if needed. */
343  void layout_children(const bool force);
344 
345  /** Inherited from tscrollbar_container. */
346  virtual void set_content_size(const tpoint& origin, const tpoint& size);
347 
348  /** See @ref tcontrol::get_control_type. */
349  virtual const std::string& get_control_type() const override;
350 
351  void order_by_column(unsigned column, twidget& widget);
352 };
353 
354 // }---------- DEFINITION ---------{
355 
357 {
358 
359  explicit tlistbox_definition(const config& cfg);
360 
362  {
363  explicit tresolution(const config& cfg);
364 
366  };
367 };
368 
369 // }---------- BUILDER -----------{
370 
371 namespace implementation
372 {
373 
375 {
376  explicit tbuilder_listbox(const config& cfg);
377 
379 
380  twidget* build() const;
381 
384 
387 
389 
390  /**
391  * Listbox data.
392  *
393  * Contains a vector with the data to set in every cell, it's used to
394  * serialize the data in the config, so the config is no longer required.
395  */
396  std::vector<string_map> list_data;
397 
399 };
400 
402 {
403  explicit tbuilder_horizontal_listbox(const config& cfg);
404 
406 
407  twidget* build() const;
408 
411 
413 
414  /**
415  * Listbox data.
416  *
417  * Contains a vector with the data to set in every cell, it's used to
418  * serialize the data in the config, so the config is no longer required.
419  */
420  std::vector<string_map> list_data;
421 };
422 
423 } // namespace implementation
424 
425 // }------------ END --------------
426 
427 } // namespace gui2
428 
429 #endif
430 #endif
virtual void set_content_size(const tpoint &origin, const tpoint &size)
Inherited from tscrollbar_container.
Definition: listbox.cpp:604
Abstract base class for the generator.
Definition: generator.hpp:41
void set_list_builder(tbuilder_grid_ptr list_builder)
Definition: listbox.hpp:230
void finalize(tbuilder_grid_const_ptr header, tbuilder_grid_const_ptr footer, const std::vector< string_map > &list_data)
Finishes the building initialization of the widget.
Definition: listbox.cpp:528
#define SDLMod
Definition: compat.hpp:30
void set_row_shown(const unsigned row, const bool shown)
Makes a row visible or invisible.
Definition: listbox.cpp:150
tbuilder_grid_const_ptr list_builder_
Contains the builder for the new items.
Definition: listbox.hpp:291
void remove_row(const unsigned row, unsigned count=1)
Removes a row in the listbox.
Definition: listbox.cpp:94
std::vector< std::pair< tselectable_ *, std::vector< tgenerator_::torder_func > > > torder_list
Definition: listbox.hpp:311
bool update_content_size()
Request to update the size of the content after changing the content.
Definition: listbox.cpp:272
friend class tdebug_layout_graph
Definition: listbox.hpp:43
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
Definition: listbox.cpp:630
Base container class.
Definition: grid.hpp:29
bool select_row(const unsigned row, const bool select=true)
Selectes a row.
Definition: listbox.cpp:228
tplacement
Determines how the items are placed.
Definition: generator.hpp:51
void set_row_active(const unsigned row, const bool active)
Makes a row active or inactive.
Definition: listbox.cpp:144
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
std::function< bool(unsigned, unsigned)> torder_func
Definition: generator.hpp:239
Base class of a resolution, contains the common keys for a resolution.
virtual void layout_children() override
See twidget::layout_children.
Definition: listbox.cpp:367
void order_by_column(unsigned column, twidget &widget)
Definition: listbox.cpp:565
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
virtual twidget * build() const =0
void order_by(const tgenerator_::torder_func &func)
Definition: listbox.cpp:588
unsigned get_item_count() const
Returns the number of items in the listbox.
Definition: listbox.cpp:138
void add_row(const string_map &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition: listbox.cpp:74
virtual void set_self_active(const bool active) override
See tcontainer_::set_self_active.
Definition: listbox.cpp:267
bool need_layout_
Definition: listbox.hpp:309
void handle_key_up_arrow(SDLMod modifier, bool &handled)
Inherited from tscrollbar_container.
Definition: listbox.cpp:384
tscrollbar_container::tscrollbar_mode vertical_scrollbar_mode
Definition: listbox.hpp:409
tgenerator_ * generator_
Contains a pointer to the generator.
Definition: listbox.hpp:286
void set_column_order(unsigned col, const std::vector< tgenerator_::torder_func > &func)
Definition: listbox.cpp:596
tlistbox(const bool has_minimum, const bool has_maximum, const tgenerator_::tplacement placement, const bool select)
Constructor.
Definition: listbox.cpp:60
std::vector< string_map > list_data
Listbox data.
Definition: listbox.hpp:420
tscrollbar_mode
The way to handle the showing or hiding of the scrollbar.
void resize_content(const int width_modification, const int height_modification, const int width__modification_pos=-1, const int height_modification_pos=-1)
Resizes the content.
Definition: listbox.cpp:316
const bool is_horizonal_
Definition: listbox.hpp:288
GLuint GLuint GLsizei count
Definition: glew.h:1221
std::map< std::string, t_string > string_map
Definition: generator.hpp:23
void handle_key_down_arrow(SDLMod modifier, bool &handled)
Inherited from tscrollbar_container.
Definition: listbox.cpp:411
GLenum GLenum GLvoid GLvoid * column
Definition: glew.h:3805
tscrollbar_container::tscrollbar_mode horizontal_scrollbar_mode
Definition: listbox.hpp:383
tlistbox_definition(const config &cfg)
Definition: listbox.cpp:638
GLuint index
Definition: glew.h:1782
torder_list orders_
Definition: listbox.hpp:312
void handle_key_right_arrow(SDLMod modifier, bool &handled)
Inherited from tscrollbar_container.
Definition: listbox.cpp:465
The listbox class.
Definition: listbox.hpp:39
Holds a 2D point.
Definition: point.hpp:24
GLsizeiptr size
Definition: glew.h:1649
GLenum GLenum GLvoid * row
Definition: glew.h:3805
std::function< void(twidget &)> callback_value_changed_
This callback is called when the value in the listbox changes.
Definition: listbox.hpp:307
Base class for all widgets.
Definition: widget.hpp:49
std::vector< string_map > list_data
Listbox data.
Definition: listbox.hpp:396
void set_callback_value_change(const std::function< void(twidget &)> &callback)
Definition: listbox.hpp:225
tscrollbar_container::tscrollbar_mode horizontal_scrollbar_mode
Definition: listbox.hpp:410
void set_callback_item_change(const std::function< void(size_t)> &callback)
Definition: listbox.hpp:219
tscrollbar_container::tscrollbar_mode vertical_scrollbar_mode
Definition: listbox.hpp:382
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
void handle_key_left_arrow(SDLMod modifier, bool &handled)
Inherited from tscrollbar_container.
Definition: listbox.cpp:438
void list_item_clicked(twidget &caller)
Function to call after the user clicked on a row.
Definition: listbox.cpp:244
virtual void child_populate_dirty_list(twindow &caller, const std::vector< twidget * > &call_stack) override
See twidget::child_populate_dirty_list.
Definition: listbox.cpp:373
int get_selected_row() const
Returns the first selected row.
Definition: listbox.cpp:237
GLsizei const GLcharARB ** string
Definition: glew.h:4503
virtual void place(const tpoint &origin, const tpoint &size) override
See twidget::place.
Definition: listbox.cpp:291
void clear()
Removes all the rows in the listbox, clearing it.
Definition: listbox.cpp:131
const tgrid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
Definition: listbox.cpp:215
Contains the implementation details for lexical_cast and shouldn't be used directly.
Base class for creating containers with one or two scrollbar(s).
std::function< void(size_t)> callback_item_changed_
This callback is called when a list item is clicked (toggled).
Definition: listbox.hpp:298