The Battle for Wesnoth  1.19.5+dev
generator.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
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 placement
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 std::unique_ptr<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  {
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 widget_item& 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 widget_data& 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<widget_item>& 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<widget_data>& data,
246  const std::function<void(widget&)>& callback) = 0;
247 
248  typedef std::function<bool (unsigned, unsigned)> order_func;
249  virtual void set_order(const order_func& order) = 0;
250 
251  /***** ***** ***** ***** Inherited ***** ***** ***** *****/
252 
253  /*
254  * These functions must be defined in our child classes so make sure they
255  * become pure virtuals.
256  */
257 
258  /** See @ref widget::layout_initialize. */
259  virtual void layout_initialize(const bool full_initialization) override = 0;
260 
261  /** See @ref widget::request_reduce_width. */
262  virtual void request_reduce_width(const unsigned maximum_width) override
263  = 0;
264 
265  /** See @ref widget::request_reduce_height. */
266  virtual void request_reduce_height(const unsigned maximum_height) override
267  = 0;
268 
269  /** See @ref widget::calculate_best_size. */
270  virtual point calculate_best_size() const override = 0;
271 
272  /** See @ref widget::place. */
273  virtual void place(const point& origin, const point& size) override = 0;
274 
275  /** See @ref widget::set_origin. */
276  virtual void set_origin(const point& origin) override = 0;
277 
278  /** See @ref widget::set_visible_rectangle. */
279  virtual void set_visible_rectangle(const SDL_Rect& rectangle) override = 0;
280 
281  /** See @ref widget::impl_draw_children. */
282  virtual void impl_draw_children() override = 0;
283 
284 public:
285  /** See @ref widget::find_at. */
286  virtual widget* find_at(const point& coordinate,
287  const bool must_be_active) override = 0;
288 
289  /** See @ref widget::find_at. */
290  virtual const widget* find_at(const point& coordinate,
291  const bool must_be_active) const override
292  = 0;
293 
294  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
295 
296  /**
297  * Up arrow key pressed.
298  *
299  * @param modifier The SDL keyboard modifier when the key was
300  * pressed.
301  * @param handled If the function handles the key it should
302  * set handled to true else do not modify it.
303  * This is used in the keyboard event
304  * changing.
305  */
306  virtual void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) = 0;
307 
308  /**
309  * Down arrow key pressed.
310  *
311  * @param modifier The SDL keyboard modifier when the key was
312  * pressed.
313  * @param handled If the function handles the key it should
314  * set handled to true else do not modify it.
315  * This is used in the keyboard event
316  * changing.
317  */
318  virtual void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) = 0;
319 
320  /**
321  * Left arrow key pressed.
322  *
323  * @param modifier The SDL keyboard modifier when the key was
324  * pressed.
325  * @param handled If the function handles the key it should
326  * set handled to true else do not modify it.
327  * This is used in the keyboard event
328  * changing.
329  */
330  virtual void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) = 0;
331 
332  /**
333  * Right arrow key pressed.
334  *
335  * @param modifier The SDL keyboard modifier when the key was
336  * pressed.
337  * @param handled If the function handles the key it should
338  * set handled to true else do not modify it.
339  * This is used in the keyboard event
340  * changing.
341  */
342  virtual void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) = 0;
343 
344 protected:
345  /**
346  * Selects a not selected item.
347  *
348  * @param index The index of a not selected item.
349  */
350  virtual void do_select_item(const unsigned index) = 0;
351 
352  /**
353  * Deselects a selected item.
354  *
355  * @param index The index of a selected item.
356  */
357  virtual void do_deselect_item(const unsigned index) = 0;
358 
359  /** Gets the grid of an item. */
360  virtual grid& item_ordered(const unsigned index) = 0;
361 
362  /** Gets the grid of an item. */
363  virtual const grid& item_ordered(const unsigned index) const = 0;
364 
365 public:
366  /**
367  * If a sort-order is being applied, maps from unsorted to sorted indicies.
368  * This does not take account of whether each object is shown or not.
369  */
370  virtual unsigned get_ordered_index(unsigned index) const = 0;
371 
372  /**
373  * If a sort-order is being applied, maps from sorted to unsorted indicies.
374  * This does not take account of whether each object is shown or not.
375  */
376  virtual unsigned get_item_at_ordered(unsigned index_ordered) const = 0;
377 
378 };
379 
380 using generator_sort_array = std::array<generator_base::order_func, 2>;
381 
382 } // namespace gui2
Abstract base class for the generator.
Definition: generator.hpp:39
std::function< bool(unsigned, unsigned)> order_func
Definition: generator.hpp:248
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:120
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:40
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:43
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:1160
void toggle_item(const unsigned index)
Toggles the selection state of an item.
Definition: generator.hpp:96
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:48
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:55
std::size_t i
Definition: function.cpp:1028
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:64
Generic file dialog.
std::array< generator_base::order_func, 2 > generator_sort_array
Definition: generator.hpp:380
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:36
std::map< std::string, t_string > widget_item
Definition: widget.hpp:33
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:70
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
std::string_view data
Definition: picture.cpp:178
Holds a 2D point.
Definition: point.hpp:25