Use REQUEST_PLACEMENT event to trigger partial relayout
It turned out that mordante had added that event for the same purpose, avoiding unnecessary full relayouts. Letting GUI2 event handling to route the event to the right widgets is better than doing it manually.
This commit is contained in:
parent
14239c6911
commit
d8c670654a
6 changed files with 42 additions and 47 deletions
|
@ -28,6 +28,15 @@
|
|||
namespace gui2
|
||||
{
|
||||
|
||||
container_base::container_base(const unsigned canvas_count)
|
||||
: styled_widget(canvas_count), grid_()
|
||||
{
|
||||
grid_.set_parent(this);
|
||||
connect_signal<event::REQUEST_PLACEMENT>(
|
||||
std::bind(&container_base::clear_layout_size, this),
|
||||
event::dispatcher::back_pre_child);
|
||||
}
|
||||
|
||||
SDL_Rect container_base::get_client_rect() const
|
||||
{
|
||||
return get_rectangle();
|
||||
|
|
|
@ -34,11 +34,7 @@ class container_base : public styled_widget
|
|||
friend class debug_layout_graph;
|
||||
|
||||
public:
|
||||
explicit container_base(const unsigned canvas_count)
|
||||
: styled_widget(canvas_count), grid_()
|
||||
{
|
||||
grid_.set_parent(this);
|
||||
}
|
||||
explicit container_base(const unsigned canvas_count);
|
||||
|
||||
/**
|
||||
* Returns the client rect.
|
||||
|
|
|
@ -44,6 +44,10 @@ grid::grid(const unsigned rows, const unsigned cols)
|
|||
, col_grow_factor_(cols)
|
||||
, children_(rows * cols)
|
||||
{
|
||||
connect_signal<event::REQUEST_PLACEMENT>(
|
||||
std::bind(&grid::request_placement, this,
|
||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
|
||||
event::dispatcher::back_pre_child);
|
||||
}
|
||||
|
||||
grid::~grid()
|
||||
|
@ -378,12 +382,13 @@ void grid::demand_reduce_height(const unsigned /*maximum_height*/)
|
|||
/** @todo Implement. */
|
||||
}
|
||||
|
||||
void grid::relayout()
|
||||
void grid::request_placement(dispatcher&, const event::ui_event, bool& handled, bool&)
|
||||
{
|
||||
point size = get_size();
|
||||
point best_size = calculate_best_size();
|
||||
if(size.x >= best_size.x && size.y >= best_size.y) {
|
||||
place(get_origin(), size);
|
||||
handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -398,6 +403,7 @@ void grid::relayout()
|
|||
if(size.x >= best_size.x && size.y >= best_size.y) {
|
||||
// Wrapping succeeded, we still fit vertically.
|
||||
place(get_origin(), size);
|
||||
handled = true;
|
||||
return;
|
||||
} else {
|
||||
// Wrapping failed, we no longer fit.
|
||||
|
@ -406,23 +412,10 @@ void grid::relayout()
|
|||
}
|
||||
}
|
||||
|
||||
// Not enough space, ask the parent grid for more.
|
||||
|
||||
// Throw away cached sizes of all parent widgets until the next grid.
|
||||
widget* parent_widget = parent();
|
||||
while(parent_widget != nullptr &&
|
||||
dynamic_cast<grid*>(parent_widget) == nullptr)
|
||||
{
|
||||
parent_widget->clear_layout_size();
|
||||
parent_widget = parent_widget->parent();
|
||||
}
|
||||
|
||||
grid* parent = get_parent_grid();
|
||||
if(parent != nullptr) {
|
||||
parent->relayout();
|
||||
} else {
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
/*
|
||||
Not enough space.
|
||||
Let the event flow higher up.
|
||||
This is a pre-event handler, so the event flows upwards. */
|
||||
}
|
||||
|
||||
point grid::recalculate_best_size()
|
||||
|
|
|
@ -220,13 +220,6 @@ public:
|
|||
/** See @ref widget::demand_reduce_height. */
|
||||
virtual void demand_reduce_height(const unsigned maximum_height) override;
|
||||
|
||||
/**
|
||||
* Attempts to lay out the grid without laying out the entire window.
|
||||
* If the grid needs to grow, asks the parent grid for more space, recursively.
|
||||
* If the grid is the top-level grid, falls back to laying out the whole window.
|
||||
*/
|
||||
void relayout();
|
||||
|
||||
/**
|
||||
* Recalculates the best size.
|
||||
*
|
||||
|
@ -241,6 +234,11 @@ private:
|
|||
/** See @ref widget::calculate_best_size. */
|
||||
virtual point calculate_best_size() const override;
|
||||
|
||||
/**
|
||||
* Attempts to lay out the grid without laying out the entire window.
|
||||
*/
|
||||
void request_placement(dispatcher& dispatcher, const event::ui_event event, bool& handled, bool& halt);
|
||||
|
||||
public:
|
||||
/** See @ref widget::can_wrap. */
|
||||
virtual bool can_wrap() const override;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "gui/widgets/scrollbar_container_private.hpp"
|
||||
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/core/event/message.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
#include "gui/core/layout_exception.hpp"
|
||||
#include "gui/widgets/clickable_item.hpp"
|
||||
|
@ -592,10 +593,9 @@ bool scrollbar_container::content_resize_request(const bool force_sizing)
|
|||
== widget::visibility::invisible)) {
|
||||
|
||||
DBG_GUI_L << LOG_HEADER
|
||||
<< " can't use horizontal scrollbar, ask grid.\n";
|
||||
grid* grid = get_parent_grid();
|
||||
assert(grid);
|
||||
grid->relayout();
|
||||
<< " can't use horizontal scrollbar, request placement.\n";
|
||||
event::message message;
|
||||
fire(event::REQUEST_PLACEMENT, *this, message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -608,10 +608,9 @@ bool scrollbar_container::content_resize_request(const bool force_sizing)
|
|||
== widget::visibility::invisible)) {
|
||||
|
||||
DBG_GUI_L << LOG_HEADER
|
||||
<< " can't use vertical scrollbar, ask grid.\n";
|
||||
grid* grid = get_parent_grid();
|
||||
assert(grid);
|
||||
grid->relayout();
|
||||
<< " can't use vertical scrollbar, request placement.\n";
|
||||
event::message message;
|
||||
fire(event::REQUEST_PLACEMENT, *this, message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,15 +259,6 @@ public:
|
|||
*/
|
||||
virtual void layout_initialise(const bool full_initialisation);
|
||||
|
||||
/**
|
||||
* Throws away @ref layout_size_.
|
||||
*
|
||||
* Use with care: this function does not recurse to child widgets.
|
||||
*
|
||||
* See @ref layout_algorithm for more information.
|
||||
*/
|
||||
void clear_layout_size() { set_layout_size(point()); }
|
||||
|
||||
/**
|
||||
* Tries to reduce the width of a widget.
|
||||
*
|
||||
|
@ -455,6 +446,15 @@ protected:
|
|||
void set_layout_size(const point& size);
|
||||
const point& layout_size() const;
|
||||
|
||||
/**
|
||||
* Throws away @ref layout_size_.
|
||||
*
|
||||
* Use with care: this function does not recurse to child widgets.
|
||||
*
|
||||
* See @ref layout_algorithm for more information.
|
||||
*/
|
||||
void clear_layout_size() { set_layout_size(point()); }
|
||||
|
||||
public:
|
||||
void set_linked_group(const std::string& linked_group);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue