Classes | Public Member Functions | Protected Member Functions

QwtDynGridLayout Class Reference

The QwtDynGridLayout class lays out widgets in a grid, adjusting the number of columns and rows to the current size. More...

#include <qwt_dyngrid_layout.h>

Collaboration diagram for QwtDynGridLayout:
Collaboration graph
[legend]

List of all members.

Classes

class  PrivateData

Public Member Functions

 QwtDynGridLayout (QWidget *, int margin=0, int space=-1)
 QwtDynGridLayout (QLayout *, int space=-1)
 QwtDynGridLayout (int space=-1)
virtual ~QwtDynGridLayout ()
 Destructor.
virtual void invalidate ()
 Invalidate all internal caches.
void setMaxCols (uint maxCols)
uint maxCols () const
uint numRows () const
uint numCols () const
virtual void addItem (QLayoutItem *)
 Adds item to the next free position.
virtual QLayoutIterator iterator ()
void setExpanding (QSizePolicy::ExpandData)
virtual QSizePolicy::ExpandData expanding () const
QValueList< QRect > layoutItems (const QRect &, uint numCols) const
virtual int maxItemWidth () const
virtual void setGeometry (const QRect &rect)
virtual bool hasHeightForWidth () const
virtual int heightForWidth (int) const
virtual QSize sizeHint () const
virtual bool isEmpty () const
uint itemCount () const
virtual uint columnsForWidth (int width) const

Protected Member Functions

void layoutGrid (uint numCols, QMemArray< int > &rowHeight, QMemArray< int > &colWidth) const
void stretchGrid (const QRect &rect, uint numCols, QMemArray< int > &rowHeight, QMemArray< int > &colWidth) const

Detailed Description

The QwtDynGridLayout class lays out widgets in a grid, adjusting the number of columns and rows to the current size.

QwtDynGridLayout takes the space it gets, divides it up into rows and columns, and puts each of the widgets it manages into the correct cell(s). It lays out as many number of columns as possible (limited by maxCols()).

Definition at line 32 of file qwt_dyngrid_layout.h.


Constructor & Destructor Documentation

QwtDynGridLayout::QwtDynGridLayout ( QWidget *  parent,
int  margin = 0,
int  spacing = -1 
) [explicit]
Parameters:
parentParent widget
marginMargin
spacingSpacing

Definition at line 107 of file qwt_dyngrid_layout.cpp.

                                :
    QLayout(parent)
{
    init();

    setSpacing(spacing);
    setMargin(margin);
}
QwtDynGridLayout::QwtDynGridLayout ( QLayout *  parent,
int  spacing = -1 
) [explicit]
Parameters:
parentParent widget
spacingSpacing

Definition at line 122 of file qwt_dyngrid_layout.cpp.

                                                              :
    QLayout(parent, spacing)
{
    init();
}
QwtDynGridLayout::QwtDynGridLayout ( int  spacing = -1 ) [explicit]
Parameters:
spacingSpacing

Definition at line 133 of file qwt_dyngrid_layout.cpp.

{
    init();
    setSpacing(spacing);
}
QwtDynGridLayout::~QwtDynGridLayout (  ) [virtual]

Destructor.

Definition at line 158 of file qwt_dyngrid_layout.cpp.

{
#if QT_VERSION < 0x040000
    deleteAllItems(); 
#endif

    delete d_data;
}

Member Function Documentation

void QwtDynGridLayout::addItem ( QLayoutItem *  item ) [virtual]

Adds item to the next free position.

Definition at line 213 of file qwt_dyngrid_layout.cpp.

References invalidate(), and QwtDynGridLayout::PrivateData::itemList.

{
    d_data->itemList.append(item);
    invalidate();
}
uint QwtDynGridLayout::columnsForWidth ( int  width ) const [virtual]

Calculate the number of columns for a given width. It tries to use as many columns as possible (limited by maxCols())

Parameters:
widthAvailable width for all columns
See also:
maxCols(), setMaxCols()

Definition at line 368 of file qwt_dyngrid_layout.cpp.

References isEmpty(), itemCount(), QwtDynGridLayout::PrivateData::maxCols, maxCols(), and numCols().

Referenced by heightForWidth(), QwtPlot::printLegend(), and setGeometry().

{
    if ( isEmpty() )
        return 0;

    const int maxCols = (d_data->maxCols > 0) ? d_data->maxCols : itemCount();
    if ( maxRowWidth(maxCols) <= width )
        return maxCols;

    for (int numCols = 2; numCols <= maxCols; numCols++ )
    {
        const int rowWidth = maxRowWidth(numCols);
        if ( rowWidth > width )
            return numCols - 1;
    }

    return 1; // At least 1 column
}
QSizePolicy::ExpandData QwtDynGridLayout::expanding (  ) const [virtual]

