The Battle for Wesnoth  1.19.0-dev
container_base.cpp
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 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
21 #include "gui/core/log.hpp"
22 #include "gui/widgets/window.hpp"
23 
24 #include <algorithm>
25 
26 #define LOG_SCOPE_HEADER \
27  "tcontainer(" + get_control_type() + ") [" + id() + "] " + __func__
28 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
29 
30 namespace gui2
31 {
32 
33 container_base::container_base(const implementation::builder_styled_widget& builder, const std::string& control_type)
34  : styled_widget(builder, control_type)
35  , grid_()
36 {
37  grid_.set_parent(this);
38  connect_signal<event::REQUEST_PLACEMENT>(
39  std::bind(&container_base::clear_layout_size, this),
41 }
42 
44 {
45  return get_rectangle();
46 }
47 
48 void container_base::layout_initialize(const bool full_initialization)
49 {
50  // Inherited.
51  styled_widget::layout_initialize(full_initialization);
52 
54 
55  grid_.layout_initialize(full_initialization);
56 }
57 
58 void container_base::reduce_width(const unsigned maximum_width)
59 {
61  point grid_size = grid_.get_best_size();
62  if(static_cast<int>(maximum_width) - border_space().x < grid_size.x) {
63  grid_.reduce_width(maximum_width - border_space().x);
64  grid_size = grid_.get_best_size();
65  size.x = grid_size.x + border_space().x;
66  size.y = std::max(size.y, grid_size.y + border_space().y);
67  } else {
68  size.x = maximum_width;
69  }
70 
72 }
73 
74 void container_base::request_reduce_width(const unsigned maximum_width)
75 {
77  point grid_size = grid_.get_best_size();
78  if(static_cast<int>(maximum_width) - border_space().x < grid_size.x) {
79  grid_.request_reduce_width(maximum_width - border_space().x);
80  grid_size = grid_.get_best_size();
81  size.x = grid_size.x + border_space().x;
82  size.y = std::max(size.y, grid_size.y + border_space().y);
83  } else {
84  size.x = maximum_width;
85  }
86 
88 }
89 
90 void container_base::demand_reduce_width(const unsigned maximum_width)
91 {
92  grid_.demand_reduce_width(maximum_width - border_space().x);
93 }
94 
95 void container_base::reduce_height(const unsigned maximum_height)
96 {
98  point grid_size = grid_.get_best_size();
99  if(static_cast<int>(maximum_height) - border_space().y < grid_size.y) {
100  grid_.reduce_height(maximum_height - border_space().y);
101  grid_size = grid_.get_best_size();
102  size.y = grid_size.y + border_space().y;
103  } else {
104  size.y = maximum_height;
105  }
106 
108 }
109 
110 void container_base::request_reduce_height(const unsigned maximum_height)
111 {
113  point grid_size = grid_.get_best_size();
114  if(static_cast<int>(maximum_height) - border_space().y < grid_size.y) {
115  grid_.request_reduce_height(maximum_height - border_space().y);
116  grid_size = grid_.get_best_size();
117  size.y = grid_size.y + border_space().y;
118  } else {
119  size.y = maximum_height;
120  }
121 
123 }
124 
125 void container_base::demand_reduce_height(const unsigned maximum_height)
126 {
127  grid_.demand_reduce_height(maximum_height - border_space().y);
128 }
129 
131 {
132  return grid_.can_wrap() || widget::can_wrap();
133 }
134 
135 void container_base::place(const point& origin, const point& size)
136 {
137  styled_widget::place(origin, size);
138 
139  const SDL_Rect rect = get_client_rect();
140  const point client_size(rect.w, rect.h);
141  const point client_position(rect.x, rect.y);
142  grid_.place(client_position, client_size);
143 }
144 
146 {
148 }
149 
151 {
153 
154  point result(grid_.get_best_size());
155  const point border_size = border_space();
156  const point default_size = get_config_default_size();
157 
158  // If the best size has a value of 0 it's means no limit so don't
159  // add the border_size might set a very small best size.
160  if(result.x) {
161  result.x += border_size.x;
162  }
163  if(default_size.x != 0 && result.x < default_size.x) {
164  result.x = default_size.x;
165  }
166 
167  if(result.y) {
168  result.y += border_size.y;
169  }
170  if(default_size.y != 0 && result.y < default_size.y) {
171  result.y = default_size.y;
172  }
173 
174 
175  DBG_GUI_L << LOG_HEADER << " border size " << border_size << " returning "
176  << result << ".";
177 
178  return result;
179 }
180 
182 {
183  // Inherited.
184  widget::set_origin(origin);
185 
186  const SDL_Rect rect = get_client_rect();
187  const point client_position(rect.x, rect.y);
188  grid_.set_origin(client_position);
189 }
190 
191 void container_base::set_visible_rectangle(const SDL_Rect& rectangle)
192 {
193  // Inherited.
195 
196  grid_.set_visible_rectangle(rectangle);
197 }
198 
200 {
203 
205 }
206 
208 {
210 }
211 
213  const bool must_be_active)
214 {
215  return grid_.find_at(coordinate, must_be_active);
216 }
217 
219  const bool must_be_active) const
220 {
221  return grid_.find_at(coordinate, must_be_active);
222 }
223 
224 widget* container_base::find(const std::string& id, const bool must_be_active)
225 {
226  widget* result = styled_widget::find(id, must_be_active);
227  return result ? result : grid_.find(id, must_be_active);
228 }
229 
230 const widget* container_base::find(const std::string& id,
231  const bool must_be_active) const
232 {
233  const widget* result = styled_widget::find(id, must_be_active);
234  return result ? result : grid_.find(id, must_be_active);
235 }
236 
237 void container_base::set_active(const bool active)
238 {
239  // Not all our children might have the proper state so let them run
240  // unconditionally.
241  grid_.set_active(active);
242 
243  if(active == get_active()) {
244  return;
245  }
246 
247  queue_redraw();
248 
249  set_self_active(active);
250 }
251 
253 {
255 }
256 
258 {
259  return std::make_unique<gui2::iteration::container>(*this);
260 }
261 
262 void container_base::init_grid(const builder_grid& grid_builder)
263 {
265 
266  assert(grid_.get_rows() == 0 && grid_.get_cols() == 0);
267 
268  grid_builder.build(grid_);
269 }
270 
272 {
273  return point();
274 }
275 
277 {
278  for(const auto& lg : get_config()->linked_groups) {
279  if(!get_window()->has_linked_size_group(lg.id)) {
280  get_window()->init_linked_size_group(lg.id, lg.fixed_width, lg.fixed_height);
281  }
282  }
283 }
284 
285 } // namespace gui2
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
virtual iteration::walker_ptr create_walker() override
See widget::create_walker.
container_base(const implementation::builder_styled_widget &builder, const std::string &control_type)
virtual void set_self_active(const bool active)=0
Helper for set_active.
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
virtual void set_active(const bool active) override
See styled_widget::set_active.
virtual bool can_wrap() const override
See widget::can_wrap.
virtual SDL_Rect get_client_rect() const
Returns the client rect.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
virtual void demand_reduce_width(const unsigned maximum_width) override
See widget::demand_reduce_width.
virtual void layout_children() override
See widget::layout_children.
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
grid grid_
The grid which holds the child objects.
virtual void set_origin(const point &origin) override
See widget::set_origin.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See widget::set_visible_rectangle.
virtual void demand_reduce_height(const unsigned maximum_height) override
See widget::demand_reduce_height.
void init_grid(const builder_grid &grid_builder)
Initializes and builds the grid.
virtual bool has_widget(const widget &widget) const override
See widget::has_widget.
virtual void impl_draw_children() override
See widget::impl_draw_children.
virtual point border_space() const
Returns the space used by the border.
void set_active(const bool active)
Activates all children.
Definition: grid.cpp:167
virtual bool has_widget(const widget &widget) const override
See widget::has_widget.
Definition: grid.cpp:656
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
Definition: grid.cpp:671
virtual void place(const point &origin, const point &size) override
See widget::place.
Definition: grid.cpp:484
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
Definition: grid.cpp:281
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See widget::set_visible_rectangle.
Definition: grid.cpp:608
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
Definition: grid.cpp:203
unsigned int get_rows() const
Definition: grid.hpp:303
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
Definition: grid.cpp:632
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Definition: grid.cpp:645
unsigned int get_cols() const
Definition: grid.hpp:309
virtual void set_origin(const point &origin) override
See widget::set_origin.
Definition: grid.cpp:591
virtual void demand_reduce_height(const unsigned maximum_height) override
See widget::demand_reduce_height.
Definition: grid.cpp:374
virtual bool can_wrap() const override
See widget::can_wrap.
Definition: grid.cpp:471
virtual void layout_children() override
See widget::layout_children.
Definition: grid.cpp:623
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
Definition: grid.cpp:190
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
Definition: grid.cpp:236
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
Definition: grid.cpp:314
virtual void demand_reduce_width(const unsigned maximum_width) override
See widget::demand_reduce_width.
Definition: grid.cpp:276
Base class for all visible items.
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
point get_config_default_size() const
Gets the default size as defined in the config.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual bool get_active() const =0
Gets the active state of the styled_widget.
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
resolution_definition_ptr get_config()
Base class for all widgets.
Definition: widget.hpp:53
void set_layout_size(const point &size)
Definition: widget.cpp:337
point get_best_size() const
Gets the best size for the widget.
Definition: widget.cpp:193
void clear_layout_size()
Throws away layout_size_.
Definition: widget.hpp:456
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:455
visibility get_visible() const
Definition: widget.cpp:497
void set_parent(widget *parent)
Definition: widget.cpp:155
void draw_children()
Draws the children of a widget.
Definition: widget.cpp:394
virtual bool has_widget(const widget &widget) const
Does the widget contain the widget.
Definition: widget.cpp:566
virtual void set_origin(const point &origin)
Sets the origin of the widget.
Definition: widget.cpp:221
window * get_window()
Get the parent window.
Definition: widget.cpp:117
@ visible
The user sets the widget visible, that means:
rect get_rectangle() const
Gets the bounding rectangle of the widget on the screen.
Definition: widget.cpp:312
virtual bool can_wrap() const
Can the widget wrap.
Definition: widget.cpp:216
virtual void set_visible_rectangle(const SDL_Rect &rectangle)
Sets the visible rectangle for a widget.
Definition: widget.cpp:442
void init_linked_size_group(const std::string &id, const bool fixed_width, const bool fixed_height)
Initializes a linked size group.
Definition: window.cpp:795
#define LOG_HEADER
#define LOG_SCOPE_HEADER
Define the common log macros for the gui toolkit.
#define DBG_GUI_L
Definition: log.hpp:55
This file contains the window object, this object is a top level container which has the event manage...
#define log_scope2(domain, description)
Definition: log.hpp:275
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:202
std::unique_ptr< class walker_base > walker_ptr
Definition: widget.hpp:42
Generic file dialog.
lg::log_domain log_gui_general("gui/general")
Definition: log.hpp:40
lg::log_domain log_gui_layout("gui/layout")
Definition: log.hpp:54
Definition: pump.hpp:41
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
virtual std::unique_ptr< widget > build() const override
Inherited from builder_widget.
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47