The Battle for Wesnoth  1.19.0-dev
stacked_widget.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 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 
19 
22 
23 #include <boost/dynamic_bitset.hpp>
24 
25 namespace gui2
26 {
27 
28 // ------------ WIDGET -----------{
29 
30 namespace implementation
31 {
32 struct builder_stacked_widget;
33 }
34 
35 class generator_base;
36 
37 /**
38  * @ingroup GUIWidgetWML
39  *
40  * A stacked widget holds several widgets on top of each other.
41  * This can be used for various effects; add an optional overlay to an image, stack it with a spacer to force a minimum size of a widget.
42  * The latter is handy to avoid making a separate definition for a single instance with a fixed size.
43  *
44  * A stacked widget has no states.
45  */
47 {
50  friend class debug_layout_graph;
51 
52 public:
54 
55  /***** ***** ***** inherited ***** ****** *****/
56 
57  /** See @ref styled_widget::get_active. */
58  virtual bool get_active() const override;
59 
60  /** See @ref styled_widget::get_state. */
61  virtual unsigned get_state() const override;
62 
63  /** See @ref widget::layout_children. */
64  virtual void layout_children() override;
65 
66  /**
67  * Gets the current visible layer number.
68  *
69  * The current layer number will be -1 if all layers are currently visible.
70  * In this case, only the topmost (highest-numbered) layer will receive
71  * events.
72  *
73  * If more than one but not all layers are visible, this will be the number of
74  * the last one made visible.
75  *
76  * @returns The most recently shown layer
77  */
78  int current_layer() const { return selected_layer_; }
79 
80  /**
81  * Tests if the specified layer is selected (ie, visible).
82  *
83  * @param layer The layer to test
84  * @returns True if the specified layer is selected
85  */
86  bool layer_selected(const unsigned layer);
87 
88  /**
89  * Selects and displays a particular layer.
90  *
91  * If layer -1 is selected, all layers will be displayed but only the
92  * topmost (highest-numbered) layer will receive events.
93  *
94  * @param layer The layer to select
95  */
96  void select_layer(const int layer);
97 
98  /**
99  * Selects and displays multiple layers based on the state of the provided dynamic_bitset.
100  *
101  * @param mask A mask specifying which layers to select and deselect
102  */
103  void select_layers(const boost::dynamic_bitset<>& mask);
104 
105  /**
106  * Gets the total number of layers.
107  *
108  * @returns The total number of layers
109  */
110  unsigned int get_layer_count() const;
111 
112  /**
113  * Gets the grid for a specified layer.
114  * This can be used to search for widgets in a hidden layer.
115  *
116  * @param i The layer to retrieve
117  * @returns The grid for the specified layer.
118  */
119  grid* get_layer_grid(unsigned int i);
120 
121  /** Const overload for @ref get_layer_grid. */
122  const grid* get_layer_grid(unsigned int i) const;
123 
124  void set_find_in_all_layers(const bool do_find)
125  {
126  find_in_all_layers_ = do_find;
127  }
128 
129 private:
130  /**
131  * Finishes the building initialization of the widget.
132  *
133  * @param generator Generator for the list
134  * @param widget_builders The builder to build the contents of the widget.
135  */
136  void finalize(std::unique_ptr<generator_base> generator, const std::vector<builder_grid>& widget_builders);
137 
138  /**
139  * Contains a pointer to the generator.
140  *
141  * The pointer is not owned by this class, it's stored in the content_grid_
142  * of the scrollbar_container super class and freed when its grid is freed.
143  *
144  * NOTE: the generator is initialized with has_minimum (first arg) as false,
145  * which seems a little counter-intuitive at first. After all, shouldn't the
146  * stack always have at least one layer visible? However, this allows select_layer
147  * to function correctly.
148  *
149  * If has_minimum is true, the generator policy selected (one_item) can leave
150  * multiple layers selected when selecting a new one. This is most likely due to
151  * cases where the new chosen layer comes *after* the currently selected one.
152  * In that case, the generator would not allow the interim state where no layer
153  * before the new chosen layer is reached in the loop.
154  */
156 
157  /**
158  * The number of the current selected layer.
159  */
161 
162  /**
163  * If true, @ref find will search all layers for widgets regardless of which
164  * one is visible.
165  */
167 
168  void update_selected_layer_index(const int i);
169 
170  /** Internal implementation detail for selecting layers. */
171  void select_layer_impl(std::function<bool(unsigned int i)> display_condition);
172 
173 public:
174  /** Static type getter that does not rely on the widget being constructed. */
175  static const std::string& type();
176 
177 private:
178  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
179  virtual const std::string& get_control_type() const override;
180 
181  /** See @ref container_base::set_self_active. */
182  virtual void set_self_active(const bool active) override;
183 
184 public:
185  /** See @ref widget::find. */
186  virtual widget* find(const std::string& id, const bool must_be_active) override;
187 
188  /** See @ref widget::find. */
189  virtual const widget* find(const std::string& id, const bool must_be_active) const override;
190 };
191 
192 // }---------- DEFINITION ---------{
193 
195 {
196  explicit stacked_widget_definition(const config& cfg);
197 
199  {
200  explicit resolution(const config& cfg);
201 
203  };
204 };
205 
206 // }---------- BUILDER -----------{
207 
208 namespace implementation
209 {
210 
212 {
213  explicit builder_stacked_widget(const config& cfg);
214 
216 
217  virtual std::unique_ptr<widget> build() const override;
218 
219  /** The builders for all layers of the stack .*/
220  std::vector<builder_grid> stack;
221 };
222 
223 } // namespace implementation
224 
225 // }------------ END --------------
226 
227 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
A generic container base class.
Abstract base class for the generator.
Definition: generator.hpp:39
Basic template class to generate new items.
Base container class.
Definition: grid.hpp:32
A stacked widget holds several widgets on top of each other.
virtual widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
generator_base * generator_
Contains a pointer to the generator.
int current_layer() const
Gets the current visible layer number.
virtual bool get_active() const override
See styled_widget::get_active.
void select_layer_impl(std::function< bool(unsigned int i)> display_condition)
Internal implementation detail for selecting layers.
void update_selected_layer_index(const int i)
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
grid * get_layer_grid(unsigned int i)
Gets the grid for a specified layer.
friend class debug_layout_graph
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
bool layer_selected(const unsigned layer)
Tests if the specified layer is selected (ie, visible).
bool find_in_all_layers_
If true, find will search all layers for widgets regardless of which one is visible.
int selected_layer_
The number of the current selected layer.
stacked_widget(const implementation::builder_stacked_widget &builder)
unsigned int get_layer_count() const
Gets the total number of layers.
void set_find_in_all_layers(const bool do_find)
virtual unsigned get_state() const override
See styled_widget::get_state.
void finalize(std::unique_ptr< generator_base > generator, const std::vector< builder_grid > &widget_builders)
Finishes the building initialization of the widget.
void select_layers(const boost::dynamic_bitset<> &mask)
Selects and displays multiple layers based on the state of the provided dynamic_bitset.
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
virtual void layout_children() override
See widget::layout_children.
void select_layer(const int layer)
Selects and displays a particular layer.
Base class for all widgets.
Definition: widget.hpp:53
std::size_t i
Definition: function.cpp:968
Generic file dialog.
std::shared_ptr< builder_grid > builder_grid_ptr
Contains the implementation details for lexical_cast and shouldn't be used directly.
std::vector< builder_grid > stack
The builders for all layers of the stack .
virtual std::unique_ptr< widget > build() const override
virtual std::unique_ptr< widget > build() const=0
Base class of a resolution, contains the common keys for a resolution.
stacked_widget_definition(const config &cfg)