Allow widgets to get the same size.

This is an initial implementation, it still needs quite some extra work,
which will be postponed until 1.7.
This commit is contained in:
Mark de Wever 2009-02-28 11:43:56 +00:00
parent 54de66b8d6
commit b6f49e0ff8
3 changed files with 114 additions and 1 deletions

View File

@ -42,6 +42,7 @@ class twidget
, public virtual tevent_executor
{
friend class tdebug_layout_graph;
friend class twindow; // needed for modifying the layout_size.
public:
twidget()

View File

@ -31,7 +31,6 @@
#include "titlescreen.hpp"
#include "video.hpp"
namespace gui2{
unsigned twindow::sunset_ = 0;
@ -116,6 +115,7 @@ twindow::twindow(CVideo& video,
, easy_close_(false)
, easy_close_blocker_()
, escape_disabled_(false)
, linked_size_()
, dirty_list_()
#ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
, debug_layout_(new tdebug_layout_graph(this))
@ -437,6 +437,23 @@ void twindow::remove_easy_close_blocker(const std::string& id)
easy_close_blocker_.end());
}
void twindow::init_linked_size_group(const std::string& id,
const bool fixed_width, const bool fixed_height)
{
assert(fixed_width || fixed_height);
assert(linked_size_.find(id) == linked_size_.end());
linked_size_[id] = tlinked_size(fixed_width, fixed_height);
}
void twindow::add_linked_widget(const std::string& id, twidget* widget)
{
assert(widget);
assert(linked_size_.find(id) != linked_size_.end());
linked_size_[id].widgets.push_back(widget);
}
void twindow::layout()
{
/**** Initialize and get initial size. *****/
@ -460,6 +477,45 @@ void twindow::layout()
const int maximum_height = automatic_placement_ ?
settings::screen_height : h_(variables);
/**
* @todo Need to document this new feature in the size algorithm. Also the
* fixed size only works when a widget doesn't get a second layout phase.
*/
// evaluate the group sizes
typedef std::pair<const std::string, tlinked_size> hack;
foreach(hack& linked_size, linked_size_) {
tpoint max_size(0, 0);
// Determine the maximum size.
foreach(twidget* widget, linked_size.second.widgets) {
const tpoint size = widget->get_best_size();
if(size.x > max_size.x) {
max_size.x = size.x;
}
if(size.y > max_size.y) {
max_size.y = size.y;
}
}
// Set the maximum size.
foreach(twidget* widget, linked_size.second.widgets) {
tpoint size = widget->get_best_size();
if(linked_size.second.width) {
size.x = max_size.x;
}
if(linked_size.second.height) {
size.y = max_size.y;
}
widget->set_layout_size(size);
}
}
tpoint size = get_best_size();
generate_dot_file("get_initial_best_size", LAYOUT);

View File

@ -50,7 +50,9 @@ class twindow : public tpanel, public tevent_handler
// Wants to use layout().
friend class tmessage;
public:
twindow(CVideo& video,
tformula<unsigned>x,
tformula<unsigned>y,
@ -242,6 +244,31 @@ public:
void set_escape_disabled(const bool escape_disabled)
{ escape_disabled_ = escape_disabled; }
/**
* Initializes a linked size group.
*
* Note at least one of fixed_width or fixed_height must be true.
*
* @param id The id of the group.
* @param fixed_width Does the group have a fixed width?
* @param fixed_height Does the group have a fixed height?
*/
void init_linked_size_group(const std::string& id,
const bool fixed_width, const bool fixed_height);
/**
* Adds a widget to a linked size group.
*
* The group needs to exist, which is done by calling
* init_linked_size_group. A widget may only be member of one group.
* @todo There's no way to remove a widget from the list.
* @todo Untested if a new widget is added after showing the widgets.
*
* @param id The id of the group.
* @param widget The widget to add to the group.
*/
void add_linked_widget(const std::string& id, twidget* widget);
/***** ***** ***** setters / getters for members ***** ****** *****/
/**
@ -358,6 +385,35 @@ private:
*/
static unsigned sunset_;
/**
* Helper struct to force widgets the have the same size.
*
* Widget which are linked will get the same width and/or height. This
* can especialy be usefull for listboxes, but can also be used for other
* applications.
*/
struct tlinked_size
{
tlinked_size(const bool width = false, const bool height = false)
: widgets()
, width(width)
, height(height)
{
}
/** The widgets linked. */
std::vector<twidget*> widgets;
/** Link the widgets in the width? */
bool width;
/** Link the widgets in the height? */
bool height;
};
/** List of the widgets, whose size are linked together. */
std::map<std::string, tlinked_size> linked_size_;
/** Layouts the window. */
void layout();