Definition at line 253 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::expanding.

Referenced by setExpanding(), and stretchGrid().

{
    return d_data->expanding;
}
bool QwtDynGridLayout::hasHeightForWidth (  ) const [virtual]
Returns:
true: QwtDynGridLayout implements heightForWidth.
See also:
heightForWidth()

Definition at line 562 of file qwt_dyngrid_layout.cpp.

{
    return true;
}
int QwtDynGridLayout::heightForWidth ( int  width ) const [virtual]
Returns:
The preferred height for this layout, given the width w.
See also:
hasHeightForWidth()

Definition at line 571 of file qwt_dyngrid_layout.cpp.

References columnsForWidth(), int(), isEmpty(), itemCount(), layoutGrid(), numCols(), and numRows().

Referenced by QwtLegend::layoutContents().

{
    if ( isEmpty() )
        return 0;

    const uint numCols = columnsForWidth(width);
    uint numRows = itemCount() / numCols;
    if ( itemCount() % numCols )
        numRows++;

    QwtArray<int> rowHeight(numRows);
    QwtArray<int> colWidth(numCols);

    layoutGrid(numCols, rowHeight, colWidth);

    int h = 2 * margin() + (numRows - 1) * spacing();
    for ( int row = 0; row < (int)numRows; row++ )
        h += rowHeight[row];

    return h;
}
void QwtDynGridLayout::invalidate (  ) [virtual]

Invalidate all internal caches.

Definition at line 168 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::isDirty.

Referenced by addItem().

{
    d_data->isDirty = true;
    QLayout::invalidate();
}
bool QwtDynGridLayout::isEmpty (  ) const [virtual]
Returns:
true if this layout is empty.

Definition at line 223 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::itemList.

Referenced by columnsForWidth(), heightForWidth(), maxItemWidth(), setGeometry(), sizeHint(), and stretchGrid().

{
    return d_data->itemList.isEmpty();
}
uint QwtDynGridLayout::itemCount (  ) const
Returns:
number of layout items

Definition at line 232 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::itemList.

Referenced by columnsForWidth(), heightForWidth(), setGeometry(), sizeHint(), and stretchGrid().

{
    return d_data->itemList.count();
}
QLayoutIterator QwtDynGridLayout::iterator (  ) [virtual]
Returns:
An iterator over the children of this layout.

Definition at line 242 of file qwt_dyngrid_layout.cpp.

Referenced by QwtPlot::printLegend().

{       
    return QLayoutIterator( 
        new QwtDynGridLayout::PrivateData::LayoutIterator(d_data) );
}
void QwtDynGridLayout::layoutGrid ( uint  numCols,
QMemArray< int > &  rowHeight,
QMemArray< int > &  colWidth 
) const [protected]

Calculate the dimensions for the columns and rows for a grid of numCols columns.

Parameters:
numColsNumber of columns.
rowHeightArray where to fill in the calculated row heights.
colWidthArray where to fill in the calculated column widths.

Definition at line 534 of file qwt_dyngrid_layout.cpp.

References int(), QwtDynGridLayout::PrivateData::isDirty, QwtDynGridLayout::PrivateData::itemSizeHints, numCols(), and qwtMax.

Referenced by heightForWidth(), and sizeHint().

{
    if ( numCols <= 0 )
        return;

    if ( d_data->isDirty )
        ((QwtDynGridLayout*)this)->updateLayoutCache();

    for ( uint index = 0; 
        index < (uint)d_data->itemSizeHints.count(); index++ )
    {
        const int row = index / numCols;
        const int col = index % numCols;

        const QSize &size = d_data->itemSizeHints[int(index)];

        rowHeight[row] = (col == 0) 
            ? size.height() : qwtMax(rowHeight[row], size.height());
        colWidth[col] = (row == 0) 
            ? size.width() : qwtMax(colWidth[col], size.width());
    }
}
QValueList< QRect > QwtDynGridLayout::layoutItems ( const QRect &  rect,
uint  numCols 
) const

Calculate the geometries of the layout items for a layout with numCols columns and a given rect.

Parameters:
rectRect where to place the items
numColsNumber of columns
Returns:
item geometries

Definition at line 452 of file qwt_dyngrid_layout.cpp.

References int(), QwtDynGridLayout::PrivateData::maxCols, and maxCols().

Referenced by QwtPlot::printLegend(), and setGeometry().

{
#if QT_VERSION < 0x040000
    QValueList<QRect> itemGeometries;
#else
    QList<QRect> itemGeometries;
#endif
    if ( numCols == 0 || isEmpty() )
        return itemGeometries;

    uint numRows = itemCount() / numCols;
    if ( numRows % itemCount() )
        numRows++;
 
    QwtArray<int> rowHeight(numRows);
    QwtArray<int> colWidth(numCols);
 
    layoutGrid(numCols, rowHeight, colWidth);

    bool expandH, expandV;
#if QT_VERSION >= 0x040000
    expandH = expandingDirections() & Qt::Horizontal;
    expandV = expandingDirections() & Qt::Vertical;
#else
    expandH = expanding() & QSizePolicy::Horizontally;
    expandV = expanding() & QSizePolicy::Vertically;
#endif

    if ( expandH || expandV )
        stretchGrid(rect, numCols, rowHeight, colWidth);

    QwtDynGridLayout *that = (QwtDynGridLayout *)this;
    const int maxCols = d_data->maxCols;
    that->d_data->maxCols = numCols;
    const QRect alignedRect = alignmentRect(rect);
    that->d_data->maxCols = maxCols;

    const int xOffset = expandH ? 0 : alignedRect.x();
    const int yOffset = expandV ? 0 : alignedRect.y();

    QwtArray<int> colX(numCols);
    QwtArray<int> rowY(numRows);

    const int xySpace = spacing();

    rowY[0] = yOffset + margin();
    for ( int r = 1; r < (int)numRows; r++ )
        rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace;

    colX[0] = xOffset + margin();
    for ( int c = 1; c < (int)numCols; c++ )
        colX[c] = colX[c-1] + colWidth[c-1] + xySpace;
    
    const int itemCount = d_data->itemList.size();
    for ( int i = 0; i < itemCount; i++ )
    {
        const int row = i / numCols;
        const int col = i % numCols;

        QRect itemGeometry(colX[col], rowY[row], 
            colWidth[col], rowHeight[row]);
        itemGeometries.append(itemGeometry);
    }

    return itemGeometries;
}
uint QwtDynGridLayout::maxCols (  ) const

Return the upper limit for the number of columns. 0 means unlimited, what is the default.

See also:
setMaxCols()

Definition at line 206 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::maxCols.

Referenced by columnsForWidth(), layoutItems(), and setMaxCols().

{ 
    return d_data->maxCols; 
}
int QwtDynGridLayout::maxItemWidth (  ) const [virtual]
Returns:
the maximum width of all layout items

Definition at line 423 of file qwt_dyngrid_layout.cpp.

References int(), QwtDynGridLayout::PrivateData::isDirty, isEmpty(), and QwtDynGridLayout::PrivateData::itemSizeHints.

Referenced by QwtLegend::layoutContents().

{
    if ( isEmpty() )
        return 0;

    if ( d_data->isDirty )
        ((QwtDynGridLayout*)this)->updateLayoutCache();

    int w = 0;
    for ( uint i = 0; i < (uint)d_data->itemSizeHints.count(); i++ )
    {
        const int itemW = d_data->itemSizeHints[int(i)].width();
        if ( itemW > w )
            w = itemW;
    }

    return w;
}
uint QwtDynGridLayout::numCols (  ) const
Returns:
Number of columns of the current layout.
See also:
numRows()
Warning:
The number of columns might change whenever the geometry changes

Definition at line 702 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::numCols.

Referenced by columnsForWidth(), heightForWidth(), layoutGrid(), sizeHint(), and stretchGrid().

{ 
    return d_data->numCols; 
}
uint QwtDynGridLayout::numRows (  ) const
Returns:
Number of rows of the current layout.
See also:
numCols()
Warning:
The number of rows might change whenever the geometry changes

Definition at line 692 of file qwt_dyngrid_layout.cpp.

References QwtDynGridLayout::PrivateData::numRows.

Referenced by heightForWidth(), sizeHint(), and stretchGrid().

{ 
    return d_data->numRows; 
}
void QwtDynGridLayout::setExpanding ( QSizePolicy::ExpandData  expanding )

Definition at line 248 of file qwt_dyngrid_layout.cpp.

References expanding(), and QwtDynGridLayout::PrivateData::expanding.

{
    d_data->expanding = expanding;
}
void QwtDynGridLayout::setGeometry ( const QRect &  rect ) [virtual]

Reorganizes columns and rows and resizes managed widgets within the rectangle rect.

Parameters:
rectLayout geometry

Definition at line 329 of file qwt_dyngrid_layout.cpp.

