Adds helper code to assist in widget placement.

The code is used to experiment with a different approach of the
implementation of a listbox.
This commit is contained in:
Mark de Wever 2012-05-19 20:06:35 +00:00
parent 2d9f94398d
commit 3c66f576d4
10 changed files with 555 additions and 0 deletions

View file

@ -166,6 +166,7 @@ Version 1.11.0-svn:
* Stop showing a unit's potential moves before moving in a move & attack,
rather than after (more consistent with regular movement)
* Changed: Made the id for a tooltip and helptip mandatory.
* Added: Helper code to assist in widget placement.
* Whiteboard:
* Fixed bug #19626: segfaults on window resize
* Fixed bug #19369: Using planning mode can cause losing ability to move my units

View file

@ -12,6 +12,9 @@ src/gui/auxiliary/iterator/iterator.cpp
src/gui/auxiliary/iterator/walker_grid.cpp
src/gui/auxiliary/iterator/walker_widget.cpp
src/gui/auxiliary/log.cpp
src/gui/auxiliary/placer.cpp
src/gui/auxiliary/placer/horizontal_list.cpp
src/gui/auxiliary/placer/vertical_list.cpp
src/gui/auxiliary/tips.cpp
src/gui/auxiliary/widget_definition/button.cpp
src/gui/auxiliary/widget_definition.cpp

View file

