The Battle for Wesnoth  1.15.12+dev
listbox.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://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 #pragma once
16 
19 
22 
23 #include "preferences/general.hpp"
24 
25 #include <boost/dynamic_bitset.hpp>
26 #include <functional>
27 
28 namespace gui2
29 {
30 // ------------ WIDGET -----------{
31 
32 class selectable_item;
33 namespace implementation
34 {
35 struct builder_listbox;
36 struct builder_horizontal_listbox;
37 struct builder_grid_listbox;
38 struct builder_styled_widget;
39 }
40 
41 /** The listbox class. */
43 {
47  friend class debug_layout_graph;
48 
49 public:
50  /**
51  * Constructor.
52  *
53  * @param builder The builder for the appropriate listbox variant.
54  * @param placement How are the items placed.
55  * @param list_builder Grid builder for the listbox definition grid.
56  * @param has_minimum Does the listbox need to have one item selected.
57  * @param has_maximum Can the listbox only have one item selected.
58  * @param select Select an item when selected. If false it changes
59  * the visible state instead. Default true.
60  */
62  const generator_base::placement placement,
63  builder_grid_ptr list_builder,
64  const bool has_minimum,
65  const bool has_maximum,
66  const bool select = true);
67 
68  /***** ***** ***** ***** Row handling. ***** ***** ****** *****/
69  /**
70  * When an item in the list is selected by the user we need to
71  * update the state. We installed a callback handler which
72  * calls us.
73  *
74  * @param item The data send to the set_members of the
75  * widgets.
76  * @param index The item before which to add the new item,
77  * 0 == begin, -1 == end.
78  */
79  grid& add_row(const string_map& item, const int index = -1);
80 
81  /**
82  * Adds single row to the grid.
83  *
84  * This function expect a row to have multiple widgets (either multiple
85  * columns or one column with multiple widgets).
86  *
87  *
88  * @param data The data to send to the set_members of the
89  * widgets. If the member id is not an empty
90  * string it is only send to the widget that has
91  * the wanted id (if any). If the member id is an
92  * empty string, it is send to all members.
93  * Having both empty and non-empty id's gives
94  * undefined behavior.
95  * @param index The item before which to add the new item,
96  * 0 == begin, -1 == end.
97  */
98  grid& add_row(const std::map<std::string /* widget id */, string_map>& data, const int index = -1);
99 
100  /**
101  * Removes a row in the listbox.
102  *
103  * @param row The row to remove, when not in
104  * range the function is ignored.
105  * @param count The number of rows to remove, 0 means all
106  * rows (starting from row).
107  */
108  void remove_row(const unsigned row, unsigned count = 1);
109 
110  /** Removes all the rows in the listbox, clearing it. */
111  void clear();
112 
113  /** Returns the number of items in the listbox. */
114  unsigned get_item_count() const;
115 
116  /**
117  * Makes a row active or inactive.
118  *
119  * NOTE this doesn't change the select status of the row.
120  *
121  * @param row The row to (de)activate.
122  * @param active true activate, false deactivate.
123  */
124  void set_row_active(const unsigned row, const bool active);
125 
126  /**
127  * Makes a row visible or invisible.
128  *
129  * @param row The row to show or hide.
130  * @param shown true visible, false invisible.
131  */
132  void set_row_shown(const unsigned row, const bool shown);
133 
134  /**
135  * Makes a row visible or invisible.
136  *
137  * Use this version if you want to show hide multiple items since it's
138  * optimized for that purpose, for one it calls the selection changed
139  * callback only once instead of several times.
140  *
141  * @param shown A vector with the show hide status for every
142  * row. The number of items in the vector must
143  * be equal to the number of items in the
144  * listbox.
145  */
146  void set_row_shown(const boost::dynamic_bitset<>& shown);
147 
148  /**
149  * Returns a list of visible rows
150  *
151  * @returns A mask indicating which rows are visible
152  */
153  boost::dynamic_bitset<> get_rows_shown() const;
154 
155  bool any_rows_shown() const;
156 
157  /**
158  * Returns the grid of the wanted row.
159  *
160  * There's only a const version since allowing callers to modify the grid
161  * behind our backs might give problems. We return a pointer instead of a
162  * reference since dynamic casting of pointers is easier (no try catch
163  * needed).
164  *
165  * @param row The row to get the grid from, the caller has
166  * to make sure the row is a valid row.
167  * @returns The grid of the wanted row.
168  */
169  const grid* get_row_grid(const unsigned row) const;
170 
171  /**
172  * The possibly-giving-problems nonconst version of get_row_grid
173  *
174  * @param row The row to get the grid from, the caller has
175  * to make sure the row is a valid row.
176  * @returns The grid of the wanted row.
177  */
178  grid* get_row_grid(const unsigned row);
179 
180  /**
181  * Selects a row.
182  *
183  * @param row The row to select.
184  * @param select Select or deselect the row.
185  * @returns True if the operation succeeded.
186  */
187  bool select_row(const unsigned row, const bool select = true);
188 
189  /**
190  * Does exactly as advertised: selects the list's last row.
191  *
192  * @param select Select or deselect the row.
193  */
194  bool select_last_row(const bool select = true)
195  {
196  return select_row(get_item_count() - 1, select);
197  }
198 
199  /**
200  * Selects a row at the given position, regardless of sorting order.
201  *
202  * When using @ref select_row the relevant row is located by index regardless
203  * of its actual position in the list, which could differ if the list had been
204  * sorted. In that case, `select_row(0)` would not select the list's first row
205  * as displayed.
206  *
207  * This function allows row selection based on position. `select_row_at(0)` will
208  * always select the list's first row, regardless of sorting order.
209  *
210  * @param row The row to select.
211  * @param select Select or deselect the row.
212  *
213  * @returns True if the operation succeeded.
214  */
215  bool select_row_at(const unsigned row, const bool select = true);
216 
217  /**
218  * Check if a row is selected
219  * @param row The row to test
220  * @returns True if it is selected.
221  */
222  bool row_selected(const unsigned row);
223 
224  /**
225  * Returns the first selected row
226  *
227  * @returns The first selected row, or -1 if no row is selected.
228  */
229  int get_selected_row() const;
230 
231  /** Function to call after the user clicked on a row. */
232  void list_item_clicked(widget& caller);
233 
234  /** See @ref container_base::set_self_active. */
235  virtual void set_self_active(const bool active) override;
236 
237  /**
238  * Request to update the size of the content after changing the content.
239  *
240  * When a resize is required the container first can try to handle it
241  * itself. If it can't honor the request the function will call @ref
242  * window::invalidate_layout().
243  *
244  * @note Calling this function on a widget with size == (0, 0) results
245  * false but doesn't call invalidate_layout, the engine expects to be in
246  * build up phase with the layout already invalidated.
247  *
248  * @returns True if the resizing succeeded, false
249  * otherwise.
250  */
251  bool update_content_size();
252 
253  /***** ***** ***** ***** inherited ***** ***** ****** *****/
254 
255  /** See @ref widget::place. */
256  virtual void place(const point& origin, const point& size) override;
257 
258  /** See @ref widget::layout_children. */
259  virtual void layout_children() override;
260 
261  /** See @ref widget::child_populate_dirty_list. */
262  virtual void child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack) override;
263 
264  /***** ***** ***** setters / getters for members ***** ****** *****/
265 
266  void order_by(const generator_base::order_func& func);
267 
268  void set_column_order(unsigned col, const generator_sort_array& func);
269 
270  template<typename Func>
271  void register_sorting_option(const int col, const Func& f)
272  {
273  set_column_order(col, {{
274  [f](int lhs, int rhs) { return f(lhs) < f(rhs); },
275  [f](int lhs, int rhs) { return f(lhs) > f(rhs); }
276  }});
277  }
278 
279  using translatable_sorter_func_t = std::function<std::string(const int)>;
280 
281  /** Registers a special sorting function specifically for translatable values. */
282  void register_translatable_sorting_option(const int col, translatable_sorter_func_t f);
283 
284  using order_pair = std::pair<int, preferences::SORT_ORDER>;
285 
286  /**
287  * Sorts the listbox by a pre-set sorting option. The corresponding header widget will also be toggled.
288  * The sorting option should already have been registered by @ref listbox::register_sorting_option().
289  *
290  * @param sort_by Pair of column index and sort direction. The column (first arguemnt)
291  * argument will be sorted in the specified direction (second argument)
292  *
293  * @param select_first If true, the first row post-sort will be selected. If false (default),
294  * the selected row will be maintained post-sort as per standard sorting
295  * functionality.
296  */
297  void set_active_sorting_option(const order_pair& sort_by, const bool select_first = false);
298 
299  const order_pair get_active_sorting_option();
300 
301  /** Deactivates all sorting toggle buttons at the top, making the list look like it's not sorted. */
302  void mark_as_unsorted();
303 
304  /** Registers a callback to be called when the active sorting option changes. */
305  void set_callback_order_change(std::function<void(unsigned, preferences::SORT_ORDER)> callback)
306  {
307  callback_order_change_ = callback;
308  }
309 
310 protected:
311  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
312 
313  /** Inherited from scrollbar_container. */
314  void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) override;
315 
316  /** Inherited from scrollbar_container. */
317  void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) override;
318 
319  /** Inherited from scrollbar_container. */
320  void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) override;
321 
322  /** Inherited from scrollbar_container. */
323  void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) override;
324 
325 private:
326  /** See @ref widget::calculate_best_size. */
327  virtual point calculate_best_size() const override;
328 
329  enum KEY_SCROLL_DIRECTION { KEY_VERTICAL, KEY_HORIZONTAL };
330 
331  /** Helper to update visible area after a key event. */
332  void update_visible_area_on_key_event(const KEY_SCROLL_DIRECTION direction);
333 
334  /**
335  * @todo A listbox must have the following config parameters in the
336  * instantiation:
337  * - fixed row height?
338  * - fixed column width?
339  * and if so the following ways to set them
340  * - fixed depending on header ids
341  * - fixed depending on footer ids
342  * - fixed depending on first row ids
343  * - fixed depending on list (the user has to enter a list of ids)
344  *
345  * For now it's always fixed width depending on the first row.
346  */
347 
348  /**
349  * Finishes the building initialization of the widget.
350  *
351  * @param header Builder for the header.
352  * @param footer Builder for the footer.
353  * @param list_data The initial data to fill the listbox with.
354  */
355  void finalize(builder_grid_const_ptr header,
356  builder_grid_const_ptr footer,
357  const std::vector<std::map<std::string, string_map>>& list_data);
358  /**
359  * Contains a pointer to the generator.
360  *
361  * The pointer is not owned by this class, it's stored in the content_grid_
362  * of the scrollbar_container super class and freed when it's grid is
363  * freed.
364  */
366 
367  const bool is_horizontal_;
368 
369  /** Contains the builder for the new items. */
371 
373 
374  typedef std::vector<std::pair<selectable_item*, generator_sort_array>> torder_list;
375  torder_list orders_;
376 
377  std::function<void(unsigned, preferences::SORT_ORDER)> callback_order_change_;
378 
379  /**
380  * Resizes the content.
381  *
382  * The resize either happens due to resizing the content or invalidate the
383  * layout of the window.
384  *
385  * @param width_modification The wanted modification to the width:
386  * * negative values reduce width.
387  * * zero leave width as is.
388  * * positive values increase width.
389  * @param height_modification The wanted modification to the height:
390  * * negative values reduce height.
391  * * zero leave height as is.
392  * * positive values increase height.
393  * @param width_modification_pos
394  * @param height_modification_pos
395  */
396  void resize_content(const int width_modification,
397  const int height_modification,
398  const int width_modification_pos = -1,
399  const int height_modification_pos = -1);
400 
401  /**
402  * Resizes the content.
403  *
404  * The resize happens when a new row is added to the contents.
405  *
406  * @param row The new row added to the listbox.
407  */
408  void resize_content(const widget& row);
409 
410  /** Layouts the children if needed. */
411  void layout_children(const bool force);
412 
413  /** Inherited from scrollbar_container. */
414  virtual void set_content_size(const point& origin, const point& size) override;
415 
416 public:
417  /** Static type getter that does not rely on the widget being constructed. */
418  static const std::string& type();
419 
420 private:
421  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
422  virtual const std::string& get_control_type() const override;
423 
424  void order_by_column(unsigned column, widget& widget);
425 };
426 
427 // }---------- DEFINITION ---------{
428 
430 {
431  explicit listbox_definition(const config& cfg);
432 
434  {
435  explicit resolution(const config& cfg);
436 
438  };
439 };
440 
441 // }---------- BUILDER -----------{
442 
443 namespace implementation
444 {
445 /**
446  * @ingroup GUIWidgetWML
447  *
448  * A listbox is a control that holds several items of the same type.
449  * Normally the items in a listbox are ordered in rows, this version might allow more options for ordering the items in the future.
450  * The definition of a listbox contains the definition of its scrollbar:
451  * Key |Type |Default |Description
452  * -------------------------|------------------------------------|------------|-------------
453  * scrollbar | @ref guivartype_section "section" |mandatory |A grid containing the widgets for the scrollbar. The scrollbar has some special widgets so it can make default behavior for certain widgets.
454  * The resolution for a listbox also contains the following keys:
455  * ID (return value) |Type |Mandatory |Description
456  * -------------------------|--------------------|------------|-------------
457  * _begin | clickable |no |Moves the position to the beginning of the list.
458  * _line_up | clickable |no |Move the position one item up. (NOTE: if too many items to move per item it might be more items.)
459  * _half_page_up | clickable |no |Move the position half the number of the visible items up. (See note at _line_up.)
460  * _page_up | clickable |no |Move the position the number of visible items up. (See note at _line_up.)
461  * _end | clickable |no |Moves the position to the end of the list.
462  * _line_down | clickable |no |Move the position one item down.(See note at _line_up.)
463  * _half_page_down | clickable |no |Move the position half the number of the visible items down. (See note at _line_up.)
464  * _page_down | clickable |no |Move the position the number of visible items down. (See note at _line_up.)
465  * _scrollbar | vertical_scrollbar |yes |This is the scrollbar so the user can scroll through the list.
466  * A clickable is one of:
467  * * button
468  * * repeating_button
469  * The following states exist:
470  * * state_enabled - the listbox is enabled.
471  * * state_disabled - the listbox is disabled.
472  * List with the listbox specific variables:
473  * Key |Type |Default |Description
474  * -------------------------|------------------------------------------------|------------|-------------
475  * vertical_scrollbar_mode | @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
476  * horizontal_scrollbar_mode| @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
477  * header | @ref guivartype_grid "grid" |[] |Defines the grid for the optional header. (This grid will automatically get the id _header_grid.)
478  * footer | @ref guivartype_grid "grid" |[] |Defines the grid for the optional footer. (This grid will automatically get the id _footer_grid.)
479  * list_definition | @ref guivartype_section "section" |mandatory |This defines how a listbox item looks. It must contain the grid definition for 1 row of the list.
480  * list_data | @ref guivartype_section "section" |[] |A grid alike section which stores the initial data for the listbox. Every row must have the same number of columns as the 'list_definition'.
481  * has_minimum | @ref guivartype_bool "bool" |true |If false, less than one row can be selected.
482  * has_maximum | @ref guivartype_bool "bool" |true |If false, more than one row can be selected.
483  * In order to force widgets to be the same size inside a listbox, the widgets need to be inside a linked_group. Inside the list section there are only the following widgets allowed:
484  * * grid (to nest)
485  * * toggle_button
486  * * toggle_panel
487  */
489 {
490  explicit builder_listbox(const config& cfg);
491 
493 
494  virtual widget* build() const override;
495 
498 
501 
503 
504  /**
505  * Listbox data.
506  *
507  * Contains a vector with the data to set in every cell, it's used to
508  * serialize the data in the config, so the config is no longer required.
509  */
510  std::vector<std::map<std::string, string_map>> list_data;
511 
512  bool has_minimum_, has_maximum_;
513 };
514 
515 /**
516  * @ingroup GUIWidgetWML
517  *
518  * A horizontal listbox is a control that holds several items of the same type. Normally the items in a listbox are ordered in rows, this version orders them in columns instead. The definition of a horizontal listbox is the same as for a normal listbox.
519  *
520  * List with the horizontal listbox specific variables:
521  * Key |Type |Default |Description
522  * -------------------------|------------------------------------------------|------------|-------------
523  * vertical_scrollbar_mode | @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
524  * horizontal_scrollbar_mode| @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
525  * list_definition | @ref guivartype_section "section" |mandatory |This defines how a listbox item looks. It must contain the grid definition for 1 column of the list.
526  * list_data | @ref guivartype_section "section" |[] |A grid alike section which stores the initial data for the listbox. Every row must have the same number of columns as the 'list_definition'.
527  * has_minimum | @ref guivartype_bool "bool" |true |If false, less than one row can be selected.
528  * has_maximum | @ref guivartype_bool "bool" |true |If false, more than one row can be selected.
529  *
530  * In order to force widgets to be the same size inside a horizontal listbox, the widgets need to be inside a linked_group.
531  * Inside the list section there are only the following widgets allowed:
532  * * grid (to nest)
533  * * toggle_button
534  * * toggle_panel
535  */
537 {
538  explicit builder_horizontal_listbox(const config& cfg);
539 
541 
542  virtual widget* build() const override;
543 
546 
548 
549  /**
550  * Listbox data.
551  *
552  * Contains a vector with the data to set in every cell, it's used to
553  * serialize the data in the config, so the config is no longer required.
554  */
555  std::vector<std::map<std::string, string_map>> list_data;
556 
557  bool has_minimum_, has_maximum_;
558 };
559 
560 /**
561  * @ingroup GUIWidgetWML
562  *
563  * A grid listbox is a styled_widget that holds several items of the same type.
564  * Normally the items in a listbox are ordered in rows, this version orders them in a grid instead.
565  *
566  * List with the grid listbox specific variables:
567  * Key |Type |Default |Description
568  * -------------------------|------------------------------------------------|------------|-------------
569  * vertical_scrollbar_mode | @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
570  * horizontal_scrollbar_mode| @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
571  * list_definition | @ref guivartype_section "section" |mandatory |This defines how a listbox item looks. It must contain the grid definition for 1 column of the list.
572  * list_data | @ref guivartype_section "section" |[] |A grid alike section which stores the initial data for the listbox. Every row must have the same number of columns as the 'list_definition'.
573  * has_minimum | @ref guivartype_bool "bool" |true |If false, less than one row can be selected.
574  * has_maximum | @ref guivartype_bool "bool" |true |If false, more than one row can be selected.
575  *
576  * In order to force widgets to be the same size inside a horizontal listbox, the widgets need to be inside a linked_group.
577  * Inside the list section there are only the following widgets allowed:
578  * * grid (to nest)
579  * * toggle_button
580  * * toggle_panel
581  */
583 {
584  explicit builder_grid_listbox(const config& cfg);
585 
587 
588  virtual widget* build() const override;
589 
592 
594 
595  /**
596  * Listbox data.
597  *
598  * Contains a vector with the data to set in every cell, it's used to
599  * serialize the data in the config, so the config is no longer required.
600  */
601  std::vector<std::map<std::string, string_map>> list_data;
602 
603  bool has_minimum_, has_maximum_;
604 };
605 
606 } // namespace implementation
607 
608 // }------------ END --------------
609 
610 } // namespace gui2
Base class of a resolution, contains the common keys for a resolution.
virtual widget * build() const =0
std::pair< int, preferences::SORT_ORDER > order_pair
Definition: listbox.hpp:284
preferences::SORT_ORDER SORT_ORDER
Definition: listbox.cpp:41
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
Definition: listbox.hpp:497
A grid listbox is a styled_widget that holds several items of the same type.
Definition: listbox.hpp:582
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
Definition: listbox.hpp:545
Base class for all widgets.
Definition: widget.hpp:49
std::function< bool(unsigned, unsigned)> order_func
Definition: generator.hpp:248
void clear(const std::string &key)
Definition: general.cpp:203
bool select_last_row(const bool select=true)
Does exactly as advertised: selects the list&#39;s last row.
Definition: listbox.hpp:194
bool need_layout_
Definition: listbox.hpp:372
A horizontal listbox is a control that holds several items of the same type.
Definition: listbox.hpp:536
torder_list orders_
Definition: listbox.hpp:375
Generic file dialog.
Definition: field-fwd.hpp:22
The listbox class.
Definition: listbox.hpp:42
Base container class.
Definition: grid.hpp:30
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
Definition: listbox.hpp:590
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
Definition: listbox.hpp:591
Abstract base class for the generator.
Definition: generator.hpp:37
std::vector< std::pair< selectable_item *, generator_sort_array > > torder_list
Definition: listbox.hpp:374
std::vector< std::map< std::string, string_map > > list_data
Listbox data.
Definition: listbox.hpp:510
builder_grid_const_ptr list_builder_
Contains the builder for the new items.
Definition: listbox.hpp:370
void set_callback_order_change(std::function< void(unsigned, preferences::SORT_ORDER)> callback)
Registers a callback to be called when the active sorting option changes.
Definition: listbox.hpp:305
static thread_local std::deque< std::string > call_stack
For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL ...
Definition: function.cpp:46
placement
Determines how the items are placed.
Definition: generator.hpp:47
std::vector< std::map< std::string, string_map > > list_data
Listbox data.
Definition: listbox.hpp:555
Base class for creating containers with one or two scrollbar(s).
A listbox is a control that holds several items of the same type.
Definition: listbox.hpp:488
std::function< void(unsigned, preferences::SORT_ORDER)> callback_order_change_
Definition: listbox.hpp:377
std::map< std::string, t_string > string_map
Definition: widget.hpp:26
std::array< generator_base::order_func, 2 > generator_sort_array
Definition: generator.hpp:389
Holds a 2D point.
Definition: point.hpp:23
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
std::shared_ptr< const builder_grid > builder_grid_const_ptr
scrollbar_mode
The way to handle the showing or hiding of the scrollbar.
std::vector< std::map< std::string, string_map > > list_data
Listbox data.
Definition: listbox.hpp:601
#define f
const bool is_horizontal_
Definition: listbox.hpp:367
point resolution()
Definition: general.cpp:387
std::unique_ptr< window > build(const builder_window::window_resolution &definition)
Builds a window.
generator_base * generator_
Contains a pointer to the generator.
Definition: listbox.hpp:365
void register_sorting_option(const int col, const Func &f)
Definition: listbox.hpp:271
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
std::function< std::string(const int)> translatable_sorter_func_t
Definition: listbox.hpp:279
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
Definition: listbox.hpp:544
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:64
std::shared_ptr< builder_grid > builder_grid_ptr
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
Definition: listbox.hpp:496
Contains the implementation details for lexical_cast and shouldn&#39;t be used directly.
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:409