GUI2/Size Lock: ensure formula sizes are recalculated as necessary.

This is similar to the change made for spacers in da5f00c2b6.
It also fixes an issue with the MP Lobby chat box (and other such widgets that use formulas
for their fixed dimensions) where it would stay too small after a window resize (the chat
box formulas in all three dialogs it appears in are a percentage of window height).
This commit is contained in:
Charles Dang 2018-05-05 06:58:19 +11:00
parent 6a310f0c79
commit 18afe08a7b
3 changed files with 38 additions and 48 deletions

View file

@ -66,6 +66,7 @@
* Highlight the titles of MP games with vacant slots. * Highlight the titles of MP games with vacant slots.
* Improved MP Lobby layout on low resolutions. * Improved MP Lobby layout on low resolutions.
* Improved reporting of network errors in the MP lobby (issue #3005). * Improved reporting of network errors in the MP lobby (issue #3005).
* Ensure the chat widget remains the correct size even after a window resize.
### WML engine ### WML engine
* Support formula= key in [variable] ConditionalWML * Support formula= key in [variable] ConditionalWML
* Support to_location in [move_unit], taking a location ID * Support to_location in [move_unit], taking a location ID

View file

@ -25,12 +25,13 @@
namespace gui2 namespace gui2
{ {
REGISTER_WIDGET(size_lock) REGISTER_WIDGET(size_lock)
size_lock::size_lock(const implementation::builder_size_lock& builder) size_lock::size_lock(const implementation::builder_size_lock& builder)
: container_base(builder, get_control_type()) : container_base(builder, get_control_type())
, widget_(nullptr) , widget_(nullptr)
, width_(builder.width_)
, height_(builder.height_)
{ {
} }
@ -38,27 +39,21 @@ void size_lock::place(const point& origin, const point& size)
{ {
point content_size = widget_->get_best_size(); point content_size = widget_->get_best_size();
if (content_size.x > size.x) if(content_size.x > size.x) {
{
reduce_width(size.x); reduce_width(size.x);
content_size = widget_->get_best_size(); content_size = widget_->get_best_size();
} }
if (content_size.y > size.y) if(content_size.y > size.y) {
{ try {
try
{
reduce_height(size.y); reduce_height(size.y);
} } catch(layout_exception_width_modified&) {
catch(layout_exception_width_modified&)
{
} }
content_size = widget_->get_best_size(); content_size = widget_->get_best_size();
} }
if (content_size.x > size.x) if(content_size.x > size.x) {
{
reduce_width(size.x); reduce_width(size.x);
content_size = widget_->get_best_size(); content_size = widget_->get_best_size();
} }
@ -78,13 +73,23 @@ void size_lock::finalize(builder_widget_const_ptr widget_builder)
set_rows_cols(1u, 1u); set_rows_cols(1u, 1u);
widget_ = widget_builder->build(); widget_ = widget_builder->build();
set_child(widget_, 0u, 0u, set_child(widget_, 0u, 0u, grid::VERTICAL_GROW_SEND_TO_CLIENT | grid::HORIZONTAL_GROW_SEND_TO_CLIENT, 0u);
grid::VERTICAL_GROW_SEND_TO_CLIENT | grid::HORIZONTAL_GROW_SEND_TO_CLIENT,
0u);
} }
size_lock_definition::size_lock_definition(const config& cfg) : point size_lock::calculate_best_size() const
styled_widget_definition(cfg) {
const wfl::map_formula_callable& size = get_screen_size_variables();
unsigned width = width_(size);
unsigned height = height_(size);
VALIDATE(width > 0 || height > 0, _("Invalid size."));
return point(width, height);
}
size_lock_definition::size_lock_definition(const config& cfg)
: styled_widget_definition(cfg)
{ {
DBG_GUI_P << "Parsing fixed size widget " << id << '\n'; DBG_GUI_P << "Parsing fixed size widget " << id << '\n';
@ -108,8 +113,9 @@ size_lock_definition::size_lock_definition(const config& cfg) :
* @end{tag}{name="size_lock_definition"} * @end{tag}{name="size_lock_definition"}
* @end{tag}{name="gui/"} * @end{tag}{name="gui/"}
*/ */
size_lock_definition::resolution::resolution(const config& cfg) : size_lock_definition::resolution::resolution(const config& cfg)
resolution_definition(cfg), grid(nullptr) : resolution_definition(cfg)
, grid(nullptr)
{ {
// Add a dummy state since every widget needs a state. // Add a dummy state since every widget needs a state.
static config dummy("draw"); static config dummy("draw");
@ -147,9 +153,11 @@ size_lock_definition::resolution::resolution(const config& cfg) :
namespace implementation namespace implementation
{ {
builder_size_lock::builder_size_lock(const config& cfg)
builder_size_lock::builder_size_lock(const config& cfg) : : builder_styled_widget(cfg)
builder_styled_widget(cfg), content_(nullptr), width_(cfg["width"]), height_(cfg["height"]) , content_(nullptr)
, width_(cfg["width"])
, height_(cfg["height"])
{ {
VALIDATE(cfg.has_child("widget"), _("No widget defined.")); VALIDATE(cfg.has_child("widget"), _("No widget defined."));
content_ = create_widget_builder(cfg.child("widget")); content_ = create_widget_builder(cfg.child("widget"));
@ -159,28 +167,15 @@ widget* builder_size_lock::build() const
{ {
size_lock* widget = new size_lock(*this); size_lock* widget = new size_lock(*this);
DBG_GUI_G << "Window builder: placed fixed size widget '" << id << DBG_GUI_G << "Window builder: placed fixed size widget '" << id << "' with definition '" << definition << "'.\n";
"' with definition '" << definition << "'.\n";
const auto conf = widget->cast_config_to<size_lock_definition>(); const auto conf = widget->cast_config_to<size_lock_definition>();
assert(conf != nullptr); assert(conf != nullptr);
widget->init_grid(conf->grid); widget->init_grid(conf->grid);
wfl::map_formula_callable size = get_screen_size_variables();
const unsigned width = width_(size);
const unsigned height = height_(size);
VALIDATE(width > 0 || height > 0, _("Invalid size."));
widget->set_target_size(point(width, height));
widget->finalize(content_); widget->finalize(content_);
return widget; return widget;
} }
} }
} }

View file

@ -56,19 +56,12 @@ public:
/** See @ref widget::layout_children. */ /** See @ref widget::layout_children. */
void layout_children() override; void layout_children() override;
void set_target_size(const point& size)
{
size_ = size;
}
protected: protected:
point calculate_best_size() const override point calculate_best_size() const override;
{
return size_;
}
private: private:
point size_; typed_formula<unsigned> width_;
typed_formula<unsigned> height_;
/** /**
* Points to the actual widget. * Points to the actual widget.
@ -118,10 +111,11 @@ struct builder_size_lock : public builder_styled_widget
widget* build() const; widget* build() const;
private:
builder_widget_const_ptr content_;
typed_formula<unsigned> width_; typed_formula<unsigned> width_;
typed_formula<unsigned> height_; typed_formula<unsigned> height_;
private:
builder_widget_const_ptr content_;
}; };
} }
} }