GUI2: When a label grows, attempt to only lay out the containing grid
This greatly improves responsiveness of the add-on manager (bug #25523).
This commit is contained in:
parent
27f2826703
commit
01035f0adc
6 changed files with 78 additions and 9 deletions
|
@ -1,4 +1,6 @@
|
|||
Version 1.13.7+dev:
|
||||
* Performance:
|
||||
* Greatly speeded up switching between add-ons in the add-on manager (bug #25523)
|
||||
|
||||
Version 1.13.7:
|
||||
* AI:
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "gui/core/log.hpp"
|
||||
#include "gui/core/layout_exception.hpp"
|
||||
#include "gui/widgets/styled_widget.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
|
@ -377,6 +378,43 @@ void grid::demand_reduce_height(const unsigned /*maximum_height*/)
|
|||
/** @todo Implement. */
|
||||
}
|
||||
|
||||
void grid::relayout()
|
||||
{
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
recalculate_best_size();
|
||||
|
||||
if(size.y >= best_size.y) {
|
||||
// We have enough space in the Y direction, but not in the X direction.
|
||||
// Try wrapping the content.
|
||||
request_reduce_width(size.x);
|
||||
best_size = get_best_size();
|
||||
|
||||
if(size.x >= best_size.x && size.y >= best_size.y) {
|
||||
// Wrapping succeeded, we still fit vertically.
|
||||
place(get_origin(), size);
|
||||
return;
|
||||
} else {
|
||||
// Wrapping failed, we no longer fit.
|
||||
// Reset the sizes of child widgets.
|
||||
layout_initialise(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Not enough space, ask the parent grid for more.
|
||||
grid* parent = get_parent_grid();
|
||||
if(parent != nullptr) {
|
||||
parent->relayout();
|
||||
} else {
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
}
|
||||
|
||||
point grid::recalculate_best_size()
|
||||
{
|
||||
point best_size = calculate_best_size();
|
||||
|
|
|
@ -220,6 +220,13 @@ 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.
|
||||
*
|
||||
|
|
|
@ -582,10 +582,11 @@ bool scrollbar_container::content_resize_request(const bool force_sizing)
|
|||
== widget::visibility::invisible)) {
|
||||
|
||||
DBG_GUI_L << LOG_HEADER
|
||||
<< " can't use horizontal scrollbar, ask window.\n";
|
||||
window* window = get_window();
|
||||
assert(window);
|
||||
window->invalidate_layout();
|
||||
<< " can't use horizontal scrollbar, ask grid.\n";
|
||||
layout_initialise(true);
|
||||
grid* grid = get_parent_grid();
|
||||
assert(grid);
|
||||
grid->relayout();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -598,10 +599,11 @@ bool scrollbar_container::content_resize_request(const bool force_sizing)
|
|||
== widget::visibility::invisible)) {
|
||||
|
||||
DBG_GUI_L << LOG_HEADER
|
||||
<< " can't use vertical scrollbar, ask window.\n";
|
||||
window* window = get_window();
|
||||
assert(window);
|
||||
window->invalidate_layout();
|
||||
<< " can't use vertical scrollbar, ask grid.\n";
|
||||
layout_initialise(true);
|
||||
grid* grid = get_parent_grid();
|
||||
assert(grid);
|
||||
grid->relayout();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||
|
||||
#include "gui/widgets/grid.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "gui/core/event/message.hpp"
|
||||
|
@ -137,6 +138,16 @@ const window* widget::get_window() const
|
|||
return dynamic_cast<const window*>(result);
|
||||
}
|
||||
|
||||
grid* widget::get_parent_grid()
|
||||
{
|
||||
widget* result = parent_;
|
||||
while(result && dynamic_cast<grid*>(result) == nullptr) {
|
||||
result = result->parent_;
|
||||
}
|
||||
|
||||
return result ? dynamic_cast<grid*>(result) : nullptr;
|
||||
}
|
||||
|
||||
dialogs::modal_dialog* widget::dialog()
|
||||
{
|
||||
window* window = get_window();
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace gui2
|
|||
struct builder_widget;
|
||||
namespace dialogs { class modal_dialog; }
|
||||
class window;
|
||||
class grid;
|
||||
|
||||
namespace iteration
|
||||
{
|
||||
|
@ -176,10 +177,18 @@ public:
|
|||
* Get the parent window.
|
||||
*
|
||||
* @returns Pointer to parent window.
|
||||
* @retval nullptr No parent window found.
|
||||
* @retval nullptr No parent window found.
|
||||
*/
|
||||
window* get_window();
|
||||
|
||||
/**
|
||||
* Get the parent grid.
|
||||
*
|
||||
* @returns Pointer to parent grid.
|
||||
* @retval nullptr No parent grid found.
|
||||
*/
|
||||
grid* get_parent_grid();
|
||||
|
||||
/** The constant version of @ref get_window. */
|
||||
const window* get_window() const;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue