added support for non flexible (in one direction only) flexible sizers
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18931 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
2abb9d2f17
commit
5d76f46282
@ -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
|
||||
- added wxArray::SetCount()
|
||||
|
||||
wxBase:
|
||||
|
||||
@ -24,6 +25,7 @@ wxBase:
|
||||
|
||||
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
|
||||
|
@ -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}.
|
||||
|
||||
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}\\
|
||||
@ -16,6 +25,7 @@ the \helpref{wxGridSizer}{wxgridsizer}.
|
||||
|
||||
\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}}
|
||||
@ -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.
|
||||
|
||||
\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::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.
|
||||
|
||||
|
@ -339,8 +339,8 @@ public:
|
||||
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; }
|
||||
@ -370,28 +370,67 @@ private:
|
||||
// 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:
|
||||
// ctors/dtor
|
||||
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 );
|
||||
|
||||
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);
|
||||
|
@ -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 )
|
||||
: 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 )
|
||||
: wxGridSizer( cols, vgap, hgap )
|
||||
, m_rowHeights( NULL )
|
||||
, m_colWidths( NULL )
|
||||
: wxGridSizer( cols, vgap, hgap ),
|
||||
m_flexDirection(wxBOTH),
|
||||
m_growMode(wxFLEX_GROWMODE_SPECIFIED)
|
||||
{
|
||||
}
|
||||
|
||||
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()
|
||||
@ -1054,36 +1027,63 @@ void wxFlexGridSizer::RecalcSizes()
|
||||
wxSize minsz( CalcMin() );
|
||||
wxPoint pt( GetPosition() );
|
||||
int delta;
|
||||
size_t idx,num;
|
||||
size_t idx, num;
|
||||
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();
|
||||
|
||||
if ((num > 0) && (sz.y > minsz.y))
|
||||
// what to do with the rows? by default, resize them proportionally
|
||||
if ( (m_flexDirection & wxVERTICAL) ||
|
||||
(m_growMode == wxFLEX_GROWMODE_SPECIFIED) )
|
||||
{
|
||||
delta = (sz.y - minsz.y) / num;
|
||||
for (idx = 0; idx < num; idx++)
|
||||
m_rowHeights[ temp[idx] ] += delta;
|
||||
// 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))
|
||||
{
|
||||
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) )
|
||||
{
|
||||
// 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();
|
||||
|
||||
if ((num > 0) && (sz.x > minsz.x))
|
||||
// the same logic as above but for the columns
|
||||
if ( (m_flexDirection & wxHORIZONTAL) ||
|
||||
(m_growMode == wxFLEX_GROWMODE_SPECIFIED) )
|
||||
{
|
||||
delta = (sz.x - minsz.x) / num;
|
||||
for (idx = 0; idx < num; idx++)
|
||||
m_colWidths[ temp[idx] ] += delta;
|
||||
// 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))
|
||||
{
|
||||
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) )
|
||||
{
|
||||
for ( int col=0; col < ncols; ++col )
|
||||
m_colWidths[ col ] = sz.x / ncols;
|
||||
}
|
||||
|
||||
sz = wxSize( pt.x + sz.x, pt.y + sz.y );
|
||||
@ -1114,11 +1114,12 @@ void wxFlexGridSizer::RecalcSizes()
|
||||
|
||||
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();
|
||||
@ -1137,6 +1138,34 @@ wxSize wxFlexGridSizer::CalcMin()
|
||||
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 ];
|
||||
|
Loading…
Reference in New Issue
Block a user