Author: mordante
Date: Sun Mar 9 13:34:16 2008
New Revision: 24438
URL: http://svn.gna.org/viewcvs/wesnoth?rev=24438&view=rev
Log:
Various improvements in order to make the automatic layout of a window
and it's children work.
Modified:
trunk/src/gui/widgets/widget.cpp
trunk/src/gui/widgets/widget.hpp
trunk/src/gui/widgets/window.cpp
trunk/src/gui/widgets/window.hpp
Modified: trunk/src/gui/widgets/widget.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/widget.cpp?rev=24438&r1=24437&r2=24438&view=diff
==============================================================================
--- trunk/src/gui/widgets/widget.cpp (original)
+++ trunk/src/gui/widgets/widget.cpp Sun Mar 9 13:34:16 2008
@@ -21,6 +21,7 @@
#include "serialization/preprocessor.hpp"
#include <cassert>
+#include <numeric>
#define DBG_GUI LOG_STREAM(debug, widget)
#define LOG_GUI LOG_STREAM(info, widget)
@@ -45,6 +46,17 @@
initialized_ = true;
return initialized_;
+}
+
+SDL_Rect create_rect(const tpoint& origin, const tpoint& size)
+{
+ return ::create_rect(origin.x, origin.y, size.x, size.y);
+}
+
+std::ostream &operator<<(std::ostream &stream, const tpoint& point)
+{
+ stream << point.x << ',' << point.y;
+ return stream;
}
#if 0
@@ -102,8 +114,8 @@
for(std::vector<tchild>::iterator itor = children_.begin();
itor != children_.end(); ++itor) {
- if(itor->widget) {
- delete itor->widget;
+ if(itor->widget()) {
+ delete itor->widget();
}
}
}
@@ -116,23 +128,23 @@
tchild& cell = child(row, col);
// clear old child if any
- if(cell.widget) {
+ if(cell.widget()) {
// free a child when overwriting it
- LOG_GUI << "Child '" << cell.id << "' at cell '"
+ LOG_GUI << "Child '" << cell.id() << "' at cell '"
<< row << "," << col << "' will be overwritten and is
disposed\n";
- delete cell.widget;
+ delete cell.widget();
}
// copy data
- cell.flags = flags;
- cell.border_size = border_size;
- cell.widget = widget;
- if(cell.widget) {
+ 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.id = cell.widget->id();
+ cell.set_id(cell.widget()->id());
// cell.widget->parent() = this; FIXME enable
} else {
- cell.id = "";
+ cell.set_id("");
}
}
@@ -170,8 +182,8 @@
tchild& cell = child(row, col);
- cell.id = "";
- cell.widget = 0;
+ cell.set_id("");
+ cell.set_widget(0);
}
void tsizer::removed_child(const std::string& id, const bool find_all)
@@ -180,9 +192,9 @@
for(std::vector<tchild>::iterator itor = children_.begin();
itor != children_.end(); ++itor) {
- if(itor->id == id) {
- itor->id = "";
- itor->widget = 0;
+ if(itor->id() == id) {
+ itor->set_id("");
+ itor->set_widget(0);
if(!find_all) {
break;
@@ -191,43 +203,103 @@
}
}
-void tsizer::layout()
-{
-
+tpoint tsizer::get_best_size()
+{
DBG_GUI << __FUNCTION__ << '\n';
- std::vector<unsigned> best_col_width;
- std::vector<unsigned> best_row_height;
+ 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) {
- }
- }
-
- // Does the best fit if so set the best, else
- // we need to determine the minimum and optimize.
-
- // FIXME improve
- tpoint start(10, 10);
- for(std::vector<tchild>::iterator itor = children_.begin();
- itor != children_.end(); ++itor) {
-
- if(itor->widget) {
- tpoint size = itor->widget->get_best_size();
-
- itor->widget->set_x(start.x);
- itor->widget->set_y(start.y);
-
- itor->widget->set_width(size.x);
- itor->widget->set_height(size.y);
-
- start.y += 30;
- }
- }
-}
-
+ 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_GUI << "Row " << row << ": " << best_row_height[row] <<
'\n';
+ }
+
+ for(unsigned col = 0; col < cols_; ++col) {
+ DBG_GUI << "Col " << col << ": " << 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)
+{
+ DBG_GUI << __FUNCTION__ << '\n';
+
+ 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_GUI << "Row : " << row << " col : " << col << " put
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;
+ }
+}
+
+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*/) :
twidget("") ,
Modified: trunk/src/gui/widgets/widget.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/widget.hpp?rev=24438&r1=24437&r2=24438&view=diff
==============================================================================
--- trunk/src/gui/widgets/widget.hpp (original)
+++ trunk/src/gui/widgets/widget.hpp Sun Mar 9 13:34:16 2008
@@ -47,6 +47,10 @@
int x;
int y;
};
+
+std::ostream &operator<<(std::ostream &stream, const tpoint& point);
+
+SDL_Rect create_rect(const tpoint& origin, const tpoint& size);
struct terror
{
@@ -153,13 +157,31 @@
virtual void set_height(const int height) { h_ = height; set_dirty(); }
int get_height() const { return h_; }
-
+ bool dirty() const { return dirty_; }
+
+ //! Sets the best size for the object.
+ virtual void set_best_size(const tpoint& origin)
+ { set_size(create_rect(origin, get_best_size())); }
+
+
+ //! Sets the minumum size for the object.
+// virtual void set_minimum_size();
+
+ //! Sets a predefined size for the object.
+ virtual void set_size(const SDL_Rect rect)
+ {
+ x_ = rect.x;
+ y_ = rect.y;
+ w_ = rect.w;
+ h_ = rect.h;
+ dirty_ = true;
+ }
protected:
virtual void set_dirty(const bool dirty = true) { dirty_ = dirty; }
SDL_Rect get_rect() const
- { return create_rect( x_, y_, w_, h_ ); }
+ { return ::create_rect( x_, y_, w_, h_ ); }
private:
const std::string id_;
@@ -232,7 +254,6 @@
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);
@@ -253,20 +274,69 @@
void remove_child(const unsigned row, const unsigned col);
void removed_child(const std::string& id, const bool find_all = false);
- void layout();
+ //! Inherited
+ tpoint get_best_size();
+
+ //! Inherited
+ void set_best_size(const tpoint& origin);
+
+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.
+ {}
-private:
- struct tchild {
- tchild() :
- flags(0),
- border_size(0),
- widget(0)
- {}
-
- std::string id;
- unsigned flags;
- unsigned border_size;
- twidget* widget;
+ 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.
+ SDL_Rect clip_;
};
public:
class iterator
@@ -280,8 +350,8 @@
iterator operator++() { return iterator(++itor_); }
iterator operator--() { return iterator(--itor_); }
- twidget* operator->() { return itor_->widget; }
- twidget* operator*() { return itor_->widget; }
+ twidget* operator->() { return itor_->widget(); }
+ twidget* operator*() { return itor_->widget(); }
bool operator!=(const iterator& i) const
{ return i.itor_ != this->itor_; }
@@ -439,6 +509,15 @@
// note we should check whether the label fits in the button
tpoint get_best_size() const { return tpoint(default_width_,
default_height_); }
+
+ void set_best_size(const tpoint& origin)
+ {
+ set_x(origin.x);
+ set_y(origin.y);
+ set_width(default_width_);
+ set_height(default_height_);
+ }
+
protected:
private:
@@ -452,7 +531,6 @@
static unsigned default_height_;
static config default_enabled_draw_;
};
-
/**
* A widget has a mouse over which can either popup directly or after a fixed
delay (this is a flag)
Modified: trunk/src/gui/widgets/window.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/window.cpp?rev=24438&r1=24437&r2=24438&view=diff
==============================================================================
--- trunk/src/gui/widgets/window.cpp (original)
+++ trunk/src/gui/widgets/window.cpp Sun Mar 9 13:34:16 2008
@@ -21,6 +21,8 @@
#include "log.hpp"
#include "serialization/parser.hpp"
#include "variable.hpp"
+
+#include <cassert>
#define DBG_GUI LOG_STREAM(debug, widget)
#define LOG_GUI LOG_STREAM(info, widget)
@@ -77,18 +79,14 @@
// for(std::multimap<std::string, twidget *>::iterator itor =
// children_().begin(); itor != children_().end(); ++itor)
{
- layout();
-
+ layout(Xrect);
for(tsizer::iterator itor = begin(); itor != end(); ++itor) {
log_scope2(widget, "Draw child");
- twidget* widget = *itor;
- if(widget) {
- // need to set the clip_rect here or let the widget do
it itself?
- widget->draw(screen);
- }
- }
+ itor->draw(screen);
+ }
+
rect = get_rect();
SDL_BlitSurface(screen, 0, video_.getSurface(), &rect);
update_rect(get_rect());
@@ -124,6 +122,25 @@
update_rect(get_rect());
flip();
}
+}
+
+void twindow::layout(const SDL_Rect position)
+{
+ tpoint best_size = get_best_size();
+
+ if(best_size.x < position.w && best_size.y < position.h) {
+ set_best_size(tpoint(0, 0));
+ return;
+ }
+
+ DBG_GUI << "Failed for best size, try minimum.\n";
+
+ // Implement the code.
+ assert(false);
+
+ // Failed at best size try minumum.
+
+ // Failed at minimum log error and try to do the best possible thing.
}
void twindow::flip()
Modified: trunk/src/gui/widgets/window.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/window.hpp?rev=24438&r1=24437&r2=24438&view=diff
==============================================================================
--- trunk/src/gui/widgets/window.hpp (original)
+++ trunk/src/gui/widgets/window.hpp Sun Mar 9 13:34:16 2008
@@ -61,6 +61,9 @@
// The flip function is the disp_.flip() if ommitted the video_flip()
is used
void show(const bool restore = true, void* flip_function = 0);
+ // layout the window
+ void layout(const SDL_Rect position);
+
enum tstatus{ NEW, SHOWING, REQUEST_CLOSE, CLOSED };
protected:
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits