Moved the tsizer class to grid.?pp and renamed it to tgrid.
This commit is contained in:
parent
9f342c90e1
commit
b6d222a683
6 changed files with 482 additions and 410 deletions
271
src/gui/widgets/grid.cpp
Normal file
271
src/gui/widgets/grid.cpp
Normal file
|
@ -0,0 +1,271 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
copyright (c) 2008 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 version 2
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "gui/widgets/grid.hpp"
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <numeric>
|
||||
|
||||
#define DBG_G LOG_STREAM(debug, gui)
|
||||
#define LOG_G LOG_STREAM(info, gui)
|
||||
#define WRN_G LOG_STREAM(warn, gui)
|
||||
#define ERR_G LOG_STREAM(err, gui)
|
||||
|
||||
#define DBG_G_D LOG_STREAM(debug, gui_draw)
|
||||
#define LOG_G_D LOG_STREAM(info, gui_draw)
|
||||
#define WRN_G_D LOG_STREAM(warn, gui_draw)
|
||||
#define ERR_G_D LOG_STREAM(err, gui_draw)
|
||||
|
||||
#define DBG_G_E LOG_STREAM(debug, gui_event)
|
||||
#define LOG_G_E LOG_STREAM(info, gui_event)
|
||||
#define WRN_G_E LOG_STREAM(warn, gui_event)
|
||||
#define ERR_G_E LOG_STREAM(err, gui_event)
|
||||
|
||||
#define DBG_G_P LOG_STREAM(debug, gui_parse)
|
||||
#define LOG_G_P LOG_STREAM(info, gui_parse)
|
||||
#define WRN_G_P LOG_STREAM(warn, gui_parse)
|
||||
#define ERR_G_P LOG_STREAM(err, gui_parse)
|
||||
|
||||
|
||||
namespace gui2 {
|
||||
|
||||
tgrid::tgrid(const unsigned rows, const unsigned cols,
|
||||
const unsigned default_flags, const unsigned default_border_size) :
|
||||
rows_(rows),
|
||||
cols_(cols),
|
||||
default_flags_(default_flags),
|
||||
default_border_size_(default_border_size),
|
||||
children_(rows * cols)
|
||||
{
|
||||
}
|
||||
|
||||
tgrid::~tgrid()
|
||||
{
|
||||
for(std::vector<tchild>::iterator itor = children_.begin();
|
||||
itor != children_.end(); ++itor) {
|
||||
|
||||
if(itor->widget()) {
|
||||
delete itor->widget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tgrid::add_child(twidget* widget, const unsigned row,
|
||||
const unsigned col, const unsigned flags, const unsigned border_size)
|
||||
{
|
||||
assert(row < rows_ && col < cols_);
|
||||
|
||||
tchild& cell = child(row, col);
|
||||
|
||||
// clear old child if any
|
||||
if(cell.widget()) {
|
||||
// free a child when overwriting it
|
||||
WRN_G << "Grid: child '" << cell.id()
|
||||
<< "' at cell '" << row << ',' << col << "' will be replaced.\n";
|
||||
delete cell.widget();
|
||||
}
|
||||
|
||||
// copy data
|
||||
cell.set_flags(flags);
|
||||
cell.set_border_size(border_size);
|
||||
cell.set_widget(widget);
|
||||
if(cell.widget()) {
|
||||
// make sure the new child is valid before deferring
|
||||
cell.set_id(cell.widget()->id());
|
||||
cell.widget()->set_parent(this);
|
||||
} else {
|
||||
cell.set_id("");
|
||||
}
|
||||
}
|
||||
|
||||
void tgrid::set_rows(const unsigned rows)
|
||||
{
|
||||
if(rows == rows_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!children_.empty()) {
|
||||
WRN_G << "Grid: resizing a non-empty grid may give unexpected problems.\n";
|
||||
}
|
||||
|
||||
rows_ = rows;
|
||||
children_.resize(rows_ * cols_);
|
||||
}
|
||||
|
||||
void tgrid::set_cols(const unsigned cols)
|
||||
{
|
||||
if(cols == cols_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!children_.empty()) {
|
||||
WRN_G << "Grid: resizing a non-empty grid may give unexpected problems.\n";
|
||||
}
|
||||
|
||||
cols_ = cols;
|
||||
children_.resize(cols_ * cols_);
|
||||
}
|
||||
|
||||
void tgrid::remove_child(const unsigned row, const unsigned col)
|
||||
{
|
||||
assert(row < rows_ && col < cols_);
|
||||
|
||||
tchild& cell = child(row, col);
|
||||
|
||||
cell.set_id("");
|
||||
cell.set_widget(0);
|
||||
}
|
||||
|
||||
void tgrid::removed_child(const std::string& id, const bool find_all)
|
||||
{
|
||||
for(std::vector<tchild>::iterator itor = children_.begin();
|
||||
itor != children_.end(); ++itor) {
|
||||
|
||||
if(itor->id() == id) {
|
||||
itor->set_id("");
|
||||
itor->set_widget(0);
|
||||
|
||||
if(!find_all) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpoint tgrid::get_best_size()
|
||||
{
|
||||
std::vector<unsigned> best_col_width(cols_, 0);
|
||||
std::vector<unsigned> best_row_height(rows_, 0);
|
||||
|
||||
// First get the best sizes for all items.
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
const tpoint size = child(row, col).get_best_size();
|
||||
|
||||
if(size.x > best_col_width[col]) {
|
||||
best_col_width[col] = size.x;
|
||||
}
|
||||
|
||||
if(size.y > best_row_height[row]) {
|
||||
best_row_height[row] = size.y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
DBG_G << "Grid: the best height for row " << row
|
||||
<< " will be " << best_row_height[row] << ".\n";
|
||||
}
|
||||
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
DBG_G << "Grid: the best width for col " << col
|
||||
<< " will be " << best_col_width[col] << ".\n";
|
||||
}
|
||||
|
||||
return tpoint(
|
||||
std::accumulate(best_col_width.begin(), best_col_width.end(), 0),
|
||||
std::accumulate(best_row_height.begin(), best_row_height.end(), 0));
|
||||
|
||||
}
|
||||
|
||||
void tgrid::set_best_size(const tpoint& origin)
|
||||
{
|
||||
std::vector<unsigned> best_col_width(cols_, 0);
|
||||
std::vector<unsigned> best_row_height(rows_, 0);
|
||||
|
||||
// First get the best sizes for all items. (FIXME copy and paste of get best size)
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
const tpoint size = child(row, col).get_best_size();
|
||||
|
||||
if(size.x > best_col_width[col]) {
|
||||
best_col_width[col] = size.x;
|
||||
}
|
||||
|
||||
if(size.y > best_row_height[row]) {
|
||||
best_row_height[row] = size.y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Set the sizes
|
||||
tpoint orig = origin;
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
DBG_G << "Grid: set widget at " << row
|
||||
<< ',' << col << " at origin " << orig << ".\n";
|
||||
|
||||
if(child(row, col).widget()) {
|
||||
child(row, col).widget()->set_best_size(orig);
|
||||
}
|
||||
|
||||
orig.x += best_col_width[col];
|
||||
}
|
||||
orig.y += best_row_height[row];
|
||||
orig.x = origin.x;
|
||||
}
|
||||
}
|
||||
|
||||
twidget* tgrid::get_widget(const tpoint& coordinate)
|
||||
{
|
||||
|
||||
//! FIXME we need to store the sizes, since this is quite
|
||||
//! pathatic.
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
twidget* widget = child(row, col).widget();
|
||||
if(!widget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
widget = widget->get_widget(coordinate);
|
||||
if(widget) {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tpoint tgrid::tchild::get_best_size()
|
||||
{
|
||||
if(!dirty_ && (!widget_ || !widget_->dirty())) {
|
||||
return best_size_;
|
||||
}
|
||||
|
||||
best_size_ = widget_ ? widget_->get_best_size() : tpoint(0, 0);
|
||||
|
||||
//FIXME take care of the border configuration.
|
||||
best_size_.x += 2 * border_size_;
|
||||
best_size_.y += 2 * border_size_;
|
||||
|
||||
dirty_ = false;
|
||||
|
||||
return best_size_;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace gui2
|
||||
|
||||
|
206
src/gui/widgets/grid.hpp
Normal file
206
src/gui/widgets/grid.hpp
Normal file
|
@ -0,0 +1,206 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
copyright (c) 2008 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 version 2
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __GUI_WIDGETS_GRID_HPP_INCLUDED__
|
||||
#define __GUI_WIDGETS_GRID_HPP_INCLUDED__
|
||||
|
||||
#include "gui/widgets/widget.hpp"
|
||||
|
||||
namespace gui2 {
|
||||
|
||||
//! Base container class which needs to size children
|
||||
class tgrid : public virtual twidget
|
||||
{
|
||||
|
||||
public:
|
||||
// ***** ***** FLAGS ***** *****
|
||||
static const unsigned VERTICAL_RESIZE_GROW = 1 << 1;
|
||||
static const unsigned VERTICAL_GROW_SEND_TO_CLIENT = 1 << 2;
|
||||
|
||||
static const unsigned VERTICAL_ALIGN_TOP = 1 << 4;
|
||||
static const unsigned VERTICAL_ALIGN_CENTER = 1 << 5;
|
||||
static const unsigned VERTICAL_ALIGN_BOTTOM = 1 << 6;
|
||||
static const unsigned VERTICAL_ALIGN_LANGUAGE = 1 << 7;
|
||||
|
||||
|
||||
static const unsigned HORIZONTAL_RESIZE_GROW = 1 << 16;
|
||||
static const unsigned HORIZONTAL_GROW_SEND_TO_CLIENT = 1 << 17;
|
||||
|
||||
static const unsigned HORIZONTAL_ALIGN_TOP = 1 << 18;
|
||||
static const unsigned HORIZONTAL_ALIGN_CENTER = 1 << 19;
|
||||
static const unsigned HORIZONTAL_ALIGN_BOTTOM = 1 << 20;
|
||||
static const unsigned HORIZONTAL_ALIGN_LANGUAGE = 1 << 21;
|
||||
|
||||
|
||||
static const unsigned BORDER_TOP = 1 << 24;
|
||||
static const unsigned BORDER_BOTTOM = 1 << 25;
|
||||
static const unsigned BORDER_LEFT = 1 << 26;
|
||||
static const unsigned BORDER_RIGHT = 1 << 27;
|
||||
|
||||
|
||||
tgrid(const unsigned rows, const unsigned cols,
|
||||
const unsigned default_flags, const unsigned default_border_size);
|
||||
|
||||
virtual ~tgrid();
|
||||
|
||||
void add_child(twidget* widget, const unsigned row,
|
||||
const unsigned col, const unsigned flags, const unsigned border_size);
|
||||
|
||||
void add_child(twidget* widget, const unsigned row, const unsigned col)
|
||||
{ add_child(widget, row, col, default_flags_, default_border_size_); }
|
||||
|
||||
void add_child(twidget* widget, const unsigned row, const unsigned col, const unsigned flags)
|
||||
{ add_child(widget, row, col, flags, default_border_size_); }
|
||||
|
||||
|
||||
void set_rows(const unsigned rows);
|
||||
unsigned int get_rows() const { return rows_; }
|
||||
|
||||
void set_cols(const unsigned cols);
|
||||
unsigned int get_cols() const { return cols_; }
|
||||
|
||||
void remove_child(const unsigned row, const unsigned col);
|
||||
void removed_child(const std::string& id, const bool find_all = false);
|
||||
|
||||
//! Inherited
|
||||
tpoint get_best_size();
|
||||
|
||||
//! Inherited
|
||||
void set_best_size(const tpoint& origin);
|
||||
|
||||
//! Gets the widget at the wanted coordinates.
|
||||
//! Override base class.
|
||||
twidget* get_widget(const tpoint& coordinate);
|
||||
|
||||
private:
|
||||
class tchild
|
||||
{
|
||||
public:
|
||||
tchild() :
|
||||
id_(),
|
||||
flags_(0),
|
||||
border_size_(0),
|
||||
widget_(0),
|
||||
best_size_(0, 0),
|
||||
dirty_(true),
|
||||
clip_()
|
||||
|
||||
// Fixme make a class wo we can store some properties in the cache
|
||||
// regarding size etc.
|
||||
{}
|
||||
|
||||
const std::string& id() const { return id_; }
|
||||
void set_id(const std::string& id) { id_ = id; }
|
||||
|
||||
unsigned get_flags() const { return flags_; }
|
||||
void set_flags(const unsigned flags) { flags_ = flags; dirty_ = true; }
|
||||
|
||||
unsigned get_border_size() const { return border_size_; }
|
||||
void set_border_size(const unsigned border_size)
|
||||
{ border_size_ = border_size; dirty_ = true; }
|
||||
|
||||
twidget* widget() { return widget_; }
|
||||
void set_widget(twidget* widget) { widget_ = widget; dirty_ = true; }
|
||||
|
||||
//! Gets the best size for the cell, not const since we modify the internal
|
||||
//! state, might use mutable later (if really needed).
|
||||
tpoint get_best_size();
|
||||
|
||||
private:
|
||||
//! The id of the widget if it has a widget.
|
||||
std::string id_;
|
||||
|
||||
//! The flags for the border and cell setup.
|
||||
unsigned flags_;
|
||||
|
||||
//! The size of the border, the actual configuration of the border
|
||||
//! is determined by the flags.
|
||||
unsigned border_size_;
|
||||
|
||||
//! Pointer to the widget. FIXME who owns the widget....
|
||||
twidget* widget_;
|
||||
|
||||
//! The best size for this cell, determined by the best size
|
||||
//! of the widget and the border_size_ and flags_.
|
||||
tpoint best_size_;
|
||||
|
||||
//! Tracks the dirty state of the cell regarding best_size_.
|
||||
bool dirty_;
|
||||
|
||||
//! The clipping area for the widget. This is also the size of
|
||||
//! the container.
|
||||
SDL_Rect clip_;
|
||||
|
||||
}; // class tchild
|
||||
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
iterator(std::vector<tchild>::iterator itor) :
|
||||
itor_(itor)
|
||||
{}
|
||||
|
||||
iterator operator++() { return iterator(++itor_); }
|
||||
iterator operator--() { return iterator(--itor_); }
|
||||
twidget* operator->() { return itor_->widget(); }
|
||||
twidget* operator*() { return itor_->widget(); }
|
||||
|
||||
bool operator!=(const iterator& i) const
|
||||
{ return i.itor_ != this->itor_; }
|
||||
|
||||
private:
|
||||
std::vector<tchild>::iterator itor_;
|
||||
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(children_.begin()); }
|
||||
iterator end() { return iterator(children_.end()); }
|
||||
|
||||
private:
|
||||
unsigned rows_;
|
||||
unsigned cols_;
|
||||
|
||||
const unsigned default_flags_;
|
||||
|
||||
const unsigned default_border_size_;
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<tchild> children_;
|
||||
tchild& child(const unsigned row, const unsigned col)
|
||||
{ return children_[rows_ * col + row]; }
|
||||
|
||||
};
|
||||
|
||||
//! Visible container to hold children.
|
||||
class tpanel : public tgrid, public tcontrol
|
||||
{
|
||||
|
||||
public:
|
||||
tpanel() :
|
||||
tgrid(0, 0, 0, 0),
|
||||
tcontrol()
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace gui2
|
||||
|
||||
#endif
|
|
@ -21,7 +21,6 @@
|
|||
#include "serialization/preprocessor.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <numeric>
|
||||
|
||||
#define DBG_G LOG_STREAM(debug, gui)
|
||||
#define LOG_G LOG_STREAM(info, gui)
|
||||
|
@ -114,229 +113,6 @@ bool tcontainer::remove_child(const std::string& id)
|
|||
}
|
||||
#endif
|
||||
|
||||
tsizer::tsizer(const unsigned rows, const unsigned cols,
|
||||
const unsigned default_flags, const unsigned default_border_size) :
|
||||
rows_(rows),
|
||||
cols_(cols),
|
||||
default_flags_(default_flags),
|
||||
default_border_size_(default_border_size),
|
||||
children_(rows * cols)
|
||||
{
|
||||
}
|
||||
|
||||
tsizer::~tsizer()
|
||||
{
|
||||
for(std::vector<tchild>::iterator itor = children_.begin();
|
||||
itor != children_.end(); ++itor) {
|
||||
|
||||
if(itor->widget()) {
|
||||
delete itor->widget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsizer::add_child(twidget* widget, const unsigned row,
|
||||
const unsigned col, const unsigned flags, const unsigned border_size)
|
||||
{
|
||||
assert(row < rows_ && col < cols_);
|
||||
|
||||
tchild& cell = child(row, col);
|
||||
|
||||
// clear old child if any
|
||||
if(cell.widget()) {
|
||||
// free a child when overwriting it
|
||||
WRN_G << "Grid: child '" << cell.id()
|
||||
<< "' at cell '" << row << ',' << col << "' will be replaced.\n";
|
||||
delete cell.widget();
|
||||
}
|
||||
|
||||
// copy data
|
||||
cell.set_flags(flags);
|
||||
cell.set_border_size(border_size);
|
||||
cell.set_widget(widget);
|
||||
if(cell.widget()) {
|
||||
// make sure the new child is valid before deferring
|
||||
cell.set_id(cell.widget()->id());
|
||||
cell.widget()->set_parent(this);
|
||||
} else {
|
||||
cell.set_id("");
|
||||
}
|
||||
}
|
||||
|
||||
void tsizer::set_rows(const unsigned rows)
|
||||
{
|
||||
if(rows == rows_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!children_.empty()) {
|
||||
WRN_G << "Grid: resizing a non-empty grid may give unexpected problems.\n";
|
||||
}
|
||||
|
||||
rows_ = rows;
|
||||
children_.resize(rows_ * cols_);
|
||||
}
|
||||
|
||||
void tsizer::set_cols(const unsigned cols)
|
||||
{
|
||||
if(cols == cols_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!children_.empty()) {
|
||||
WRN_G << "Grid: resizing a non-empty grid may give unexpected problems.\n";
|
||||
}
|
||||
|
||||
cols_ = cols;
|
||||
children_.resize(cols_ * cols_);
|
||||
}
|
||||
|
||||
void tsizer::remove_child(const unsigned row, const unsigned col)
|
||||
{
|
||||
assert(row < rows_ && col < cols_);
|
||||
|
||||
tchild& cell = child(row, col);
|
||||
|
||||
cell.set_id("");
|
||||
cell.set_widget(0);
|
||||
}
|
||||
|
||||
void tsizer::removed_child(const std::string& id, const bool find_all)
|
||||
{
|
||||
for(std::vector<tchild>::iterator itor = children_.begin();
|
||||
itor != children_.end(); ++itor) {
|
||||
|
||||
if(itor->id() == id) {
|
||||
itor->set_id("");
|
||||
itor->set_widget(0);
|
||||
|
||||
if(!find_all) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpoint tsizer::get_best_size()
|
||||
{
|
||||
std::vector<unsigned> best_col_width(cols_, 0);
|
||||
std::vector<unsigned> best_row_height(rows_, 0);
|
||||
|
||||
// First get the best sizes for all items.
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
const tpoint size = child(row, col).get_best_size();
|
||||
|
||||
if(size.x > best_col_width[col]) {
|
||||
best_col_width[col] = size.x;
|
||||
}
|
||||
|
||||
if(size.y > best_row_height[row]) {
|
||||
best_row_height[row] = size.y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
DBG_G << "Grid: the best height for row " << row
|
||||
<< " will be " << best_row_height[row] << ".\n";
|
||||
}
|
||||
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
DBG_G << "Grid: the best width for col " << col
|
||||
<< " will be " << best_col_width[col] << ".\n";
|
||||
}
|
||||
|
||||
return tpoint(
|
||||
std::accumulate(best_col_width.begin(), best_col_width.end(), 0),
|
||||
std::accumulate(best_row_height.begin(), best_row_height.end(), 0));
|
||||
|
||||
}
|
||||
|
||||
void tsizer::set_best_size(const tpoint& origin)
|
||||
{
|
||||
std::vector<unsigned> best_col_width(cols_, 0);
|
||||
std::vector<unsigned> best_row_height(rows_, 0);
|
||||
|
||||
// First get the best sizes for all items. (FIXME copy and paste of get best size)
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
const tpoint size = child(row, col).get_best_size();
|
||||
|
||||
if(size.x > best_col_width[col]) {
|
||||
best_col_width[col] = size.x;
|
||||
}
|
||||
|
||||
if(size.y > best_row_height[row]) {
|
||||
best_row_height[row] = size.y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Set the sizes
|
||||
tpoint orig = origin;
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
DBG_G << "Grid: set widget at " << row
|
||||
<< ',' << col << " at origin " << orig << ".\n";
|
||||
|
||||
if(child(row, col).widget()) {
|
||||
child(row, col).widget()->set_best_size(orig);
|
||||
}
|
||||
|
||||
orig.x += best_col_width[col];
|
||||
}
|
||||
orig.y += best_row_height[row];
|
||||
orig.x = origin.x;
|
||||
}
|
||||
}
|
||||
|
||||
twidget* tsizer::get_widget(const tpoint& coordinate)
|
||||
{
|
||||
|
||||
//! FIXME we need to store the sizes, since this is quite
|
||||
//! pathatic.
|
||||
for(unsigned row = 0; row < rows_; ++row) {
|
||||
for(unsigned col = 0; col < cols_; ++col) {
|
||||
|
||||
twidget* widget = child(row, col).widget();
|
||||
if(!widget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
widget = widget->get_widget(coordinate);
|
||||
if(widget) {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tpoint tsizer::tchild::get_best_size()
|
||||
{
|
||||
if(!dirty_ && (!widget_ || !widget_->dirty())) {
|
||||
return best_size_;
|
||||
}
|
||||
|
||||
best_size_ = widget_ ? widget_->get_best_size() : tpoint(0, 0);
|
||||
|
||||
//FIXME take care of the border configuration.
|
||||
best_size_.x += 2 * border_size_;
|
||||
best_size_.y += 2 * border_size_;
|
||||
|
||||
dirty_ = false;
|
||||
|
||||
return best_size_;
|
||||
|
||||
}
|
||||
|
||||
tcontrol::tcontrol(/*const int x, const int y, const int w, const int h*/) :
|
||||
/* x_(x),
|
||||
y_(y),
|
||||
|
|
|
@ -276,174 +276,6 @@ private:
|
|||
};
|
||||
#endif
|
||||
|
||||
//! Base container class which needs to size children
|
||||
class tsizer : /*public tcontainer,*/ public virtual twidget
|
||||
{
|
||||
|
||||
public:
|
||||
// ***** ***** FLAGS ***** *****
|
||||
static const unsigned VERTICAL_RESIZE_GROW = 1 << 1;
|
||||
static const unsigned VERTICAL_GROW_SEND_TO_CLIENT = 1 << 2;
|
||||
|
||||
static const unsigned VERTICAL_ALIGN_TOP = 1 << 4;
|
||||
static const unsigned VERTICAL_ALIGN_CENTER = 1 << 5;
|
||||
static const unsigned VERTICAL_ALIGN_BOTTOM = 1 << 6;
|
||||
static const unsigned VERTICAL_ALIGN_LANGUAGE = 1 << 7;
|
||||
|
||||
|
||||
static const unsigned HORIZONTAL_RESIZE_GROW = 1 << 16;
|
||||
static const unsigned HORIZONTAL_GROW_SEND_TO_CLIENT = 1 << 17;
|
||||
|
||||
static const unsigned HORIZONTAL_ALIGN_TOP = 1 << 18;
|
||||
static const unsigned HORIZONTAL_ALIGN_CENTER = 1 << 19;
|
||||
static const unsigned HORIZONTAL_ALIGN_BOTTOM = 1 << 20;
|
||||
static const unsigned HORIZONTAL_ALIGN_LANGUAGE = 1 << 21;
|
||||
|
||||
|
||||
static const unsigned BORDER_TOP = 1 << 24;
|
||||
static const unsigned BORDER_BOTTOM = 1 << 25;
|
||||
static const unsigned BORDER_LEFT = 1 << 26;
|
||||
static const unsigned BORDER_RIGHT = 1 << 27;
|
||||
|
||||
|
||||
tsizer(const unsigned rows, const unsigned cols,
|
||||
const unsigned default_flags, const unsigned default_border_size);
|
||||
|
||||
virtual ~tsizer();
|
||||
|
||||
void add_child(twidget* widget, const unsigned row,
|
||||
const unsigned col, const unsigned flags, const unsigned border_size);
|
||||
|
||||
void add_child(twidget* widget, const unsigned row, const unsigned col)
|
||||
{ add_child(widget, row, col, default_flags_, default_border_size_); }
|
||||
|
||||
void add_child(twidget* widget, const unsigned row, const unsigned col, const unsigned flags)
|
||||
{ add_child(widget, row, col, flags, default_border_size_); }
|
||||
|
||||
|
||||
void set_rows(const unsigned rows);
|
||||
unsigned int get_rows() const { return rows_; }
|
||||
|
||||
void set_cols(const unsigned cols);
|
||||
unsigned int get_cols() const { return cols_; }
|
||||
|
||||
void remove_child(const unsigned row, const unsigned col);
|
||||
void removed_child(const std::string& id, const bool find_all = false);
|
||||
|
||||
//! Inherited
|
||||
tpoint get_best_size();
|
||||
|
||||
//! Inherited
|
||||
void set_best_size(const tpoint& origin);
|
||||
|
||||
//! Gets the widget at the wanted coordinates.
|
||||
//! Override base class.
|
||||
twidget* get_widget(const tpoint& coordinate);
|
||||
|
||||
private:
|
||||
class tchild
|
||||
{
|
||||
public:
|
||||
tchild() :
|
||||
id_(),
|
||||
flags_(0),
|
||||
border_size_(0),
|
||||
widget_(0),
|
||||
best_size_(0, 0),
|
||||
dirty_(true),
|
||||
clip_()
|
||||
|
||||
// Fixme make a class wo we can store some properties in the cache
|
||||
// regarding size etc.
|
||||
{}
|
||||
|
||||
const std::string& id() const { return id_; }
|
||||
void set_id(const std::string& id) { id_ = id; }
|
||||
|
||||
unsigned get_flags() const { return flags_; }
|
||||
void set_flags(const unsigned flags) { flags_ = flags; dirty_ = true; }
|
||||
|
||||
unsigned get_border_size() const { return border_size_; }
|
||||
void set_border_size(const unsigned border_size)
|
||||
{ border_size_ = border_size; dirty_ = true; }
|
||||
|
||||
twidget* widget() { return widget_; }
|
||||
void set_widget(twidget* widget) { widget_ = widget; dirty_ = true; }
|
||||
|
||||
//! Gets the best size for the cell, not const since we modify the internal
|
||||
//! state, might use mutable later (if really needed).
|
||||
tpoint get_best_size();
|
||||
|
||||
private:
|
||||
//! The id of the widget if it has a widget.
|
||||
std::string id_;
|
||||
|
||||
//! The flags for the border and cell setup.
|
||||
unsigned flags_;
|
||||
|
||||
//! The size of the border, the actual configuration of the border
|
||||
//! is determined by the flags.
|
||||
unsigned border_size_;
|
||||
|
||||
//! Pointer to the widget. FIXME who owns the widget....
|
||||
twidget* widget_;
|
||||
|
||||
//! The best size for this cell, determined by the best size
|
||||
//! of the widget and the border_size_ and flags_.
|
||||
tpoint best_size_;
|
||||
|
||||
//! Tracks the dirty state of the cell regarding best_size_.
|
||||
bool dirty_;
|
||||
|
||||
//! The clipping area for the widget. This is also the size of
|
||||
//! the container.
|
||||
SDL_Rect clip_;
|
||||
|
||||
}; // class tchild
|
||||
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
iterator(std::vector<tchild>::iterator itor) :
|
||||
itor_(itor)
|
||||
{}
|
||||
|
||||
iterator operator++() { return iterator(++itor_); }
|
||||
iterator operator--() { return iterator(--itor_); }
|
||||
twidget* operator->() { return itor_->widget(); }
|
||||
twidget* operator*() { return itor_->widget(); }
|
||||
|
||||
bool operator!=(const iterator& i) const
|
||||
{ return i.itor_ != this->itor_; }
|
||||
|
||||
private:
|
||||
std::vector<tchild>::iterator itor_;
|
||||
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(children_.begin()); }
|
||||
iterator end() { return iterator(children_.end()); }
|
||||
|
||||
private:
|
||||
unsigned rows_;
|
||||
unsigned cols_;
|
||||
|
||||
const unsigned default_flags_;
|
||||
|
||||
const unsigned default_border_size_;
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<tchild> children_;
|
||||
tchild& child(const unsigned row, const unsigned col)
|
||||
{ return children_[rows_ * col + row]; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! Base class for all visible items.
|
||||
class tcontrol : public virtual twidget
|
||||
|
@ -503,20 +335,7 @@ private:
|
|||
surface canvas_;
|
||||
};
|
||||
|
||||
//! Visible container to hold children.
|
||||
class tpanel : public tsizer, public tcontrol
|
||||
{
|
||||
|
||||
public:
|
||||
tpanel() :
|
||||
tsizer(0, 0, 0, 0),
|
||||
tcontrol()
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* tscroll_panel is a panel which handels scrolling for
|
||||
* clients which have more data then can be shown
|
||||
|
@ -525,7 +344,7 @@ private:
|
|||
class tscrollpanel : public tpanel /*etc*/
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
/**
|
||||
* The slider has a few extra option
|
||||
* min, max minimum maximum of the slider
|
||||
|
|
|
@ -120,7 +120,7 @@ void twindow::show(const bool restore, void* /*flip_function*/)
|
|||
fill_rect_alpha(temp_rect, 0, 1, screen);
|
||||
#endif
|
||||
|
||||
for(tsizer::iterator itor = begin(); itor != end(); ++itor) {
|
||||
for(tgrid::iterator itor = begin(); itor != end(); ++itor) {
|
||||
|
||||
if(! *itor || !itor->dirty()) {
|
||||
continue;
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
#ifndef __GUI_WIDGETS_WINDOW_HPP_INCLUDED__
|
||||
#define __GUI_WIDGETS_WINDOW_HPP_INCLUDED__
|
||||
|
||||
#include "gui/widgets/widget.hpp"
|
||||
#include "gui/widgets/canvas.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/event_info.hpp"
|
||||
#include "gui/widgets/grid.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
|
||||
#include "sdl_utils.hpp"
|
||||
#include "video.hpp"
|
||||
|
|
Loading…
Add table
Reference in a new issue