The Battle for Wesnoth  1.17.4+dev
generator.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2022
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "widget.hpp"
19 
20 #include <boost/dynamic_bitset.hpp>
21 
22 #include <array>
23 
24 namespace gui2
25 {
26 struct builder_grid;
27 
28 class generator_base;
29 class grid;
30 
31 /**
32  * Abstract base class for the generator.
33  *
34  * A generator is a class which holds multiple grids and controls their
35  * placement on the screen. The final class is policy based, more info about
36  * the possible policies is documented in the build() function. This function
37  * is the factory to generate the classes as well.
38  */
39 class generator_base : public widget
40 {
41  friend class debug_layout_graph;
42 
43 public:
44  virtual ~generator_base()
45  {
46  }
47 
48  /** Determines how the items are placed. */
49  enum placement {
54  };
55 
56  /**
57  * Create a new generator.
58  *
59  * @param has_minimum Does one item need to be selected?
60  * @param has_maximum Is one the maximum number of items that can
61  * be selected?
62  * @param placement The placement of the grids, see placement
63  * for more info.
64  * @param select If a grid is selected, what should happen?
65  * If true the grid is selected, if false the
66  * grid is shown.
67  *
68  * @returns A pointer to a new object. The caller gets
69  * ownership of the new object.
70  */
71  static std::unique_ptr<generator_base> build(const bool has_minimum,
72  const bool has_maximum,
73  const placement placement,
74  const bool select);
75 
76  /**
77  * Deletes an item.
78  */
79  virtual void delete_item(const unsigned index) = 0;
80 
81  /** Deletes all items. */
82  virtual void clear() = 0;
83 
84  /**
85  * (De)selects an item.
86  *
87  * @param index The item to (de)select.
88  * @param select If true selects, if false deselects.
89  */
90  virtual void select_item(const unsigned index, const bool select) = 0;
91 
92  /**
93  * Toggles the selection state of an item.
94  *
95  * @param index The item to toggle.
96  */
97  void toggle_item(const unsigned index)
98  {
99  select_item(index, !is_selected(index));
100  }
101 
102  /** Returns whether the item is selected. */
103  virtual bool is_selected(const unsigned index) const = 0;
104 
105  /**
106  * Shows or hides an item.
107  *
108  * The caller is responsible for reformatting the grid. If a selected item
109  * is hidden then it will be automatically deselected; if no items are
110  * shown then no items will be selected, even if has_minimum was requested.
111  *
112  * @param index The item to show or hide.
113  * @param show If true shows the item, else hides it.
114  */
115  virtual void set_item_shown(const unsigned index, const bool show) = 0;
116 
117  /** Returns whether the item is shown. */
118  virtual bool get_item_shown(const unsigned index) const = 0;
119 
120  /** Returns the visibility of all the items as a bit set. */
121  boost::dynamic_bitset<> get_items_shown() const
122  {
123  boost::dynamic_bitset<> items_shown(get_item_count());
124  for (unsigned int i = 0u; i < get_item_count(); ++i)
125  {
126  items_shown[i] = get_item_shown(i);
127  }
128  return items_shown;
129  }
130 
131  /** Returns the number of items. */
132  virtual unsigned get_item_count() const = 0;
133 
134  /** Returns the number of selected items. */
135  virtual unsigned get_selected_item_count() const = 0;
136 
137  /**
138  * Returns the selected item.
139  *
140  * If a list has multiple selected items it looks whether it knows the last
141  * item actually selected, if that item is selected that one is chosen.
142  * Else is goes through all selected items and returns the first one
143  * selected.
144  *
145  * @note stacked_widget depends on that behavior it always has all items
146  * selected and thus shown and by default the last selected item (the top
147  * one) is active.
148  *
149  * @returns The selected item, -1 if none selected.
150  */
151  virtual int get_selected_item() const = 0;
152 
153  /** Gets the grid of an item. */
154  virtual grid& item(const unsigned index) = 0;
155 
156  /** Gets the grid of an item. */
157  virtual const grid& item(const unsigned index) const = 0;
158 
159  /***** ***** ***** ***** Create items ***** ***** ***** *****/
160 
161  /**
162  * Creates a new item.
163  *
164  * The item_data is used for the first widget found, this normally should
165  * be used when there's one widget in an item.
166  *
167  * @param index The item before which to add the new item,
168  * 0 == begin, -1 == end.
169  * @param list_builder A grid builder that's will build the
170  * contents of the new item.
171  * @param item_data The data to initialize the parameters of
172  * the new item.
173  * @param callback The callback function to call when an item
174  * in the grid is (de)selected.
175  *
176  * @returns A reference to the newly created grid.
177  */
178  virtual grid& create_item(const int index,
179  const builder_grid& list_builder,
180  const string_map& item_data,
181  const std::function<void(widget&)>& callback)
182  = 0;
183 
184  /**
185  * Creates a new item.
186  *
187  * The item_data is used by id, and is meant to set multiple widgets in
188  * an item.
189  *
190  * @param index The item before which to add the new item,
191  * 0 == begin, -1 == end.
192  * @param list_builder A grid builder that's will build the
193  * contents of the new item.
194  * @param data The data to initialize the parameters of
195  * the new item.
196  * @param callback The callback function to call when an item
197  * in the grid is (de)selected.
198  *
199  * @returns A reference to the newly created grid.
200  */
201  virtual grid&
202  create_item(const int index,
203  const builder_grid& list_builder,
204  const std::map<std::string /* widget id */, string_map>& data,
205  const std::function<void(widget&)>& callback) = 0;
206 
207  /**
208  * Creates one or more new item(s).
209  *
210  * For every item in item_data a new item is generated. This version
211  * expects one widget per item.
212  *
213  * @param index The item before which to add the new item,
214  * 0 == begin, -1 == end.
215  * @param list_builder A grid builder that's will build the
216  * contents of the new item.
217  * @param data The data to initialize the parameters of
218  * the new item.
219  * @param callback The callback function to call when an item
220  * in the grid is (de)selected.
221  */
222  virtual void create_items(const int index,
223  const builder_grid& list_builder,
224  const std::vector<string_map>& data,
225  const std::function<void(widget&)>& callback)
226  = 0;
227 
228  /**
229  * Creates one or more new item(s).
230  *
231  * For every item in item_data a new item is generated. This version
232  * expects multiple widgets per item.
233  *
234  * @param index The item before which to add the new item,
235  * 0 == begin, -1 == end.
236  * @param list_builder A grid builder that's will build the
237  * contents of the new item.
238  * @param data The data to initialize the parameters of
239  * the new item.
240  * @param callback The callback function to call when an item
241  * in the grid is (de)selected.
242  */
243  virtual void create_items(
244  const int index,
245  const builder_grid& list_builder,
246  const std::vector<std::map<std::string /*widget id*/, string_map>>&
247  data,
248  const std::function<void(widget&)>& callback) = 0;
249 
250  typedef std::function<bool (unsigned, unsigned)> order_func;
251  virtual void set_order(const order_func& order) = 0;
252 
253  /***** ***** ***** ***** Inherited ***** ***** ***** *****/
254 
255  /*
256  * These functions must be defined in our child classes so make sure they
257  * become pure virtuals.
258  */
259 
260  /** See @ref widget::layout_initialize. */
261  virtual void layout_initialize(const bool full_initialization) override = 0;
262 
263  /** See @ref widget::request_reduce_width. */
264  virtual void request_reduce_width(const unsigned maximum_width) override
265  = 0;
266 
267  /** See @ref widget::request_reduce_height. */
268  virtual void request_reduce_height(const unsigned maximum_height) override
269  = 0;
270 
271  /** See @ref widget::calculate_best_size. */
272  virtual point calculate_best_size() const override = 0;
273 
274  /** See @ref widget::place. */
275  virtual void place(const point& origin, const point& size) override = 0;
276 
277  /** See @ref widget::set_origin. */
278  virtual void set_origin(const point& origin) override = 0;
279 
280  /** See @ref widget::set_visible_rectangle. */
281  virtual void set_visible_rectangle(const SDL_Rect& rectangle) override = 0;
282 
283  /** See @ref widget::impl_draw_children. */
284  virtual void impl_draw_children(int x_offset, int y_offset) override = 0;
285 
286 protected:
287  /** See @ref widget::child_populate_dirty_list. */
288  virtual void
290  const std::vector<widget*>& call_stack) override
291  = 0;
292 
293 public:
294  /** See @ref widget::find_at. */
295  virtual widget* find_at(const point& coordinate,
296  const bool must_be_active) override = 0;
297 
298  /** See @ref widget::find_at. */
299  virtual const widget* find_at(const point& coordinate,
300  const bool must_be_active) const override
301  = 0;
302 
303  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
304 
305  /**
306  * Up arrow key pressed.
307  *
308  * @param modifier The SDL keyboard modifier when the key was
309  * pressed.
310  * @param handled If the function handles the key it should
311  * set handled to true else do not modify it.
312  * This is used in the keyboard event
313  * changing.
314  */
315  virtual void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) = 0;
316 
317  /**
318  * Down arrow key pressed.
319  *
320  * @param modifier The SDL keyboard modifier when the key was
321  * pressed.
322  * @param handled If the function handles the key it should
323  * set handled to true else do not modify it.
324  * This is used in the keyboard event
325  * changing.
326  */
327  virtual void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) = 0;
328 
329  /**
330  * Left arrow key pressed.
331  *
332  * @param modifier The SDL keyboard modifier when the key was
333  * pressed.
334  * @param handled If the function handles the key it should
335  * set handled to true else do not modify it.
336  * This is used in the keyboard event
337  * changing.
338  */
339  virtual void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) = 0;
340 
341  /**
342  * Right arrow key pressed.
343  *
344  * @param modifier The SDL keyboard modifier when the key was
345  * pressed.
346  * @param handled If the function handles the key it should
347  * set handled to true else do not modify it.
348  * This is used in the keyboard event
349  * changing.
350  */
351  virtual void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) = 0;
352 
353 protected:
354  /**
355  * Selects a not selected item.
356  *
357  * @param index The index of a not selected item.
358  */
359  virtual void do_select_item(const unsigned index) = 0;
360 
361  /**
362  * Deselects a selected item.
363  *
364  * @param index The index of a selected item.
365  */
366  virtual void do_deselect_item(const unsigned index) = 0;
367 
368  /** Gets the grid of an item. */
369  virtual grid& item_ordered(const unsigned index) = 0;
370 
371  /** Gets the grid of an item. */
372  virtual const grid& item_ordered(const unsigned index) const = 0;
373 
374 public:
375  /**
376  * If a sort-order is being applied, maps from unsorted to sorted indicies.
377  * This does not take account of whether each object is shown or not.
378  */
379  virtual unsigned get_ordered_index(unsigned index) const = 0;
380 
381  /**
382  * If a sort-order is being applied, maps from sorted to unsorted indicies.
383  * This does not take account of whether each object is shown or not.
384  */
385  virtual unsigned get_item_at_ordered(unsigned index_ordered) const = 0;
386 
387 };
388 
389 using generator_sort_array = std::array<generator_base::order_func, 2>;
390 
391 } // namespace gui2
virtual void handle_key_left_arrow(SDL_Keymod modifier, bool &handled)=0
Left arrow key pressed.
friend class debug_layout_graph
Definition: generator.hpp:41
virtual grid & item_ordered(const unsigned index)=0
Gets the grid of an item.
virtual void handle_key_up_arrow(SDL_Keymod modifier, bool &handled)=0
Up arrow key pressed.
virtual unsigned get_item_at_ordered(unsigned index_ordered) const =0
If a sort-order is being applied, maps from sorted to unsorted indicies.
virtual void request_reduce_width(const unsigned maximum_width) override=0
See widget::request_reduce_width.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override=0
See widget::find_at.
virtual unsigned get_item_count() const =0
Returns the number of items.
virtual void handle_key_right_arrow(SDL_Keymod modifier, bool &handled)=0
Right arrow key pressed.
virtual void set_item_shown(const unsigned index, const bool show)=0
Shows or hides an item.
virtual ~generator_base()
Definition: generator.hpp:44
virtual void place(const point &origin, const point &size) override=0
See widget::place.
virtual void set_order(const order_func &order)=0
virtual bool is_selected(const unsigned index) const =0
Returns whether the item is selected.
virtual void do_select_item(const unsigned index)=0
Selects a not selected item.
Base class for all widgets.
Definition: widget.hpp:49
std::function< bool(unsigned, unsigned)> order_func
Definition: generator.hpp:250
virtual grid & item(const unsigned index)=0
Gets the grid of an item.
virtual void child_populate_dirty_list(window &caller, const std::vector< widget *> &call_stack) override=0
See widget::child_populate_dirty_list.
virtual unsigned get_selected_item_count() const =0
Returns the number of selected items.
Generic file dialog.
Definition: field-fwd.hpp:23
virtual point calculate_best_size() const override=0
See widget::calculate_best_size.
Base container class.
Definition: grid.hpp:31
virtual void request_reduce_height(const unsigned maximum_height) override=0
See widget::request_reduce_height.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
Abstract base class for the generator.
Definition: generator.hpp:39
void toggle_item(const unsigned index)
Toggles the selection state of an item.
Definition: generator.hpp:97
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:47
placement
Determines how the items are placed.
Definition: generator.hpp:49
virtual void create_items(const int index, const builder_grid &list_builder, const std::vector< string_map > &data, const std::function< void(widget &)> &callback)=0
Creates one or more new item(s).
virtual void layout_initialize(const bool full_initialization) override=0
See widget::layout_initialize.
virtual bool get_item_shown(const unsigned index) const =0
Returns whether the item is shown.
virtual int get_selected_item() const =0
Returns the selected item.
std::size_t i
Definition: function.cpp:967
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override=0
See widget::set_visible_rectangle.
virtual void clear()=0
Deletes all items.
virtual grid & create_item(const int index, const builder_grid &list_builder, const string_map &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
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:24
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:72
static std::unique_ptr< generator_base > build(const bool has_minimum, const bool has_maximum, const placement placement, const bool select)
Create a new generator.
Definition: generator.cpp:1166
bool grid()
Definition: general.cpp:562
virtual void delete_item(const unsigned index)=0
Deletes an item.
virtual void handle_key_down_arrow(SDL_Keymod modifier, bool &handled)=0
Down arrow key pressed.
virtual void select_item(const unsigned index, const bool select)=0
(De)selects an item.
virtual unsigned get_ordered_index(unsigned index) const =0
If a sort-order is being applied, maps from unsorted to sorted indicies.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
virtual void set_origin(const point &origin) override=0
See widget::set_origin.
virtual void do_deselect_item(const unsigned index)=0
Deselects a selected item.
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
virtual void impl_draw_children(int x_offset, int y_offset) override=0
See widget::impl_draw_children.
boost::dynamic_bitset get_items_shown() const
Returns the visibility of all the items as a bit set.
Definition: generator.hpp:121
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
Definition: tooltip.cpp:140