The Battle for Wesnoth  1.17.0-dev
container_base.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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 
20 #include "gui/core/log.hpp"
21 #include "gui/widgets/window.hpp"
22 
23 #include <algorithm>
24 
25 #define LOG_SCOPE_HEADER \
26  "tcontainer(" + get_control_type() + ") [" + id() + "] " + __func__
27 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
28 
29 namespace gui2
30 {
31 
32 container_base::container_base(const implementation::builder_styled_widget& builder, const std::string& control_type)
33  : styled_widget(builder, control_type)
34  , grid_()
35 {
36  grid_.set_parent(this);
37  connect_signal<event::REQUEST_PLACEMENT>(
38  std::bind(&container_base::clear_layout_size, this),
40 }
41 
43 {
44  return get_rectangle();
45 }
46 
47 void container_base::layout_initialize(const bool full_initialization)
48 {
49  // Inherited.
50  styled_widget::layout_initialize(full_initialization);
51 
53 
54  grid_.layout_initialize(full_initialization);
55 }
56 
57 void container_base::reduce_width(const unsigned maximum_width)
58 {
60  point grid_size = grid_.get_best_size();
61  if(static_cast<int>(maximum_width) - border_space().x < grid_size.x) {
62  grid_.reduce_width(maximum_width - border_space().x);
63  grid_size = grid_.get_best_size();
64  size.x = grid_size.x + border_space().x;
65  size.y = std::max(size.y, grid_size.y + border_space().y);
66  } else {
67  size.x = maximum_width;
68  }
69 
70  set_layout_size(size);
71 }
72 
73 void container_base::request_reduce_width(const unsigned maximum_width)
74 {
76  point grid_size = grid_.get_best_size();
77  if(static_cast<int>(maximum_width) - border_space().x < grid_size.x) {
78  grid_.request_reduce_width(maximum_width - border_space().x);
79  grid_size = grid_.get_best_size();
80  size.x = grid_size.x + border_space().x;
81  size.y = std::max(size.y, grid_size.y + border_space().y);
82  } else {
83  size.x = maximum_width;
84  }
85 
86  set_layout_size(size);
87 }
88 
89 void container_base::demand_reduce_width(const unsigned maximum_width)
90 {
91  grid_.demand_reduce_width(maximum_width - border_space().x);
92 }
93 
94 void container_base::reduce_height(const unsigned maximum_height)
95 {
97  point grid_size = grid_.get_best_size();
98  if(static_cast<int>(maximum_height) - border_space().y < grid_size.y) {
99  grid_.reduce_height(maximum_height - border_space().y);
100  grid_size = grid_.get_best_size();
101  size.y = grid_size.y + border_space().y;
102  } else {
103  size.y = maximum_height;
104  }
105 
106  set_layout_size(size);
107 }
108 
109 void container_base::request_reduce_height(const unsigned maximum_height)
110 {
112  point grid_size = grid_.get_best_size();
113  if(static_cast<int>(maximum_height) - border_space().y < grid_size.y) {
114  grid_.request_reduce_height(maximum_height - border_space().y);
115  grid_size = grid_.get_best_size();
116  size.y = grid_size.y + border_space().y;
117  } else {
118  size.y = maximum_height;
119  }
120 
121  set_layout_size(size);
122 }
123 
124 void container_base::demand_reduce_height(const unsigned maximum_height)
125 {
126  grid_.demand_reduce_height(maximum_height - border_space().y);
127 }
128 
130 {
131  return grid_.can_wrap() || widget::can_wrap();
132 }
133 
134 void container_base::place(const point& origin, const point& size)
135 {
136  styled_widget::place(origin, size);
137 
138  const SDL_Rect rect = get_client_rect();
139  const point client_size(rect.w, rect.h);
140  const point client_position(rect.x, rect.y);
141  grid_.place(client_position, client_size);
142 }
143 
145 {
146  return widget::has_widget(widget) || grid_.has_widget(widget);
147 }
148 
150 {
152 
153  point result(grid_.get_best_size());
154  const point border_size = border_space();
155  const point default_size = get_config_default_size();
156 
157  // If the best size has a value of 0 it's means no limit so don't
158  // add the border_size might set a very small best size.
159  if(result.x) {
160  result.x += border_size.x;
161  }
162  if(default_size.x != 0 && result.x < default_size.x) {
163  result.x = default_size.x;
164  }
165 
166  if(result.y) {
167  result.y += border_size.y;
168  }
169  if(default_size.y != 0 && result.y < default_size.y) {
170  result.y = default_size.y;
171  }
172 
173 
174  DBG_GUI_L << LOG_HEADER << " border size " << border_size << " returning "
175  << result << ".\n";
176 
177  return result;
178 }
179 
181 {
182  // Inherited.
183  widget::set_origin(origin);
184 
185  const SDL_Rect rect = get_client_rect();
186  const point client_position(rect.x, rect.y);
187  grid_.set_origin(client_position);
188 }
189 
190 void container_base::set_visible_rectangle(const SDL_Rect& rectangle)
191 {
192  // Inherited.
194 
195  grid_.set_visible_rectangle(rectangle);
196 }
197 
199  int x_offset,
200  int y_offset)
201 {
204 
205  grid_.draw_children(frame_buffer, x_offset, y_offset);
206 }
207 
209 {
211 }
212 
213 void
215  const std::vector<widget*>& call_stack)
216 {
217  std::vector<widget*> child_call_stack = call_stack;
218  grid_.populate_dirty_list(caller, child_call_stack);
219 }
220 
222  const bool must_be_active)
223 {
224  return grid_.find_at(coordinate, must_be_active);
225 }
226 
228  const bool must_be_active) const
229 {
230  return grid_.find_at(coordinate, must_be_active);
231 }
232 
233 widget* container_base::find(const std::string& id, const bool must_be_active)
234 {
235  widget* result = styled_widget::find(id, must_be_active);
236  return result ? result : grid_.find(id, must_be_active);
237 }
238 
239 const widget* container_base::find(const std::string& id,
240  const bool must_be_active) const
241 {
242  const widget* result = styled_widget::find(id, must_be_active);
243  return result ? result : grid_.find(id, must_be_active);
244 }
245 
246 void container_base::set_active(const bool active)
247 {
248  // Not all our children might have the proper state so let them run
249  // unconditionally.
250  grid_.set_active(active);
251 
252  if(active == get_active()) {
253  return;
254  }
255 
256  set_is_dirty(true);
257 
258  set_self_active(active);
259 }
260 
262 {
264 }
265 
266 void container_base::init_grid(const builder_grid& grid_builder)
267 {
269 
270  assert(grid_.get_rows() == 0 && grid_.get_cols() == 0);
271 
272  grid_builder.build(&grid_);
273 }
274 
276 {
277  return point();
278 }
279 
281 {
282  for(const auto& lg : config()->linked_groups) {
283  if(!get_window()->has_linked_size_group(lg.id)) {
284  get_window()->init_linked_size_group(lg.id, lg.fixed_width, lg.fixed_height);
285  }
286  }
287 }
288 
289 } // namespace gui2
Define the common log macros for the gui toolkit.
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See widget::set_visible_rectangle.
Definition: grid.cpp:604
virtual grid * build() const override
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
virtual void child_populate_dirty_list(window &caller, const std::vector< widget *> &call_stack) override
See widget::child_populate_dirty_list.
void set_parent(widget *parent)
Definition: widget.cpp:155
#define DBG_GUI_L
Definition: log.hpp:55
void set_layout_size(const point &size)
Definition: widget.cpp:335
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
virtual void demand_reduce_width(const unsigned maximum_width) override
See widget::demand_reduce_width.
Definition: grid.cpp:272
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual void place(const point &origin, const point &size) override
See widget::place.
virtual bool can_wrap() const override
See widget::can_wrap.
Definition: grid.cpp:467
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
Definition: grid.cpp:682
visibility get_visible() const
Definition: widget.cpp:503
virtual bool get_active() const =0
Gets the active state of the styled_widget.
#define LOG_SCOPE_HEADER
unsigned int get_rows() const
Definition: grid.hpp:308
virtual bool has_widget(const widget &widget) const override
See widget::has_widget.
Definition: grid.cpp:667
This file contains the window object, this object is a top level container which has the event manage...
SDL_Rect get_rectangle() const
Gets the bounding rectangle of the widget on the screen.
Definition: widget.cpp:310
Base class for all widgets.
Definition: widget.hpp:49
virtual void set_visible_rectangle(const SDL_Rect &rectangle)
Sets the visible rectangle for a widget.
Definition: widget.cpp:453
lg::log_domain log_gui_layout("gui/layout")
Definition: log.hpp:54
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
virtual void impl_draw_children(surface &frame_buffer, int x_offset, int y_offset) override
See widget::impl_draw_children.
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
Definition: grid.cpp:232
virtual point calculate_best_size() const override
See widget::calculate_best_size.
#define LOG_HEADER
int x
x coordinate.
Definition: point.hpp:45
Generic file dialog.
Definition: field-fwd.hpp:23
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
Definition: grid.cpp:186
void populate_dirty_list(window &caller, std::vector< widget *> &call_stack)
Adds a widget to the dirty list if it is dirty.
Definition: widget.cpp:417
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
point get_best_size() const
Gets the best size for the widget.
Definition: widget.cpp:193
grid grid_
The grid which holds the child objects.
virtual bool has_widget(const widget &widget) const override
See widget::has_widget.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:466
virtual void set_origin(const point &origin)
Sets the origin of the widget.
Definition: widget.cpp:221
virtual void set_self_active(const bool active)=0
Helper for set_active.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
void init_grid(const builder_grid &grid_builder)
Initializes and builds the grid.
static thread_local std::deque< std::string > call_stack
For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL ...
Definition: function.cpp:47
virtual bool has_widget(const widget &widget) const
Does the widget contain the widget.
Definition: widget.cpp:595
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See widget::set_visible_rectangle.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Definition: grid.cpp:656
unsigned int get_cols() const
Definition: grid.hpp:314
#define log_scope2(domain, description)
Definition: log.hpp:219
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:827
virtual bool can_wrap() const override
See widget::can_wrap.
container_base(const implementation::builder_styled_widget &builder, const std::string &control_type)
virtual void place(const point &origin, const point &size) override
See widget::place.
Definition: grid.cpp:480
Definition: pump.hpp:40
point get_config_default_size() const
Gets the default size as defined in the config.
resolution_definition_ptr config()
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
window * get_window()
Get the parent window.
Definition: widget.cpp:117
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
Definition: grid.cpp:199
virtual void demand_reduce_width(const unsigned maximum_width) override
See widget::demand_reduce_width.
Holds a 2D point.
Definition: point.hpp:24
void set_active(const bool active)
Activates all children.
Definition: grid.cpp:163
void clear_layout_size()
Throws away layout_size_.
Definition: widget.hpp:460
Base class for all visible items.
virtual void set_origin(const point &origin) override
See widget::set_origin.
Definition: grid.cpp:587
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
Definition: grid.cpp:310
virtual void set_active(const bool active) override
See styled_widget::set_active.
lg::log_domain log_gui_general("gui/general")
Definition: log.hpp:40
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
Definition: grid.cpp:643
The user sets the widget visible, that means:
virtual void set_origin(const point &origin) override
See widget::set_origin.
virtual void demand_reduce_height(const unsigned maximum_height) override
See widget::demand_reduce_height.
Definition: grid.cpp:370
virtual void layout_children() override
See widget::layout_children.
Definition: grid.cpp:619
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
virtual void request_reduce_height(const unsigned maximum_height) override
See widget::request_reduce_height.
virtual void layout_children() override
See widget::layout_children.
virtual void demand_reduce_height(const unsigned maximum_height) override
See widget::demand_reduce_height.
void draw_children(surface &frame_buffer, int x_offset, int y_offset)
Draws the children of a widget.
Definition: widget.cpp:387
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
virtual bool can_wrap() const
Can the widget wrap.
Definition: widget.cpp:216
virtual SDL_Rect get_client_rect() const
Returns the client rect.
virtual point border_space() const
Returns the space used by the border.
int y
y coordinate.
Definition: point.hpp:48
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
Definition: grid.cpp:277