The Battle for Wesnoth  1.17.23+dev
generator.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2023
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  {
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 widget_item& 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 widget_data& 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<widget_item>& 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<widget_data>& 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() override = 0;
284 
285 public:
286  /** See @ref widget::find_at. */
287  virtual widget* find_at(const point& coordinate,
288  const bool must_be_active) override = 0;
289 
290  /** See @ref widget::find_at. */
291  virtual const widget* find_at(const point& coordinate,
292  const bool must_be_active) const override
293  = 0;
294 
295  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
296 
297  /**
298  * Up arrow key pressed.
299  *
300  * @param modifier The SDL keyboard modifier when the key was
301  * pressed.
302  * @param handled If the function handles the key it should
303  * set handled to true else do not modify it.
304  * This is used in the keyboard event
305  * changing.
306  */
307  virtual void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) = 0;
308 
309  /**
310  * Down arrow key pressed.
311  *
312  * @param modifier The SDL keyboard modifier when the key was
313  * pressed.
314  * @param handled If the function handles the key it should
315  * set handled to true else do not modify it.
316  * This is used in the keyboard event
317  * changing.
318  */
319  virtual void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) = 0;
320 
321  /**
322  * Left arrow key pressed.
323  *
324  * @param modifier The SDL keyboard modifier when the key was
325  * pressed.
326  * @param handled If the function handles the key it should
327  * set handled to true else do not modify it.
328  * This is used in the keyboard event
329  * changing.
330  */
331  virtual void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) = 0;
332 
333  /**
334  * Right arrow key pressed.
335  *
336  * @param modifier The SDL keyboard modifier when the key was
337  * pressed.
338  * @param handled If the function handles the key it should
339  * set handled to true else do not modify it.
340  * This is used in the keyboard event
341  * changing.
342  */
343  virtual void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) = 0;
344 
345 protected:
346  /**
347  * Selects a not selected item.
348  *
349  * @param index The index of a not selected item.
350  */
351  virtual void do_select_item(const unsigned index) = 0;
352 
353  /**
354  * Deselects a selected item.
355  *
356  * @param index The index of a selected item.
357  */
358  virtual void do_deselect_item(const unsigned index) = 0;
359 
360  /** Gets the grid of an item. */
361  virtual grid& item_ordered(const unsigned index) = 0;
362 
363  /** Gets the grid of an item. */
364  virtual const grid& item_ordered(const unsigned index) const = 0;
365 
366 public:
367  /**
368  * If a sort-order is being applied, maps from unsorted to sorted indicies.
369  * This does not take account of whether each object is shown or not.
370  */
371  virtual unsigned get_ordered_index(unsigned index) const = 0;
372 
373  /**
374  * If a sort-order is being applied, maps from sorted to unsorted indicies.
375  * This does not take account of whether each object is shown or not.
376  */
377  virtual unsigned get_item_at_ordered(unsigned index_ordered) const = 0;
378 
379 };
380 
381 using generator_sort_array = std::array<generator_base::order_func, 2>;
382 
383 } // namespace gui2
Abstract base class for the generator.
Definition: generator.hpp:40
std::function< bool(unsigned, unsigned)> order_func
Definition: generator.hpp:249
virtual void set_order(const order_func &order)=0
virtual void handle_key_left_arrow(SDL_Keymod modifier, bool &handled)=0
Left arrow key pressed.
virtual void set_origin(const point &origin) override=0
See widget::set_origin.
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override=0
See widget::set_visible_rectangle.
virtual void impl_draw_children() override=0
See widget::impl_draw_children.
virtual const grid & item_ordered(const unsigned index) const =0
Gets the grid of an item.
virtual unsigned get_ordered_index(unsigned index) const =0
If a sort-order is being applied, maps from unsorted to sorted indicies.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_data &data, const std::function< void(widget &)> &callback)=0
Creates a new item.
virtual void request_reduce_height(const unsigned maximum_height) override=0
See widget::request_reduce_height.
virtual unsigned get_selected_item_count() const =0
Returns the number of selected items.
virtual void create_items(const int index, const builder_grid &list_builder, const std::vector< widget_item > &data, const std::function< void(widget &)> &callback)=0
Creates one or more new item(s).
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 void delete_item(const unsigned index)=0
Deletes an item.
boost::dynamic_bitset get_items_shown() const
Returns the visibility of all the items as a bit set.
Definition: generator.hpp:121
virtual void request_reduce_width(const unsigned maximum_width) override=0
See widget::request_reduce_width.
virtual void handle_key_up_arrow(SDL_Keymod modifier, bool &handled)=0
Up arrow key pressed.
virtual void place(const point &origin, const point &size) override=0
See widget::place.
virtual grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback)=0
Creates a new item.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override=0
See widget::find_at.
virtual const grid & item(const unsigned index) const =0
Gets the grid of an item.
friend class debug_layout_graph
Definition: generator.hpp:41
virtual grid & item_ordered(const unsigned index)=0
Gets the grid of an item.
virtual const widget * find_at(const point &coordinate, const bool must_be_active) const override=0
See widget::find_at.
virtual point calculate_best_size() const override=0
See widget::calculate_best_size.
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 grid & item(const unsigned index)=0
Gets the grid of an item.
virtual unsigned get_item_count() const =0
Returns the number of items.
virtual ~generator_base()
Definition: generator.hpp:44
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:1163
void toggle_item(const unsigned index)
Toggles the selection state of an item.
Definition: generator.hpp:97
virtual bool is_selected(const unsigned index) const =0
Returns whether the item is selected.
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.
placement
Determines how the items are placed.
Definition: generator.hpp:49
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 create_items(const int index, const builder_grid &list_builder, const std::vector< widget_data > &data, const std::function< void(widget &)> &callback)=0
Creates one or more new item(s).
virtual void clear()=0
Deletes all items.
virtual void do_select_item(const unsigned index)=0
Selects a not selected item.
virtual void do_deselect_item(const unsigned index)=0
Deselects a selected item.
virtual int get_selected_item() const =0
Returns the selected item.
Base container class.
Definition: grid.hpp:32
Base class for all widgets.
Definition: widget.hpp:54
std::size_t i
Definition: function.cpp:968
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:81
Generic file dialog.
std::array< generator_base::order_func, 2 > generator_sort_array
Definition: generator.hpp:381
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
std::map< std::string, t_string > widget_item
Definition: widget.hpp:32
bool grid()
Definition: general.cpp:565
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
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
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
std::string_view data
Definition: picture.cpp:199
Holds a 2D point.
Definition: point.hpp:25