]> git.saurik.com Git - wxWidgets.git/commitdiff
added support for non flexible (in one direction only) flexible sizers
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 26 Jan 2003 00:04:24 +0000 (00:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 26 Jan 2003 00:04:24 +0000 (00:04 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18931 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/flexsizr.tex
include/wx/sizer.h
src/common/sizer.cpp

index fa5ab9811c2f9099f2f0428382310ec82925383a..ddc9309b7a7e3655f2ad3c90dbcce00fab3f7179 100644 (file)
@@ -17,6 +17,7 @@ All:
 - use true/false throughout the library instead of TRUE/FALSE
 - wxStopWatch::Start() resumes the stop watch if paused, as per the docs
 - added wxDirTraverser::OnOpenError() to customize the error handling
 - use true/false throughout the library instead of TRUE/FALSE
 - wxStopWatch::Start() resumes the stop watch if paused, as per the docs
 - added wxDirTraverser::OnOpenError() to customize the error handling
+- added wxArray::SetCount()
 
 wxBase:
 
 
 wxBase:
 
@@ -24,6 +25,7 @@ wxBase:
 
 All GUI ports:
 
 
 All GUI ports:
 
+- added wxFlexGridSizer::SetFlexibleDirection() (Szczepan Holyszewski)
 - implemented GetEditControl for wxGenericTreeCtrl (Peter Stieber)
 - improved contrib/utils/convertrc parsing (David J. Cooke)
 - fixed handling of URLs and filenames in wxFileSystem
 - implemented GetEditControl for wxGenericTreeCtrl (Peter Stieber)
 - improved contrib/utils/convertrc parsing (David J. Cooke)
 - fixed handling of URLs and filenames in wxFileSystem
index d7456bbc21d9931314e221759e5e75956c77110f..0ce1e99fe4bda4c935ddb8ae167e27b18c53a66c 100644 (file)
@@ -6,6 +6,15 @@ height and all fields in one column having the same width, but all
 rows or all columns are not necessarily the same height or width as in
 the \helpref{wxGridSizer}{wxgridsizer}.
 
 rows or all columns are not necessarily the same height or width as in
 the \helpref{wxGridSizer}{wxgridsizer}.
 
+Since wxWindows 2.5.0, wxFlexGridSizer can also size items equally in one
+direction but unequally ("flexibly") in the other. If the sizer is only
+flexible in one direction (this can be changed using 
+\helpref{SetFlexibleDrection}{wxflexgridsizersetflexibledrection}),
+it needs to be decided how the sizer should grow in the other ("non flexible")
+direction in order to fill the available space. The 
+\helpref{SetNonFlexibleGrowMode}{wxflexgridsizersetnonflexiblegrowmode} method
+serves this purpose.
+
 \wxheading{Derived from}
 
 \helpref{wxGridSizer}{wxgridsizer}\\
 \wxheading{Derived from}
 
 \helpref{wxGridSizer}{wxgridsizer}\\
@@ -16,6 +25,7 @@ the \helpref{wxGridSizer}{wxgridsizer}.
 
 \helpref{wxSizer}{wxsizer}, \helpref{Sizer overview}{sizeroverview}
 
 
 \helpref{wxSizer}{wxsizer}, \helpref{Sizer overview}{sizeroverview}
 
+
 \membersection{wxFlexGridSizer::wxFlexGridSizer}\label{wxflexgridsizerwxflexgridsizer}
 
 \func{}{wxFlexGridSizer}{\param{int }{rows}, \param{int }{cols}, \param{int }{vgap}, \param{int }{hgap}}
 \membersection{wxFlexGridSizer::wxFlexGridSizer}\label{wxflexgridsizerwxflexgridsizer}
 
 \func{}{wxFlexGridSizer}{\param{int }{rows}, \param{int }{cols}, \param{int }{vgap}, \param{int }{hgap}}
@@ -43,15 +53,94 @@ there is extra space available to the sizer.
 Specifies that row idx (starting from zero) should be grown if there
 is extra space available to the sizer.
 
 Specifies that row idx (starting from zero) should be grown if there
 is extra space available to the sizer.
 
+\membersection{wxFlexGridSizer::GetFlexibleDirection}\label{wxflexgridsizergetflexibledrection}
+
+\constfunc{int}{GetFlexibleDirections}{\void}
+
+Returns a wxOrientation value that specifies whether the sizer flexibly
+resizes its columns, rows, or both (default).
+
+\wxheading{Return value}
+
+One of the following values:
+
+\begin{twocollist}
+\twocolitem{wxVERTICAL}{Rows are flexibly sized.}
+\twocolitem{wxHORIZONTAL}{Columns are flexibly sized.}
+\twocolitem{wxBOTH}{Both rows and columns are flexibly sized (this is the default value).}
+\end{twocollist}
+
+\wxheading{See also}
+
+\helpref{SetFlexibleDrection}{wxflexgridsizersetflexibledrection}
+
+
+\membersection{wxFlexGridSizer::GetNonFlexibleGrowMode}\label{wxflexgridsizergetnonflexiblegrowmode}
+
+\constfunc{int}{GetNonFlexibleGrowMode}{\void}
+
+Returns the value that specifies how the sizer grows in the "non flexible"
+direction if there is one.
+
+\wxheading{Return value}
+
+One of the following values:
+
+\begin{twocollist}
+\twocolitem{wxFLEX\_GROWMODE\_NONE}{Sizer doesn't grow in the non flexible direction.}
+\twocolitem{wxFLEX\_GROWMODE\_SPECIFIED}{Sizer honors growable columns/rows set with
+\helpref{AddGrowableCol}{wxflexgridsizeraddgrowablecol} and 
+\helpref{AddGrowableRow}{wxflexgridsizeraddgrowablerow}.
+In this case equal sizing applies to minimum sizes of columns or
+rows (this is the default value).}
+\twocolitem{wxFLEX\_GROWMODE\_ALL}{Sizer equally stretches all columns or rows
+in the non flexible direction, whether they are growable or not in the flexbile
+direction.}
+\end{twocollist}
+
+\wxheading{See also}
+
+\helpref{SetFlexibleDrection}{wxflexgridsizersetflexibledrection}, 
+\helpref{SetNonFlexibleGrowMode}{wxflexgridsizersetnonflexiblegrowmode}
+
+
 \membersection{wxFlexGridSizer::RemoveGrowableCol}\label{wxflexgridsizerremovegrowablecol}
 
 \func{void}{RemoveGrowableCol}{\param{size\_t }{idx}}
 
 Specifies that column idx is no longer growable.
 
 \membersection{wxFlexGridSizer::RemoveGrowableCol}\label{wxflexgridsizerremovegrowablecol}
 
 \func{void}{RemoveGrowableCol}{\param{size\_t }{idx}}
 
 Specifies that column idx is no longer growable.
 
+
 \membersection{wxFlexGridSizer::RemoveGrowableRow}\label{wxflexgridsizerremovegrowablerow}
 
 \func{void}{RemoveGrowableRow}{\param{size\_t }{idx}}
 
 Specifies that row idx is no longer growable.
 
 \membersection{wxFlexGridSizer::RemoveGrowableRow}\label{wxflexgridsizerremovegrowablerow}
 
 \func{void}{RemoveGrowableRow}{\param{size\_t }{idx}}
 
 Specifies that row idx is no longer growable.
 
+
+\membersection{wxFlexGridSizer::SetFlexibleDirection}{wxflexgridsizersetflexibledrection}
+
+\func{void}{SetFlexibleDirections}{\param{int }{direction}}
+
+Specifies whether the sizer should flexibly resize its columns, rows, or
+both. Argument {\t direction} can be {\tt wxVERTICAL}, {\tt wxHORIZONTAL} 
+or {\tt wxBOTH} (which is the default value). Any other value is ignored. See
+\helpref{GetFlexibleDirection()}{wxflexgridsizergetflexibledrection} for the
+explanation of these values.
+
+Note that this method does not trigger relayout.
+
+
+\membersection{wxFlexGridSizer::SetNonFlexibleGrowMode}{wxflexgridsizersetnonflexiblegrowmode}
+
+\func{void}{SetNonFlexibleGrowMode}{\param{int }{mode}}
+
+Specifies how the sizer should grow in the non flexible direction if
+there is one (so
+\helpref{SetFlexibleDirections()}{wxflexgridsizersetflexibledrection} must have
+been called previously). Argument {\it mode} can be one of those documented in
+\helpref{GetNonFlexibleGrowMode}{wxflexgridsizergetnonflexiblegrowmode}, please
+see there for their explanation.
+
+Note that this method does not trigger relayout.
+
index 913d9131a2b651f9872d921281557012594eb32a..b5f06659551fd8c880b0037d09f3644f3e747895 100644 (file)
@@ -339,8 +339,8 @@ public:
     wxGridSizer( int rows, int cols, int vgap, int hgap );
     wxGridSizer( int cols, int vgap = 0, int hgap = 0 );
 
     wxGridSizer( int rows, int cols, int vgap, int hgap );
     wxGridSizer( int cols, int vgap = 0, int hgap = 0 );
 
-    void RecalcSizes();
-    wxSize CalcMin();
+    virtual void RecalcSizes();
+    virtual wxSize CalcMin();
 
     void SetCols( int cols )    { m_cols = cols; }
     void SetRows( int rows )    { m_rows = rows; }
 
     void SetCols( int cols )    { m_cols = cols; }
     void SetRows( int rows )    { m_rows = rows; }
@@ -370,28 +370,67 @@ private:
 // wxFlexGridSizer
 //---------------------------------------------------------------------------
 
 // wxFlexGridSizer
 //---------------------------------------------------------------------------
 
+// the bevaiour for resizing wxFlexGridSizer cells in the "non-flexible"
+// direction
+enum wxFlexSizerGrowMode
+{
+    // don't resize the cells in non-flexible direction at all
+    wxFLEX_GROWMODE_NONE,
+
+    // uniformly resize only the specified ones (default)
+    wxFLEX_GROWMODE_SPECIFIED,
+
+    // uniformly resize all cells
+    wxFLEX_GROWMODE_ALL
+};
+
 class WXDLLEXPORT wxFlexGridSizer: public wxGridSizer
 {
 public:
 class WXDLLEXPORT wxFlexGridSizer: public wxGridSizer
 {
 public:
+    // ctors/dtor
     wxFlexGridSizer( int rows, int cols, int vgap, int hgap );
     wxFlexGridSizer( int cols, int vgap = 0, int hgap = 0 );
     wxFlexGridSizer( int rows, int cols, int vgap, int hgap );
     wxFlexGridSizer( int cols, int vgap = 0, int hgap = 0 );
-    ~wxFlexGridSizer();
+    virtual ~wxFlexGridSizer();
 
 
-    void RecalcSizes();
-    wxSize CalcMin();
 
 
+    // set the rows/columns which will grow (the others will remain of the
+    // constant initial size)
     void AddGrowableRow( size_t idx );
     void RemoveGrowableRow( size_t idx );
     void AddGrowableCol( size_t idx );
     void RemoveGrowableCol( size_t idx );
 
     void AddGrowableRow( size_t idx );
     void RemoveGrowableRow( size_t idx );
     void AddGrowableCol( size_t idx );
     void RemoveGrowableCol( size_t idx );
 
-protected:
-    int         *m_rowHeights;
-    int         *m_colWidths;
-    wxArrayInt  m_growableRows;
-    wxArrayInt  m_growableCols;
 
 
-    void CreateArrays();
+    // the sizer cells may grow in both directions, not grow at all or only
+    // grow in one direction but not the other
+
+    // the direction may be wxVERTICAL, wxHORIZONTAL or wxBOTH (default)
+    void SetFlexibleDirection(int direction) { m_flexDirection = direction; }
+    int GetFlexibleDirection() const { return m_flexDirection; }
+
+    // note that the grow mode only applies to the direction which is not
+    // flexible
+    void SetNonFlexibleGrowMode(wxFlexSizerGrowMode mode) { m_growMode = mode; }
+    wxFlexSizerGrowMode GetNonFlexibleGrowMode() const { return m_growMode; }
+
+
+    // implementation
+    virtual void RecalcSizes();
+    virtual wxSize CalcMin();
+
+protected:
+    // the heights/widths of all rows/columns
+    wxArrayInt  m_rowHeights,
+                m_colWidths;
+
+    // indices of the growable columns and rows
+    wxArrayInt  m_growableRows,
+                m_growableCols;
+
+    // parameters describing whether the growable cells should be resized in
+    // both directions or only one
+    int m_flexDirection;
+    wxFlexSizerGrowMode m_growMode;
 
 private:
     DECLARE_CLASS(wxFlexGridSizer);
 
 private:
     DECLARE_CLASS(wxFlexGridSizer);
index 1d7ed91c2c0b79e3a1c9f45616680f409613dc61..a0ee65773c2cb0c7c69578e2a1e10544d6d08cb2 100644 (file)
@@ -1000,48 +1000,21 @@ void wxGridSizer::SetItemBounds( wxSizerItem *item, int x, int y, int w, int h )
 //---------------------------------------------------------------------------
 
 wxFlexGridSizer::wxFlexGridSizer( int rows, int cols, int vgap, int hgap )
 //---------------------------------------------------------------------------
 
 wxFlexGridSizer::wxFlexGridSizer( int rows, int cols, int vgap, int hgap )
-   : wxGridSizer( rows, cols, vgap, hgap )
-   , m_rowHeights( NULL )
-   , m_colWidths( NULL )
+               : wxGridSizer( rows, cols, vgap, hgap ),
+                 m_flexDirection(wxBOTH),
+                 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
 {
 }
 
 wxFlexGridSizer::wxFlexGridSizer( int cols, int vgap, int hgap )
 {
 }
 
 wxFlexGridSizer::wxFlexGridSizer( int cols, int vgap, int hgap )
-   : wxGridSizer( cols, vgap, hgap )
-   , m_rowHeights( NULL )
-   , m_colWidths( NULL )
+               : wxGridSizer( cols, vgap, hgap ),
+                 m_flexDirection(wxBOTH),
+                 m_growMode(wxFLEX_GROWMODE_SPECIFIED)
 {
 }
 
 wxFlexGridSizer::~wxFlexGridSizer()
 {
 {
 }
 
 wxFlexGridSizer::~wxFlexGridSizer()
 {
-    if (m_rowHeights)
-        delete[] m_rowHeights;
-    if (m_colWidths)
-        delete[] m_colWidths;
-}
-
-void wxFlexGridSizer::CreateArrays()
-{
-    if (m_rowHeights)
-        delete[] m_rowHeights;
-    if (m_colWidths)
-        delete[] m_colWidths;
-
-    int nitems, nrows, ncols;
-    if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
-    {
-        m_rowHeights =
-        m_colWidths = NULL;
-    }
-
-    m_rowHeights = new int[nrows];
-    m_colWidths = new int[ncols];
-
-    for (int col = 0; col < ncols; col++)
-        m_colWidths[ col ] = 0;
-    for (int row = 0; row < nrows; row++)
-        m_rowHeights[ row ] = 0;
 }
 
 void wxFlexGridSizer::RecalcSizes()
 }
 
 void wxFlexGridSizer::RecalcSizes()
@@ -1054,36 +1027,63 @@ void wxFlexGridSizer::RecalcSizes()
     wxSize minsz( CalcMin() );
     wxPoint pt( GetPosition() );
     int    delta;
     wxSize minsz( CalcMin() );
     wxPoint pt( GetPosition() );
     int    delta;
-    size_t idx,num;
+    size_t idx, num;
     wxArrayInt temp;
 
     wxArrayInt temp;
 
-    // Transfer only those rows into temp which exist in the sizer
-    // ignoring the superflouus ones. This prevents a segfault when
-    // calling AddGrowableRow( 3 ) if the sizer only has 2 rows.
-    for (idx = 0; idx < m_growableRows.GetCount(); idx++)
-        if (m_growableRows[idx] < nrows)
-            temp.Add( m_growableRows[idx] );
-    num = temp.GetCount();
+    // what to do with the rows? by default, resize them proportionally
+    if ( (m_flexDirection & wxVERTICAL) ||
+            (m_growMode == wxFLEX_GROWMODE_SPECIFIED) )
+    {
+        // Transfer only those rows into temp which exist in the sizer
+        // ignoring the superfluous ones. This prevents a segfault when
+        // calling AddGrowableRow( 3 ) if the sizer only has 2 rows.
+        for (idx = 0; idx < m_growableRows.GetCount(); idx++)
+        {
+            if (m_growableRows[idx] < nrows)
+                temp.Add( m_growableRows[idx] );
+        }
+
+        num = temp.GetCount();
 
 
-    if ((num > 0) && (sz.y > minsz.y))
+        if ((num > 0) && (sz.y > minsz.y))
+        {
+            delta = (sz.y - minsz.y) / num;
+            for (idx = 0; idx < num; idx++)
+                m_rowHeights[ temp[idx] ] += delta;
+        }
+        temp.Empty();
+    }
+    else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.y > minsz.y) )
     {
     {
-        delta = (sz.y - minsz.y) / num;
-        for (idx = 0; idx < num; idx++)
-            m_rowHeights[ temp[idx] ] += delta;
+        // rounding problem?
+        for ( int row = 0; row < nrows; ++row )
+            m_rowHeights[ row ] = sz.y / nrows;
     }
 
     }
 
-    temp.Empty();
-    // See above
-    for (idx = 0; idx < m_growableCols.GetCount(); idx++)
-        if (m_growableCols[idx] < ncols)
-            temp.Add( m_growableCols[idx] );
-    num = temp.GetCount();
+    // the same logic as above but for the columns
+    if ( (m_flexDirection & wxHORIZONTAL) ||
+            (m_growMode == wxFLEX_GROWMODE_SPECIFIED) )
+    {
+        // See above
+        for (idx = 0; idx < m_growableCols.GetCount(); idx++)
+        {
+            if (m_growableCols[idx] < ncols)
+                temp.Add( m_growableCols[idx] );
+        }
+
+        num = temp.GetCount();
 
 
-    if ((num > 0) && (sz.x > minsz.x))
+        if ((num > 0) && (sz.x > minsz.x))
+        {
+            delta = (sz.x - minsz.x) / num;
+            for (idx = 0; idx < num; idx++)
+                m_colWidths[ temp[idx] ] += delta;
+        }
+    }
+    else if ( (m_growMode == wxFLEX_GROWMODE_ALL) && (sz.x > minsz.x) )
     {
     {
-        delta = (sz.x - minsz.x) / num;
-        for (idx = 0; idx < num; idx++)
-            m_colWidths[ temp[idx] ] += delta;
+        for ( int col=0; col < ncols; ++col )
+            m_colWidths[ col ] = sz.x / ncols;
     }
 
     sz = wxSize( pt.x + sz.x, pt.y + sz.y );
     }
 
     sz = wxSize( pt.x + sz.x, pt.y + sz.y );
@@ -1114,11 +1114,12 @@ void wxFlexGridSizer::RecalcSizes()
 
 wxSize wxFlexGridSizer::CalcMin()
 {
 
 wxSize wxFlexGridSizer::CalcMin()
 {
-    int nitems, nrows, ncols;
-    if ( (nitems = CalcRowsCols(nrows, ncols)) == 0 )
-        return wxSize(10,10);
+    int nrows, ncols;
+    if ( !CalcRowsCols(nrows, ncols) )
+        return wxSize(10, 10);
 
 
-    CreateArrays();
+    m_rowHeights.SetCount(nrows);
+    m_colWidths.SetCount(ncols);
 
     int                      i = 0;
     wxSizerItemList::Node   *node = m_children.GetFirst();
 
     int                      i = 0;
     wxSizerItemList::Node   *node = m_children.GetFirst();
@@ -1137,6 +1138,34 @@ wxSize wxFlexGridSizer::CalcMin()
         i++;
     }
 
         i++;
     }
 
+    // the logic above works when we resize flexibly in both directions but
+    // maybe this is not the case
+    if ( m_flexDirection != wxBOTH )
+    {
+        // select the array corresponding to the direction in which we do *not*
+        // resize flexibly
+        wxArrayInt& array = m_flexDirection == wxVERTICAL ? m_colWidths
+                                                          : m_rowHeights;
+
+        const int count = array.GetCount();
+
+        // find the largest value in this array
+        int n,
+            largest = 0;
+        for ( n = 0; n < count; ++n )
+        {
+            if ( array[n] > largest )
+                largest = array[n];
+        }
+
+        // and now fill it with the largest value
+        for ( n = 0; n < count; ++n )
+        {
+            array[n] = largest;
+        }
+    }
+
+
     int width = 0;
     for (int col = 0; col < ncols; col++)
         width += m_colWidths[ col ];
     int width = 0;
     for (int col = 0; col < ncols; col++)
         width += m_colWidths[ col ];