@ -418,6 +418,9 @@ set(wesnoth-main_SRC
gui/auxiliary/iterator/walker_grid.cpp
gui/auxiliary/iterator/walker_widget.cpp
gui/auxiliary/log.cpp
gui/auxiliary/placer.cpp
gui/auxiliary/placer/horizontal_list.cpp
gui/auxiliary/placer/vertical_list.cpp
gui/auxiliary/old_markup.cpp
gui/auxiliary/timer.cpp
gui/auxiliary/tips.cpp

View file

@ -262,6 +262,9 @@ wesnoth_sources = Split("""
gui/auxiliary/iterator/walker_grid.cpp
gui/auxiliary/iterator/walker_widget.cpp
gui/auxiliary/log.cpp
gui/auxiliary/placer.cpp
gui/auxiliary/placer/horizontal_list.cpp
gui/auxiliary/placer/vertical_list.cpp
gui/auxiliary/old_markup.cpp
gui/auxiliary/timer.cpp
gui/auxiliary/tips.cpp

View file

@ -0,0 +1,49 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#define ENUM_ENABLE_STREAM_OPERATORS_IMPLEMENTATION
#define ENUM_TYPE ::gui2::tplacer_
#define ENUM_LIST \
ENUM(horizontal, "horizontal"); \
ENUM(vertical, "vertical"); \
#include "gui/auxiliary/placer.hpp"
#include "gui/auxiliary/placer/horizontal_list.hpp"
#include "gui/auxiliary/placer/vertical_list.hpp"
ENUM_DEFINE_STREAM_OPERATORS(::gui2::tplacer_::tgrow_direction)
namespace gui2 {
tplacer_* tplacer_::build(
const tgrow_direction grow_direction
, const unsigned parallel_items)
{
switch(grow_direction) {
case horizontal :
return new implementation::tplacer_horizontal_list(parallel_items);
case vertical :
return new implementation::tplacer_vertical_list(parallel_items);
};
}
tplacer_::~tplacer_()
{
}
} // namespace gui2

View file

@ -0,0 +1,130 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* @file
* Base class for the placement helper.
*
* Some items can create new child items and these items are placed in some way
* this code contains helpers for the placement by calculating the positions
* for the items and the best size for the children.
*/
#ifndef GUI_AUXILIARY_PLACER_HPP_INCLUDED
#define GUI_AUXILIARY_PLACER_HPP_INCLUDED
namespace gui2 {
class tpoint;
/**
* Base class for the placement helper.
*
* The normal operation for the usage of the class is:
* * Call @ref initialise().
* * For every visible child item call @ref add_item() with the wanted size of
* the widget.
* Once this is done the required size for all children can be retrieved with
* @ref get_size(). It is also possible to place all children now. In order to
* do so loop again over all children in the same order as @ref add_item() and
* call @ref get_origin(). The @p index parameter is an increasing counter.
*
* @note The origins can only be retrieved after all items are added since the
* adding of a later item may influence a previous item. E.g. in a vertical
* list with two columns the position of the second column depends on the width
* of the first and a later row may have a wider column 1 as an earlier row.
*/
class tplacer_
{
public:
/***** ***** Types. ***** *****/
/** The direction the placer should grow towards. */
enum tgrow_direction
{
horizontal
, vertical
};
/***** ***** Constructor, destructor, assignment. ***** *****/
public:
/**
* Builder function.
*
* @pre @p parallel_items > 0
*
* @param grow_direction The direction in which the items will be
* added.
* @param parallel_items The direction perpendicular towards the grow
* direction has a fixed number of items. This
* value sets that limit. For a list containing
* only horizontally or vertically placed items
* the value should be 1.
*/
static tplacer_* build(
const tgrow_direction grow_direction
, const unsigned parallel_items);
virtual ~tplacer_();
/***** ***** Operations. ***** *****/
/**
* Initialises the placer.
*
* When the placement needs to be calculated the state often needs to be
* reset, items are placed, removed or changed visibility causing the old
* placement to be invalid.
*/
virtual void initialise() = 0;
/**
* Adds a item to be placed.
*
* @param size The required size for the item.
*/
virtual void add_item(const tpoint& size) = 0;
/**
* Gets the required size of all items.
*
* @returns The required size.
*/
virtual tpoint get_size() const = 0;
/**
* Gets the origin for an item.
*
* @param index The index of the item whose origin to return.
* The index is the index of the call to
* @ref add_item().
*
* @returns The origin where to place the widget.
*/
virtual tpoint get_origin(const unsigned index) const = 0;
};
} // namespace gui2
#include "enumerate.tpp"
ENUM_DECLARE_STREAM_OPERATORS(::gui2::tplacer_::tgrow_direction)
#endif

View file

@ -0,0 +1,89 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/auxiliary/placer/horizontal_list.hpp"
#include "gui/widgets/helper.hpp"
#include <cassert>
#include <numeric>
namespace gui2 {
namespace implementation {
tplacer_horizontal_list::tplacer_horizontal_list(const unsigned maximum_rows)
: maximum_rows_(maximum_rows)
, rows_(maximum_rows, 0)
, columns_(1, std::make_pair(0, 0))
, row_(0)
, column_(0)
{
assert(maximum_rows_ > 0);
}
void tplacer_horizontal_list::initialise()
{
std::fill(rows_.begin(), rows_.end(), 0);
columns_.clear();
columns_.push_back(std::make_pair(0, 0));
row_ = 0;
column_ = 0;
}
void tplacer_horizontal_list::add_item(const tpoint& size)
{
if(size.x > columns_[column_].second) {
columns_[column_].second = size.x;
}
if(size.y > rows_[row_]) {
rows_[row_]= size.y;
}
++row_;
if(row_ == maximum_rows_) {
row_ = 0;
++column_;
const int origin = columns_.back().first + columns_.back().second;
columns_.push_back(std::make_pair(origin, 0));
}
}
tpoint tplacer_horizontal_list::get_size() const
{
const int width = columns_.back().first + columns_.back().second;
const int height = std::accumulate(rows_.begin(), rows_.end(), 0);
return tpoint(width, height);
}
tpoint tplacer_horizontal_list::get_origin(const unsigned index) const
{
const unsigned row = index % maximum_rows_;
const unsigned column = index / maximum_rows_;
const int height = row == 0
? 0
: std::accumulate(rows_.begin(), rows_.begin() + row, 0);
return tpoint(columns_[column].first, height);
}
} // namespace implementation
} // namespace gui2

View file

@ -0,0 +1,95 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* @file
* Placement helper for the horizontal list.
*/
#ifndef GUI_AUXILIARY_PLACER_HORIZONTAL_LIST_HPP_INCLUDED
#define GUI_AUXILIARY_PLACER_HORIZONTAL_LIST_HPP_INCLUDED
#include "gui/auxiliary/placer.hpp"
#include <vector>
namespace gui2 {
namespace implementation {
/**
* The placement class for a horizontal list.
*
* @see @ref tplacer_ for more information.
*/
class tplacer_horizontal_list
: public tplacer_
{
public:
/***** ***** Constructor, destructor, assignment. ***** *****/
explicit tplacer_horizontal_list(const unsigned maximum_rows);
/***** ***** Inherited operations. ***** *****/
virtual void initialise();
virtual void add_item(const tpoint& size);
virtual tpoint get_size() const;
virtual tpoint get_origin(const unsigned index) const;
/***** ***** Members. ***** *****/
private:
/**
* The maximum number of rows to use.
*
* This value is determined by the @p parallel_items parameter of
* @ref tplacer_::build).
*/
unsigned maximum_rows_;
/** Holds the heights of the rows. */
std::vector<int> rows_;
/**
* Holds the column sizes
*
* The pair contains the following values:
* * first The origin of a column.
* * second The width of a column.
*/
std::vector<std::pair<int, int> > columns_;
/** The row to add an item to. */
unsigned row_;
/** The column to add an item to. */
unsigned column_;
};
} // namespace implementation
} // namespace gui2
#endif

View file

@ -0,0 +1,89 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/auxiliary/placer/vertical_list.hpp"
#include "gui/widgets/helper.hpp"
#include <cassert>
#include <numeric>
namespace gui2 {
namespace implementation {
tplacer_vertical_list::tplacer_vertical_list(const unsigned maximum_columns)
: maximum_columns_(maximum_columns)
, rows_(1, std::make_pair(0, 0))
, columns_(maximum_columns, 0)
, row_(0)
, column_(0)
{
assert(maximum_columns_ > 0);
}
void tplacer_vertical_list::initialise()
{
rows_.clear();
rows_.push_back(std::make_pair(0, 0));
std::fill(columns_.begin(), columns_.end(), 0);
row_ = 0;
column_ = 0;
}
void tplacer_vertical_list::add_item(const tpoint& size)
{
if(size.x > columns_[column_]) {
columns_[column_] = size.x;
}
if(size.y > rows_[row_].second) {
rows_[row_].second = size.y;
}
++column_;
if(column_ == maximum_columns_) {
column_ = 0;
++row_;
const int origin = rows_.back().first + rows_.back().second;
rows_.push_back(std::make_pair(origin, 0));
}
}
tpoint tplacer_vertical_list::get_size() const
{
const int width = std::accumulate(columns_.begin(), columns_.end(), 0);
const int height = rows_.back().first + rows_.back().second;
return tpoint(width, height);
}
tpoint tplacer_vertical_list::get_origin(const unsigned index) const
{
const unsigned row = index / maximum_columns_;
const unsigned column = index % maximum_columns_;
const int width = column == 0
? 0
: std::accumulate(columns_.begin(), columns_.begin() + column, 0);
return tpoint(width, rows_[row].first);
}
} // namespace implementation
} // namespace gui2

View file

@ -0,0 +1,93 @@
/* $Id$ */
/*
Copyright (C) 2012 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* @file
* Placement helper for the vertical list.
*/
#ifndef GUI_AUXILIARY_PLACER_VERTICAL_LIST_HPP_INCLUDED
#define GUI_AUXILIARY_PLACER_VERTICAL_LIST_HPP_INCLUDED
#include "gui/auxiliary/placer.hpp"
#include <vector>
namespace gui2 {
namespace implementation {
/**
* The placement class for a vertical list.
*
* @see @ref tplacer_ for more information.
*/
class tplacer_vertical_list
: public tplacer_
{
public:
/***** ***** Constructor, destructor, assignment. ***** *****/
explicit tplacer_vertical_list(const unsigned maximum_columns);
/***** ***** Inherited operations. ***** *****/
virtual void initialise();
virtual void add_item(const tpoint& size);
virtual tpoint get_size() const;
virtual tpoint get_origin(const unsigned index) const;
/***** ***** Members. ***** *****/
private:
/**
* The maximum number of colums to use.
*
* This value is determined by the @p parallel_items parameter of
* @ref tplacer_::build).
*/
unsigned maximum_columns_;
/**
* Holds the row sizes
*
* The pair contains the following values:
* * first The origin of a row.
* * second The height of a row.
*/
std::vector<std::pair<int, int> > rows_;
/** Holds the widths of the columns. */
std::vector<int> columns_;
/** The row to add an item to. */
unsigned row_;
/** The column to add an item to. */
unsigned column_;
};
} // namespace implementation
} // namespace gui2
#endif