mail[Wesnoth-commits] r24438 - in /trunk/src/gui/widgets: widget.cpp widget.hpp window.cpp window.hpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by koraq on March 09, 2008 - 13:34:
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:




Related Messages


Powered by MHonArc, Updated Sun Mar 09 14:01:39 2008