| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 | 
							- /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 
-  * Qwt Widget Library
 
-  * Copyright (C) 1997   Josef Wilgen
 
-  * Copyright (C) 2002   Uwe Rathmann
 
-  *
 
-  * This library is free software; you can redistribute it and/or
 
-  * modify it under the terms of the Qwt License, Version 1.0
 
-  *****************************************************************************/
 
- #include "qwt_dyngrid_layout.h"
 
- #include "qwt_math.h"
 
- #include <qwidget.h>
 
- #include <qlist.h>
 
- class QwtDynGridLayout::PrivateData
 
- {
 
- public:
 
-     PrivateData():
 
-         isDirty( true )
 
-     {
 
-     }
 
-     void updateLayoutCache();
 
-     mutable QList<QLayoutItem*> itemList;
 
-     uint maxCols;
 
-     uint numRows;
 
-     uint numCols;
 
-     Qt::Orientations expanding;
 
-     bool isDirty;
 
-     QVector<QSize> itemSizeHints;
 
- };
 
- void QwtDynGridLayout::PrivateData::updateLayoutCache()
 
- {
 
-     itemSizeHints.resize( itemList.count() );
 
-     int index = 0;
 
-     for ( QList<QLayoutItem*>::iterator it = itemList.begin();
 
-         it != itemList.end(); ++it, index++ )
 
-     {
 
-         itemSizeHints[ index ] = ( *it )->sizeHint();
 
-     }
 
-     isDirty = false;
 
- }
 
- /*!
 
-   \param parent Parent widget
 
-   \param margin Margin
 
-   \param spacing Spacing
 
- */
 
- QwtDynGridLayout::QwtDynGridLayout( QWidget *parent,
 
-         int margin, int spacing ):
 
-     QLayout( parent )
 
- {
 
-     init();
 
-     setSpacing( spacing );
 
-     setMargin( margin );
 
- }
 
- /*!
 
-   \param spacing Spacing
 
- */
 
- QwtDynGridLayout::QwtDynGridLayout( int spacing )
 
- {
 
-     init();
 
-     setSpacing( spacing );
 
- }
 
- /*!
 
-   Initialize the layout with default values.
 
- */
 
- void QwtDynGridLayout::init()
 
- {
 
-     d_data = new QwtDynGridLayout::PrivateData;
 
-     d_data->maxCols = d_data->numRows = d_data->numCols = 0;
 
-     d_data->expanding = 0;
 
- }
 
- //! Destructor
 
- QwtDynGridLayout::~QwtDynGridLayout()
 
- {
 
-     for ( int i = 0; i < d_data->itemList.size(); i++ )
 
-         delete d_data->itemList[i];
 
-     delete d_data;
 
- }
 
- //! Invalidate all internal caches
 
- void QwtDynGridLayout::invalidate()
 
- {
 
-     d_data->isDirty = true;
 
-     QLayout::invalidate();
 
- }
 
- /*!
 
-   Limit the number of columns.
 
-   \param maxCols upper limit, 0 means unlimited
 
-   \sa maxCols()
 
- */
 
- void QwtDynGridLayout::setMaxCols( uint maxCols )
 
- {
 
-     d_data->maxCols = maxCols;
 
- }
 
- /*!
 
-   Return the upper limit for the number of columns.
 
-   0 means unlimited, what is the default.
 
-   \sa setMaxCols()
 
- */
 
- uint QwtDynGridLayout::maxCols() const
 
- {
 
-     return d_data->maxCols;
 
- }
 
- //! Adds item to the next free position.
 
- void QwtDynGridLayout::addItem( QLayoutItem *item )
 
- {
 
-     d_data->itemList.append( item );
 
-     invalidate();
 
- }
 
- /*!
 
-   \return true if this layout is empty.
 
- */
 
- bool QwtDynGridLayout::isEmpty() const
 
- {
 
-     return d_data->itemList.isEmpty();
 
- }
 
- /*!
 
-   \return number of layout items
 
- */
 
- uint QwtDynGridLayout::itemCount() const
 
- {
 
-     return d_data->itemList.count();
 
- }
 
- /*!
 
-   Find the item at a spcific index
 
-   \param index Index
 
-   \sa takeAt()
 
- */
 
- QLayoutItem *QwtDynGridLayout::itemAt( int index ) const
 
- {
 
-     if ( index < 0 || index >= d_data->itemList.count() )
 
-         return NULL;
 
-     return d_data->itemList.at( index );
 
- }
 