References columnsForWidth(), isEmpty(), itemCount(), QwtDynGridLayout::PrivateData::itemList, layoutItems(), QwtDynGridLayout::PrivateData::numCols, and QwtDynGridLayout::PrivateData::numRows.

{
    QLayout::setGeometry(rect);

    if ( isEmpty() )
        return;

    d_data->numCols = columnsForWidth(rect.width());
    d_data->numRows = itemCount() / d_data->numCols;
    if ( itemCount() % d_data->numCols )
        d_data->numRows++;

#if QT_VERSION < 0x040000
    QValueList<QRect> itemGeometries = layoutItems(rect, d_data->numCols);
#else
    QList<QRect> itemGeometries = layoutItems(rect, d_data->numCols);
#endif

    int index = 0;
    for (PrivateData::LayoutItemList::iterator it = d_data->itemList.begin();
        it != d_data->itemList.end(); ++it)
    {
        QWidget *w = (*it)->widget();
        if ( w )
        {
            w->setGeometry(itemGeometries[index]);
            index++;
        }
    }
}
void QwtDynGridLayout::setMaxCols ( uint  maxCols )

Limit the number of columns.

Parameters:
maxColsupper limit, 0 means unlimited
See also:
maxCols()

Definition at line 195 of file qwt_dyngrid_layout.cpp.

References maxCols(), and QwtDynGridLayout::PrivateData::maxCols.

Referenced by QwtPlot::insertLegend().

{
    d_data->maxCols = maxCols;
}
QSize QwtDynGridLayout::sizeHint (  ) const [virtual]

Return the size hint. If maxCols() > 0 it is the size for a grid with maxCols() columns, otherwise it is the size for a grid with only one row.

See also:
maxCols(), setMaxCols()

Definition at line 661 of file qwt_dyngrid_layout.cpp.

References int(), isEmpty(), itemCount(), layoutGrid(), QwtDynGridLayout::PrivateData::maxCols, numCols(), and numRows().

{
    if ( isEmpty() )
        return QSize();

    const uint numCols = (d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
    uint numRows = itemCount() / numCols;
    if ( itemCount() % numCols )
        numRows++;

    QwtArray<int> rowHeight(numRows);
    QwtArray<int> colWidth(numCols);

    layoutGrid(numCols, rowHeight, colWidth);

    int h = 2 * margin() + (numRows - 1) * spacing();
    for ( int row = 0; row < (int)numRows; row++ )
        h += rowHeight[row];

    int w = 2 * margin() + (numCols - 1) * spacing(); 
    for ( int col = 0; col < (int)numCols; col++ )
        w += colWidth[col];

    return QSize(w, h);
}
void QwtDynGridLayout::stretchGrid ( const QRect &  rect,
uint  numCols,
QMemArray< int > &  rowHeight,
QMemArray< int > &  colWidth 
) const [protected]

Stretch columns in case of expanding() & QSizePolicy::Horizontal and rows in case of expanding() & QSizePolicy::Vertical to fill the entire rect. Rows and columns are stretched with the same factor.

See also:
setExpanding(), expanding()

Definition at line 600 of file qwt_dyngrid_layout.cpp.

References expanding(), int(), isEmpty(), itemCount(), numCols(), and numRows().

{
    if ( numCols == 0 || isEmpty() )
        return;

    bool expandH, expandV;
#if QT_VERSION >= 0x040000
    expandH = expandingDirections() & Qt::Horizontal;
    expandV = expandingDirections() & Qt::Vertical;
#else
    expandH = expanding() & QSizePolicy::Horizontally;
    expandV = expanding() & QSizePolicy::Vertically;
#endif

    if ( expandH )
    {
        int xDelta = rect.width() - 2 * margin() - (numCols - 1) * spacing();
        for ( int col = 0; col < (int)numCols; col++ )
            xDelta -= colWidth[col];

        if ( xDelta > 0 )
        {
            for ( int col = 0; col < (int)numCols; col++ )
            {
                const int space = xDelta / (numCols - col);
                colWidth[col] += space;
                xDelta -= space;
            }
        }
    }

    if ( expandV )
    {
        uint numRows = itemCount() / numCols;
        if ( itemCount() % numCols )
            numRows++;

        int yDelta = rect.height() - 2 * margin() - (numRows - 1) * spacing();
        for ( int row = 0; row < (int)numRows; row++ )
            yDelta -= rowHeight[row];

        if ( yDelta > 0 )
        {
            for ( int row = 0; row < (int)numRows; row++ )
            {
                const int space = yDelta / (numRows - row);
                rowHeight[row] += space;
                yDelta -= space;
            }
        }
    }
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines