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