- /*!
 
-   Find the item at a spcific index and remove it from the layout
 
-   \param index Index
 
-   \sa itemAt()
 
- */
 
- QLayoutItem *QwtDynGridLayout::takeAt( int index )
 
- {
 
-     if ( index < 0 || index >= d_data->itemList.count() )
 
-         return NULL;
 
-     d_data->isDirty = true;
 
-     return d_data->itemList.takeAt( index );
 
- }
 
- //! \return Number of items in the layout
 
- int QwtDynGridLayout::count() const
 
- {
 
-     return d_data->itemList.count();
 
- }
 
- /*!
 
-   Set whether this layout can make use of more space than sizeHint().
 
-   A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only
 
-   one dimension, while Qt::Vertical | Qt::Horizontal means that it wants
 
-   to grow in both dimensions. The default value is 0.
 
-   \param expanding Or'd orientations
 
-   \sa expandingDirections()
 
- */
 
- void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding )
 
- {
 
-     d_data->expanding = expanding;
 
- }
 
- /*!
 
-   Returns whether this layout can make use of more space than sizeHint().
 
-   A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only
 
-   one dimension, while Qt::Vertical | Qt::Horizontal means that it wants
 
-   to grow in both dimensions.
 
-   \sa setExpandingDirections()
 
- */
 
- Qt::Orientations QwtDynGridLayout::expandingDirections() const
 
- {
 
-     return d_data->expanding;
 
- }
 
- /*!
 
-   Reorganizes columns and rows and resizes managed widgets within
 
-   the rectangle rect.
 
-   \param rect Layout geometry
 
- */
 
- void QwtDynGridLayout::setGeometry( const QRect &rect )
 
- {
 
-     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++;
 
-     QList<QRect> itemGeometries = layoutItems( rect, d_data->numCols );
 
-     int index = 0;
 
-     for ( QList<QLayoutItem*>::iterator it = d_data->itemList.begin();
 
-         it != d_data->itemList.end(); ++it )
 
-     {
 
-         QWidget *w = ( *it )->widget();
 
-         if ( w )
 
-         {
 
-             w->setGeometry( itemGeometries[index] );
 
-             index++;
 
-         }
 
-     }
 
- }
 
- /*!
 
-   Calculate the number of columns for a given width. It tries to
 
-   use as many columns as possible (limited by maxCols())
 
-   \param width Available width for all columns
 
-   \sa maxCols(), setMaxCols()
 
- */
 
- uint QwtDynGridLayout::columnsForWidth( int width ) const
 
- {
 
-     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
 
- }
 
- /*!
 
-   Calculate the width of a layout for a given number of
 
-   columns.
 
-   \param numCols Given number of columns
 
-   \param itemWidth Array of the width hints for all items
 
- */
 
- int QwtDynGridLayout::maxRowWidth( int numCols ) const
 
- {
 
-     int col;
 
-     QVector<int> colWidth( numCols );
 
-     for ( col = 0; col < ( int )numCols; col++ )
 
-         colWidth[col] = 0;
 
-     if ( d_data->isDirty )
 
-         d_data->updateLayoutCache();
 
-     for ( uint index = 0;
 
-         index < ( uint )d_data->itemSizeHints.count(); index++ )
 
-     {
 
-         col = index % numCols;
 
-         colWidth[col] = qMax( colWidth[col],
 
-             d_data->itemSizeHints[int( index )].width() );
 
-     }
 
-     int rowWidth = 2 * margin() + ( numCols - 1 ) * spacing();
 
-     for ( col = 0; col < ( int )numCols; col++ )
 
-         rowWidth += colWidth[col];
 
-     return rowWidth;
 
- }
 
- /*!
 
-   \return the maximum width of all layout items
 
- */
 
- int QwtDynGridLayout::maxItemWidth() const
 
- {
 
-     if ( isEmpty() )
 
-         return 0;
 
-     if ( d_data->isDirty )
 
-         d_data->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;
 
- }
 
- /*!
 
-   Calculate the geometries of the layout items for a layout
 
-   with numCols columns and a given rect.
 
-   \param rect Rect where to place the items
 
-   \param numCols Number of columns
 
-   \return item geometries
 
- */
 
- QList<QRect> QwtDynGridLayout::layoutItems( const QRect &rect,
 
-     uint numCols ) const
 
