GUI2/Spacer: delegate size caluclations to the widget instead of the builder

This allows size formulae that rely on screen size variables, which can change, to correctly
update the size of the widget.
This commit is contained in:
Charles Dang 2017-04-12 15:48:42 +11:00
parent e3b5213f21
commit da5f00c2b6
2 changed files with 38 additions and 28 deletions

View file

@ -28,28 +28,45 @@ namespace gui2
REGISTER_WIDGET(spacer)
bool spacer::fills_available_space()
{
return (!width_.has_formula() && width_() == 0) && (!height_.has_formula() && height_() == 0);
}
void spacer::request_reduce_width(const unsigned maximum_width)
{
if(best_size_ != point()) {
// This spacer is of fixed size, do nothing.
} else {
// Do nothing unless this widget fills all available space (has non-size size).
if(fills_available_space()) {
styled_widget::request_reduce_width(maximum_width);
}
}
void spacer::request_reduce_height(const unsigned maximum_height)
{
if(best_size_ != point()) {
// This spacer is of fixed size, do nothing.
} else {
// Do nothing unless this widget fills all available space (has non-size size).
if(fills_available_space()) {
styled_widget::request_reduce_height(maximum_height);
}
}
point spacer::calculate_best_size() const
{
return best_size_ != point() ? best_size_
: styled_widget::calculate_best_size();
const wfl::map_formula_callable& size = get_screen_size_variables();
unsigned width = width_(size);
unsigned height = height_(size);
point best_size;
if(width || height) {
best_size = point(width, height);
}
if(best_size != point()) {
return best_size;
}
return styled_widget::calculate_best_size();
}
void spacer::set_active(const bool /*active*/)
@ -161,19 +178,10 @@ builder_spacer::builder_spacer(const config& cfg)
widget* builder_spacer::build() const
{
spacer* widget = new spacer();
spacer* widget = new spacer(width_, height_);
init_control(widget);
const wfl::map_formula_callable& size = get_screen_size_variables();
const unsigned width = width_(size);
const unsigned height = height_(size);
if(width || height) {
widget->set_best_size(point(width, height));
}
DBG_GUI_G << "Window builder: placed spacer '" << id
<< "' with definition '" << definition << "'.\n";

View file

@ -38,7 +38,10 @@ namespace gui2
class spacer : public styled_widget
{
public:
spacer() : styled_widget(0), best_size_(0, 0)
spacer(const std::string& w = "0", const std::string& h = "0")
: styled_widget(0)
, width_(w)
, height_(h)
{
}
@ -71,14 +74,11 @@ public:
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_best_size(const point& best_size)
{
best_size_ = best_size;
}
private:
/** When we're used as a fixed size item, this holds the best size. */
point best_size_;
typed_formula<unsigned> width_;
typed_formula<unsigned> height_;
bool fills_available_space();
/** See @ref widget::impl_draw_background. */
virtual void impl_draw_background(surface& frame_buffer,
@ -115,8 +115,10 @@ struct builder_spacer : public builder_styled_widget
widget* build() const;
private:
typed_formula<unsigned> width_;
typed_formula<unsigned> height_;
// We store these as strings since they could contain formulas.
// The widget handles the parsing.
const std::string width_;
const std::string height_;
};
} // namespace implementation