The Battle for Wesnoth  1.15.12+dev
stacked_widget.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
18 
21 
22 #include <boost/dynamic_bitset.hpp>
23 
24 namespace gui2
25 {
26 
27 // ------------ WIDGET -----------{
28 
29 namespace implementation
30 {
31 struct builder_stacked_widget;
32 }
33 
34 class generator_base;
35 
36 /**
37  * @ingroup GUIWidgetWML
38  *
39  * A stacked widget holds several widgets on top of each other.
40  * 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.
41  * The latter is handy to avoid making a separate definition for a single instance with a fixed size.
42  *
43  * A stacked widget has no states.
44  */
46 {
49  friend class debug_layout_graph;
50 
51 public:
53 
54  /***** ***** ***** inherited ***** ****** *****/
55 
56  /** See @ref styled_widget::get_active. */
57  virtual bool get_active() const override;
58 
59  /** See @ref styled_widget::get_state. */
60  virtual unsigned get_state() const override;
61 
62  /** See @ref widget::layout_children. */
63  virtual void layout_children() override;
64 
65  /**
66  * Gets the current visible layer number.
67  *
68  * The current layer number will be -1 if all layers are currently visible.
69  * In this case, only the topmost (highest-numbered) layer will receive
70  * events.
71  *
72  * If more than one but not all layers are visible, this will be the number of
73  * the last one made visible.
74  *
75  * @returns The most recently shown layer
76  */
77  int current_layer() const { return selected_layer_; }
78 
79  /**
80  * Tests if the specified layer is selected (ie, visible).
81  *
82  * @param layer The layer to test
83  * @returns True if the specified layer is selected
84  */
85  bool layer_selected(const unsigned layer);
86 
87  /**
88  * Selects and displays a particular layer.
89  *
90  * If layer -1 is selected, all layers will be displayed but only the
91  * topmost (highest-numbered) layer will receive events.
92  *
93  * @param layer The layer to select
94  */
95  void select_layer(const int layer);
96 
97  /**
98  * Selects and displays multiple layers based on the state of the provided dynamic_bitset.
99  *
100  * @param mask A mask specifying which layers to select and deselect
101  */
102  void select_layers(const boost::dynamic_bitset<>& mask);
103 
104  /**
105  * Gets the total number of layers.
106  *
107  * @returns The total number of layers
108  */
109  unsigned int get_layer_count() const;
110 
111  /**
112  * Gets the grid for a specified layer.
113  * This can be used to search for widgets in a hidden layer.
114  *
115  * @param i The layer to retrieve
116  * @returns The grid for the specified layer.
117  */
118  grid* get_layer_grid(unsigned int i);
119 
120  /** Const overload for @ref get_layer_grid. */
121  const grid* get_layer_grid(unsigned int i) const;
122 
123  void set_find_in_all_layers(const bool do_find)
124  {
125  find_in_all_layers_ = do_find;
126  }
127 
128 private:
129  /**
130  * Finishes the building initialization of the widget.
131  *
132  * @param widget_builders The builder to build the contents of the
133  * widget.
134  */
135  void finalize(const std::vector<builder_grid>& widget_builders);
136 
137  /**
138  * Contains a pointer to the generator.
139  *
140  * The pointer is not owned by this class, it's stored in the content_grid_
141  * of the scrollbar_container super class and freed when its grid is
142  * 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 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
Base class of a resolution, contains the common keys for a resolution.
virtual widget * build() const =0
bool find_in_all_layers_
If true, find will search all layers for widgets regardless of which one is visible.
Base class for all widgets.
Definition: widget.hpp:49
int current_layer() const
Gets the current visible layer number.
Generic file dialog.
Definition: field-fwd.hpp:22
Base container class.
Definition: grid.hpp:30
Abstract base class for the generator.
Definition: generator.hpp:37
generator_base * generator_
Contains a pointer to the generator.
std::vector< builder_grid > stack
The builders for all layers of the stack .
std::size_t i
Definition: function.cpp:940
A generic container base class.
int selected_layer_
The number of the current selected layer.
point resolution()
Definition: general.cpp:387
std::unique_ptr< window > build(const builder_window::window_resolution &definition)
Builds a window.
A stacked widget holds several widgets on top of each other.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
std::shared_ptr< builder_grid > builder_grid_ptr
void set_find_in_all_layers(const bool do_find)
Contains the implementation details for lexical_cast and shouldn&#39;t be used directly.