- {
 
-     QList<QRect> itemGeometries;
 
-     if ( numCols == 0 || isEmpty() )
 
-         return itemGeometries;
 
-     uint numRows = itemCount() / numCols;
 
-     if ( numRows % itemCount() )
 
-         numRows++;
 
-     QVector<int> rowHeight( numRows );
 
-     QVector<int> colWidth( numCols );
 
-     layoutGrid( numCols, rowHeight, colWidth );
 
-     bool expandH, expandV;
 
-     expandH = expandingDirections() & Qt::Horizontal;
 
-     expandV = expandingDirections() & Qt::Vertical;
 
-     if ( expandH || expandV )
 
-         stretchGrid( rect, numCols, rowHeight, colWidth );
 
-     const int maxCols = d_data->maxCols;
 
-     d_data->maxCols = numCols;
 
-     const QRect alignedRect = alignmentRect( rect );
 
-     d_data->maxCols = maxCols;
 
-     const int xOffset = expandH ? 0 : alignedRect.x();
 
-     const int yOffset = expandV ? 0 : alignedRect.y();
 
-     QVector<int> colX( numCols );
 
-     QVector<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;
 
- }
 
- /*!
 
-   Calculate the dimensions for the columns and rows for a grid
 
-   of numCols columns.
 
-   \param numCols Number of columns.
 
-   \param rowHeight Array where to fill in the calculated row heights.
 
-   \param colWidth Array where to fill in the calculated column widths.
 
- */
 
- void QwtDynGridLayout::layoutGrid( uint numCols,
 
-     QVector<int>& rowHeight, QVector<int>& colWidth ) const
 
- {
 
-     if ( numCols <= 0 )
 
-         return;
 
-     if ( d_data->isDirty )
 
-         d_data->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() : qMax( rowHeight[row], size.height() );
 
-         colWidth[col] = ( row == 0 )
 
-             ? size.width() : qMax( colWidth[col], size.width() );
 
-     }
 
- }
 
- /*!
 
-   \return true: QwtDynGridLayout implements heightForWidth.
 
-   \sa heightForWidth()
 
- */
 
- bool QwtDynGridLayout::hasHeightForWidth() const
 
- {
 
-     return true;
 
- }
 
- /*!
 
-   \return The preferred height for this layout, given the width w.
 
-   \sa hasHeightForWidth()
 
- */
 
- int QwtDynGridLayout::heightForWidth( int width ) const
 
- {
 
-     if ( isEmpty() )
 
-         return 0;
 
-     const uint numCols = columnsForWidth( width );
 
-     uint numRows = itemCount() / numCols;
 
-     if ( itemCount() % numCols )
 
-         numRows++;
 
-     QVector<int> rowHeight( numRows );
 
-     QVector<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;
 
- }
 
- /*!
 
-   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.
 
-   \sa setExpanding(), expanding()
 
- */
 
- void QwtDynGridLayout::stretchGrid( const QRect &rect,
 
-     uint numCols, QVector<int>& rowHeight, QVector<int>& colWidth ) const
 
- {
 
-     if ( numCols == 0 || isEmpty() )
 
-         return;
 
-     bool expandH, expandV;
 
-     expandH = expandingDirections() & Qt::Horizontal;
 
-     expandV = expandingDirections() & Qt::Vertical;
 
-     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;
 
-             }
 
-         }
 
-     }
 
- }
 
- /*!
 
-    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.
 
-    \sa maxCols(), setMaxCols()
 
- */
 
- QSize QwtDynGridLayout::sizeHint() const
 
- {
 
-     if ( isEmpty() )
 
-         return QSize();
 
-     const uint numCols = ( d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
 
-     uint numRows = itemCount() / numCols;
 
-     if ( itemCount() % numCols )
 
-         numRows++;
 
-     QVector<int> rowHeight( numRows );
 
-     QVector<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 );
 
- }
 
- /*!
 
-   \return Number of rows of the current layout.
 
-   \sa numCols()
 
-   \warning The number of rows might change whenever the geometry changes
 
- */
 
- uint QwtDynGridLayout::numRows() const
 
- {
 
-     return d_data->numRows;
 
- }
 
- /*!
 
-   \return Number of columns of the current layout.
 
-   \sa numRows()
 
-   \warning The number of columns might change whenever the geometry changes
 
- */
 
- uint QwtDynGridLayout::numCols() const
 
- {
 
-     return d_data->numCols;
 
- }
 
 
  |