gui/widgets/grid.hpp

Go to the documentation of this file.
00001 /* $Id: grid.hpp 54266 2012-05-20 19:19:32Z mordante $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #ifndef GUI_WIDGETS_GRID_HPP_INCLUDED
00017 #define GUI_WIDGETS_GRID_HPP_INCLUDED
00018 
00019 #include "gui/widgets/widget.hpp"
00020 
00021 namespace gui2 {
00022 
00023 /**
00024  * Base container class.
00025  *
00026  * This class holds a number of widgets and their wanted layout parameters. It
00027  * also layouts the items in the grid and hanldes their drawing.
00028  */
00029 class tgrid : public virtual twidget
00030 {
00031     friend class tdebug_layout_graph;
00032     friend struct tgrid_implementation;
00033 
00034 public:
00035 
00036     explicit tgrid(const unsigned rows = 0, const unsigned cols = 0);
00037 
00038     virtual ~tgrid();
00039 
00040     /***** ***** ***** ***** LAYOUT FLAGS ***** ***** ***** *****/
00041     static const unsigned VERTICAL_SHIFT                 = 0;
00042     static const unsigned VERTICAL_GROW_SEND_TO_CLIENT   = 1 << VERTICAL_SHIFT;
00043     static const unsigned VERTICAL_ALIGN_TOP             = 2 << VERTICAL_SHIFT;
00044     static const unsigned VERTICAL_ALIGN_CENTER          = 3 << VERTICAL_SHIFT;
00045     static const unsigned VERTICAL_ALIGN_BOTTOM          = 4 << VERTICAL_SHIFT;
00046     static const unsigned VERTICAL_MASK                  = 7 << VERTICAL_SHIFT;
00047 
00048     static const unsigned HORIZONTAL_SHIFT               = 3;
00049     static const unsigned HORIZONTAL_GROW_SEND_TO_CLIENT = 1 << HORIZONTAL_SHIFT;
00050     static const unsigned HORIZONTAL_ALIGN_LEFT          = 2 << HORIZONTAL_SHIFT;
00051     static const unsigned HORIZONTAL_ALIGN_CENTER        = 3 << HORIZONTAL_SHIFT;
00052     static const unsigned HORIZONTAL_ALIGN_RIGHT         = 4 << HORIZONTAL_SHIFT;
00053     static const unsigned HORIZONTAL_MASK                = 7 << HORIZONTAL_SHIFT;
00054 
00055     static const unsigned BORDER_TOP                     = 1 << 6;
00056     static const unsigned BORDER_BOTTOM                  = 1 << 7;
00057     static const unsigned BORDER_LEFT                    = 1 << 8;
00058     static const unsigned BORDER_RIGHT                   = 1 << 9;
00059     static const unsigned BORDER_ALL                     =
00060         BORDER_TOP | BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT;
00061 
00062     /***** ***** ***** ***** ROW COLUMN MANIPULATION ***** ***** ***** *****/
00063 
00064     /**
00065      * Addes a row to end of the grid.
00066      *
00067      * @param count               Number of rows to add, should be > 0.
00068      *
00069      * @returns                   The row number of the first row added.
00070      */
00071     unsigned add_row(const unsigned count = 1);
00072 
00073     /**
00074      * Sets the grow factor for a row.
00075      *
00076      * @todo refer to a page with the layout manipulation info.
00077      *
00078      * @param row                 The row to modify.
00079      * @param factor              The grow factor.
00080      */
00081     void set_row_grow_factor(const unsigned row, const unsigned factor)
00082     {
00083         assert(row < row_grow_factor_.size());
00084         row_grow_factor_[row] = factor;
00085         set_dirty();
00086     }
00087 
00088     /**
00089      * Sets the grow factor for a column.
00090      *
00091      * @todo refer to a page with the layout manipulation info.
00092      *
00093      * @param column              The column to modify.
00094      * @param factor              The grow factor.
00095      */
00096     void set_column_grow_factor(const unsigned column, const unsigned factor)
00097     {
00098         assert(column< col_grow_factor_.size());
00099         col_grow_factor_[column] = factor;
00100         set_dirty();
00101     }
00102 
00103     /***** ***** ***** ***** CHILD MANIPULATION ***** ***** ***** *****/
00104 
00105     /**
00106      * Sets a child in the grid.
00107      *
00108      * When the child is added to the grid the grid 'owns' the widget.
00109      * The widget is put in a cell, and every cell can only contain 1 widget if
00110      * the wanted cell already contains a widget, that widget is freed and
00111      * removed.
00112      *
00113      * @param widget              The widget to put in the grid.
00114      * @param row                 The row of the cell.
00115      * @param col                 The columnof the cell.
00116      * @param flags               The flags for the widget in the cell.
00117      * @param border_size         The size of the border for the cell, how the
00118      *                            border is applied depends on the flags.
00119      */
00120     void set_child(twidget* widget, const unsigned row,
00121         const unsigned col, const unsigned flags, const unsigned border_size);
00122 
00123     /**
00124      * Exchangs a child in the grid.
00125      *
00126      * It replaced the child with a certain id with the new widget but doesn't
00127      * touch the other settings of the child.
00128      *
00129      * @param id                  The id of the widget to free.
00130      * @param widget              The widget to put in the grid.
00131      * @param recurse             Do we want to decent into the child grids.
00132      * @param new_parent          The new parent for the swapped out widget.
00133      *
00134      * returns                    The widget which got removed (the parent of
00135      *                            the widget is cleared). If no widget found
00136      *                            and thus not replace NULL will returned.
00137      */
00138     twidget* swap_child(
00139         const std::string& id, twidget* widget, const bool recurse,
00140         twidget* new_parent = NULL);
00141 
00142     /**
00143      * Removes and frees a widget in a cell.
00144      *
00145      * @param row                 The row of the cell.
00146      * @param col                 The columnof the cell.
00147      */
00148     void remove_child(const unsigned row, const unsigned col);
00149 
00150     /**
00151      * Removes and frees a widget in a cell by it's id.
00152      *
00153      * @param id                  The id of the widget to free.
00154      * @param find_all            If true if removes all items with the id,
00155      *                            otherwise it stops after removing the first
00156      *                            item (or once all children have been tested).
00157      */
00158     void remove_child(const std::string& id, const bool find_all = false);
00159 
00160     /**
00161      * Activates all children.
00162      *
00163      * If a child inherits from tcontrol or is a tgrid it will call
00164      * set_active() for the child otherwise it ignores the widget.
00165      *
00166      * @param active              Parameter for set_active.
00167      */
00168     void set_active(const bool active);
00169 
00170 
00171     /** Returns the widget in the selected cell. */
00172     const twidget* widget(const unsigned row, const unsigned col) const
00173         { return child(row, col).widget(); }
00174 
00175     /** Returns the widget in the selected cell. */
00176     twidget* widget(const unsigned row, const unsigned col)
00177         { return child(row, col).widget(); }
00178 
00179     /***** ***** ***** ***** layout functions ***** ***** ***** *****/
00180 
00181     /** Inherited from twidget. */
00182     void layout_init(const bool full_initialization);
00183 
00184     /**
00185      * Tries to reduce the width of a container.
00186      *
00187      * @see @ref layout_algorihm for more information.
00188      *
00189      * @param maximum_width       The wanted maximum width.
00190      */
00191     void reduce_width(const unsigned maximum_width);
00192 
00193     /** Inherited from twidget. */
00194     void request_reduce_width(const unsigned maximum_width);
00195 
00196     /** Inherited from twidget. */
00197     void demand_reduce_width(const unsigned maximum_width);
00198 
00199     /**
00200      * Tries to reduce the height of a container.
00201      *
00202      * @see @ref layout_algorihm for more information.
00203      *
00204      * @param maximum_height      The wanted maximum height.
00205      */
00206     void reduce_height(const unsigned maximum_height);
00207 
00208     /** Inherited from twidget. */
00209     void request_reduce_height(const unsigned maximum_height);
00210 
00211     /** Inherited from twidget. */
00212     void demand_reduce_height(const unsigned maximum_height);
00213 
00214     /**
00215      * Recalculates the best size.
00216      *
00217      * This is used for scrollbar containers when they try to update their
00218      * contents size before falling back to the 'global' invalidate_layout.
00219      *
00220      * @returns                   The newly calculated size.
00221      */
00222     tpoint recalculate_best_size();
00223 
00224 private:
00225 
00226     /** Inherited from twidget. */
00227     tpoint calculate_best_size() const;
00228 public:
00229 
00230     /** Inherited from twidget. */
00231     bool can_wrap() const;
00232 
00233 public:
00234     /** Inherited from twidget. */
00235     void place(const tpoint& origin, const tpoint& size);
00236 
00237     /***** ***** ***** ***** Inherited ***** ***** ***** *****/
00238 
00239     /** Inherited from twidget. */
00240     void set_origin(const tpoint& origin);
00241 
00242     /** Inherited from twidget. */
00243     void set_visible_area(const SDL_Rect& area);
00244 
00245     /** Inherited from twidget. */
00246     void layout_children();
00247 
00248     /** Inherited from twidget. */
00249     void child_populate_dirty_list(twindow& caller,
00250             const std::vector<twidget*>& call_stack);
00251 
00252     /** Inherited from twidget. */
00253     twidget* find_at(const tpoint& coordinate, const bool must_be_active);
00254 
00255     /** Inherited from twidget. */
00256     const twidget* find_at(const tpoint& coordinate,
00257             const bool must_be_active) const;
00258 
00259     /** Inherited from twidget.*/
00260     twidget* find(const std::string& id, const bool must_be_active);
00261 
00262     /** Inherited from twidget.*/
00263     const twidget* find(const std::string& id,
00264             const bool must_be_active) const;
00265 
00266     /** Inherited from twidget.*/
00267     bool has_widget(const twidget* widget) const;
00268 
00269     /** Inherited from tcontrol. */
00270     bool disable_click_dismiss() const;
00271 
00272     /** Inherited from twidget. */
00273     virtual iterator::twalker_* create_walker();
00274 
00275     /***** ***** ***** setters / getters for members ***** ****** *****/
00276 
00277     void set_rows(const unsigned rows);
00278     unsigned int get_rows() const { return rows_; }
00279 
00280     void set_cols(const unsigned cols);
00281     unsigned int get_cols() const { return cols_; }
00282 
00283     /**
00284      * Wrapper to set_rows and set_cols.
00285      *
00286      * @param rows                Parameter to call set_rows with.
00287      * @param cols                Parameter to call set_cols with.
00288      */
00289     void set_rows_cols(const unsigned rows, const unsigned cols);
00290 
00291 private:
00292     /** Child item of the grid. */
00293     class tchild
00294     {
00295         friend struct tgrid_implementation;
00296     public:
00297         tchild() :
00298             flags_(0),
00299             border_size_(0),
00300             widget_(NULL)
00301 
00302             // Fixme make a class wo we can store some properties in the cache
00303             // regarding size etc.
00304             {}
00305 
00306         /** Returns the best size for the cell. */
00307         tpoint get_best_size() const;
00308 
00309         /**
00310          * Places the widget in the cell.
00311          *
00312          * @param origin          The origin (x, y) for the widget.
00313          * @param size            The size for the widget.
00314          */
00315         void place(tpoint origin, tpoint size);
00316 
00317         /** Forwards layout_init() to the cell. */
00318         void layout_init(const bool full_initialization);
00319 
00320         /** Returns the can_wrap for the cell. */
00321         bool can_wrap() const
00322             { return widget_ ? widget_->can_wrap() : false; }
00323 
00324         /** Returns the id of the widget/ */
00325         const std::string& id() const;
00326 
00327         unsigned get_flags() const { return flags_; }
00328         void set_flags(const unsigned flags) { flags_ = flags; }
00329 
00330         unsigned get_border_size() const { return border_size_; }
00331         void set_border_size(const unsigned border_size)
00332             {  border_size_ = border_size; }
00333 
00334         const twidget* widget() const { return widget_; }
00335         twidget* widget() { return widget_; }
00336 
00337         void set_widget(twidget* widget) { widget_ = widget; }
00338 
00339     private:
00340         /** The flags for the border and cell setup. */
00341         unsigned flags_;
00342 
00343         /**
00344          * The size of the border, the actual configuration of the border
00345          * is determined by the flags.
00346          */
00347         unsigned border_size_;
00348 
00349         /**
00350          * Pointer to the widget.
00351          *
00352          * Once the widget is assigned to the grid we own the widget and are
00353          * responsible for it's destruction.
00354          */
00355         twidget* widget_;
00356 
00357         /** Returns the space needed for the border. */
00358         tpoint border_space() const;
00359 
00360     }; // class tchild
00361 
00362 public:
00363     /** Iterator for the tchild items. */
00364     class iterator
00365     {
00366 
00367     public:
00368 
00369         iterator(std::vector<tchild>::iterator itor) :
00370             itor_(itor)
00371             {}
00372 
00373         iterator operator++() { return iterator(++itor_); }
00374         iterator operator--() { return iterator(--itor_); }
00375         twidget* operator->() { return itor_->widget(); }
00376         twidget* operator*() { return itor_->widget(); }
00377 
00378         bool operator==(const iterator& i) const
00379             { return i.itor_ == this->itor_; }
00380 
00381         bool operator!=(const iterator& i) const
00382             { return i.itor_ != this->itor_; }
00383 
00384     private:
00385         std::vector<tchild>::iterator itor_;
00386 
00387     };
00388 
00389     iterator begin() { return iterator(children_.begin()); }
00390     iterator end() { return iterator(children_.end()); }
00391 
00392 private:
00393     /** The number of grid rows. */
00394     unsigned rows_;
00395 
00396     /** The number of grid columns. */
00397     unsigned cols_;
00398 
00399     /***** ***** ***** ***** size caching ***** ***** ***** *****/
00400 
00401     /** The row heights in the grid. */
00402     mutable std::vector<unsigned> row_height_;
00403 
00404     /** The column widths in the grid. */
00405     mutable std::vector<unsigned> col_width_;
00406 
00407     /** The grow factor for all rows. */
00408     std::vector<unsigned> row_grow_factor_;
00409 
00410     /** The grow factor for all columns. */
00411     std::vector<unsigned> col_grow_factor_;
00412 
00413     /**
00414      * The child items.
00415      *
00416      * All children are stored in a 1D vector and the formula to access a cell
00417      * is: rows_ * col + row. All other vectors use the same access formula.
00418      */
00419     std::vector<tchild> children_;
00420     const tchild& child(const unsigned row, const unsigned col) const
00421         { return children_[rows_ * col + row]; }
00422     tchild& child(const unsigned row, const unsigned col)
00423         { return children_[rows_ * col + row]; }
00424 
00425     /** Layouts the children in the grid. */
00426     void layout(const tpoint& origin);
00427 
00428     /** Inherited from twidget. */
00429     void impl_draw_children(surface& frame_buffer);
00430     void impl_draw_children(surface& frame_buffer, int x_offset, int y_offset);
00431 
00432 };
00433 
00434 /**
00435  * Sets the single child in a grid.
00436  *
00437  * The function initializes the grid to 1 x 1 and adds the widget with the grow
00438  * to client flags.
00439  *
00440  * @param grid                    The grid to add the child to.
00441  * @param widget                  The widget to add as child to the grid.
00442  */
00443 void set_single_child(tgrid& grid, twidget* widget);
00444 
00445 } // namespace gui2
00446 
00447 #endif
00448 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:59 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs