qwt_dyngrid_layout.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_dyngrid_layout.h"
11 
12 #include <qvector.h>
13 #include <qlist.h>
14 
16 {
17  public:
18  PrivateData()
19  : isDirty( true )
20  {
21  }
22 
23  void updateLayoutCache();
24 
26 
27  uint maxColumns;
28  uint numRows;
29  uint numColumns;
30 
31  Qt::Orientations expanding;
32 
33  bool isDirty;
35 };
36 
38 {
39  itemSizeHints.resize( itemList.count() );
40 
41  int index = 0;
42 
43  for ( QList< QLayoutItem* >::const_iterator it = itemList.constBegin();
44  it != itemList.constEnd(); ++it, index++ )
45  {
46  itemSizeHints[ index ] = ( *it )->sizeHint();
47  }
48 
49  isDirty = false;
50 }
51 
58 QwtDynGridLayout::QwtDynGridLayout( QWidget* parent, int margin, int spacing )
59  : QLayout( parent )
60 {
61  init();
62 
63  setSpacing( spacing );
64  setContentsMargins( margin, margin, margin, margin );
65 }
66 
72 {
73  init();
74  setSpacing( spacing );
75 }
76 
81 {
84 }
85 
87 
89 {
90  qDeleteAll( m_data->itemList );
91  delete m_data;
92 }
93 
96 {
97  m_data->isDirty = true;
98  QLayout::invalidate();
99 }
100 
106 void QwtDynGridLayout::setMaxColumns( uint maxColumns )
107 {
109 }
110 
120 {
121  return m_data->maxColumns;
122 }
123 
128 void QwtDynGridLayout::addItem( QLayoutItem* item )
129 {
130  m_data->itemList.append( item );
131  invalidate();
132 }
133 
138 {
139  return m_data->itemList.isEmpty();
140 }
141 
146 {
147  return m_data->itemList.count();
148 }
149 
157 QLayoutItem* QwtDynGridLayout::itemAt( int index ) const
158 {
159  if ( index < 0 || index >= m_data->itemList.count() )
160  return NULL;
161 
162  return m_data->itemList.at( index );
163 }
164 
172 QLayoutItem* QwtDynGridLayout::takeAt( int index )
173 {
174  if ( index < 0 || index >= m_data->itemList.count() )
175  return NULL;
176 
177  m_data->isDirty = true;
178  return m_data->itemList.takeAt( index );
179 }
180 
183 {
184  return m_data->itemList.count();
185 }
186 
196 void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding )
197 {
198  m_data->expanding = expanding;
199 }
200 
212 {
213  return m_data->expanding;
214 }
215 
222 void QwtDynGridLayout::setGeometry( const QRect& rect )
223 {
224  QLayout::setGeometry( rect );
225 
226  if ( isEmpty() )
227  return;
228 
229  m_data->numColumns = columnsForWidth( rect.width() );
231  if ( itemCount() % m_data->numColumns )
232  m_data->numRows++;
233 
234  const QList< QRect > itemGeometries = layoutItems( rect, m_data->numColumns );
235 
236  int index = 0;
237  for ( QList< QLayoutItem* >::const_iterator it = m_data->itemList.constBegin();
238  it != m_data->itemList.constEnd(); ++it )
239  {
240  ( *it )->setGeometry( itemGeometries[index] );
241  index++;
242  }
243 }
244 
256 uint QwtDynGridLayout::columnsForWidth( int width ) const
257 {
258  if ( isEmpty() )
259  return 0;
260 
261  uint maxColumns = itemCount();
262  if ( m_data->maxColumns > 0 )
264 
265  if ( maxRowWidth( maxColumns ) <= width )
266  return maxColumns;
267 
268  for ( uint numColumns = 2; numColumns <= maxColumns; numColumns++ )
269  {
270  const int rowWidth = maxRowWidth( numColumns );
271  if ( rowWidth > width )
272  return numColumns - 1;
273  }
274 
275  return 1; // At least 1 column
276 }
277 
285 int QwtDynGridLayout::maxRowWidth( int numColumns ) const
286 {
287  int col;
288 
289  QVector< int > colWidth( numColumns );
290  for ( col = 0; col < numColumns; col++ )
291  colWidth[col] = 0;
292 
293  if ( m_data->isDirty )
295 
296  for ( int index = 0;
297  index < m_data->itemSizeHints.count(); index++ )
298  {
299  col = index % numColumns;
300  colWidth[col] = qMax( colWidth[col],
301  m_data->itemSizeHints[index].width() );
302  }
303 
304  const QMargins m = contentsMargins();
305 
306  int rowWidth = m.left() + m.right() + ( numColumns - 1 ) * spacing();
307  for ( col = 0; col < numColumns; col++ )
308  rowWidth += colWidth[col];
309 
310  return rowWidth;
311 }
312 
317 {
318  if ( isEmpty() )
319  return 0;
320 
321  if ( m_data->isDirty )
323 
324  int w = 0;
325  for ( int i = 0; i < m_data->itemSizeHints.count(); i++ )
326  {
327  const int itemW = m_data->itemSizeHints[i].width();
328  if ( itemW > w )
329  w = itemW;
330  }
331 
332  return w;
333 }
334 
345  uint numColumns ) const
346 {
347  QList< QRect > itemGeometries;
348  if ( numColumns == 0 || isEmpty() )
349  return itemGeometries;
350 
351  uint numRows = itemCount() / numColumns;
352  if ( numColumns % itemCount() )
353  numRows++;
354 
355  if ( numRows == 0 )
356  return itemGeometries;
357 
358  QVector< int > rowHeight( numRows );
359  QVector< int > colWidth( numColumns );
360 
361  layoutGrid( numColumns, rowHeight, colWidth );
362 
363  bool expandH, expandV;
364  expandH = expandingDirections() & Qt::Horizontal;
365  expandV = expandingDirections() & Qt::Vertical;
366 
367  if ( expandH || expandV )
368  stretchGrid( rect, numColumns, rowHeight, colWidth );
369 
370  const int maxColumns = m_data->maxColumns;
372  const QRect alignedRect = alignmentRect( rect );
374 
375  const int xOffset = expandH ? 0 : alignedRect.x();
376  const int yOffset = expandV ? 0 : alignedRect.y();
377 
378  QVector< int > colX( numColumns );
379  QVector< int > rowY( numRows );
380 
381  const int xySpace = spacing();
382 
383  const QMargins m = contentsMargins();
384 
385  rowY[0] = yOffset + m.top();
386  for ( uint r = 1; r < numRows; r++ )
387  rowY[r] = rowY[r - 1] + rowHeight[r - 1] + xySpace;
388 
389  colX[0] = xOffset + m.left();
390  for ( uint c = 1; c < numColumns; c++ )
391  colX[c] = colX[c - 1] + colWidth[c - 1] + xySpace;
392 
393  const int itemCount = m_data->itemList.size();
394  itemGeometries.reserve( itemCount );
395 
396  for ( int i = 0; i < itemCount; i++ )
397  {
398  const int row = i / numColumns;
399  const int col = i % numColumns;
400 
401  const QRect itemGeometry( colX[col], rowY[row],
402  colWidth[col], rowHeight[row] );
403  itemGeometries.append( itemGeometry );
404  }
405 
406  return itemGeometries;
407 }
408 
409 
419 void QwtDynGridLayout::layoutGrid( uint numColumns,
420  QVector< int >& rowHeight, QVector< int >& colWidth ) const
421 {
422  if ( numColumns <= 0 )
423  return;
424 
425  if ( m_data->isDirty )
427 
428  for ( int index = 0; index < m_data->itemSizeHints.count(); index++ )
429  {
430  const int row = index / numColumns;
431  const int col = index % numColumns;
432 
433  const QSize& size = m_data->itemSizeHints[index];
434 
435  rowHeight[row] = ( col == 0 )
436  ? size.height() : qMax( rowHeight[row], size.height() );
437  colWidth[col] = ( row == 0 )
438  ? size.width() : qMax( colWidth[col], size.width() );
439  }
440 }
441 
447 {
448  return true;
449 }
450 
455 int QwtDynGridLayout::heightForWidth( int width ) const
456 {
457  if ( isEmpty() )
458  return 0;
459 
460  const uint numColumns = columnsForWidth( width );
461  uint numRows = itemCount() / numColumns;
462  if ( itemCount() % numColumns )
463  numRows++;
464 
465  QVector< int > rowHeight( numRows );
466  QVector< int > colWidth( numColumns );
467 
468  layoutGrid( numColumns, rowHeight, colWidth );
469 
470  const QMargins m = contentsMargins();
471 
472  int h = m.top() + m.bottom() + ( numRows - 1 ) * spacing();
473  for ( uint row = 0; row < numRows; row++ )
474  h += rowHeight[row];
475 
476  return h;
477 }
478 
491 void QwtDynGridLayout::stretchGrid( const QRect& rect,
492  uint numColumns, QVector< int >& rowHeight, QVector< int >& colWidth ) const
493 {
494  if ( numColumns == 0 || isEmpty() )
495  return;
496 
497  bool expandH, expandV;
498  expandH = expandingDirections() & Qt::Horizontal;
499  expandV = expandingDirections() & Qt::Vertical;
500 
501  const QMargins m = contentsMargins();
502 
503  if ( expandH )
504  {
505  int xDelta = rect.width() - m.left() - m.right() - ( numColumns - 1 ) * spacing();
506  for ( uint col = 0; col < numColumns; col++ )
507  xDelta -= colWidth[col];
508 
509  if ( xDelta > 0 )
510  {
511  for ( uint col = 0; col < numColumns; col++ )
512  {
513  const int space = xDelta / ( numColumns - col );
514  colWidth[col] += space;
515  xDelta -= space;
516  }
517  }
518  }
519 
520  if ( expandV )
521  {
522  uint numRows = itemCount() / numColumns;
523  if ( itemCount() % numColumns )
524  numRows++;
525 
526  int yDelta = rect.height() - m.top() - m.bottom() - ( numRows - 1 ) * spacing();
527  for ( uint row = 0; row < numRows; row++ )
528  yDelta -= rowHeight[row];
529 
530  if ( yDelta > 0 )
531  {
532  for ( uint row = 0; row < numRows; row++ )
533  {
534  const int space = yDelta / ( numRows - row );
535  rowHeight[row] += space;
536  yDelta -= space;
537  }
538  }
539  }
540 }
541 
551 {
552  if ( isEmpty() )
553  return QSize();
554 
555  uint numColumns = itemCount();
556  if ( m_data->maxColumns > 0 )
558 
559  uint numRows = itemCount() / numColumns;
560  if ( itemCount() % numColumns )
561  numRows++;
562 
563  QVector< int > rowHeight( numRows );
564  QVector< int > colWidth( numColumns );
565 
566  layoutGrid( numColumns, rowHeight, colWidth );
567 
568  const QMargins m = contentsMargins();
569 
570  int h = m.top() + m.bottom() + ( numRows - 1 ) * spacing();
571  for ( uint row = 0; row < numRows; row++ )
572  h += rowHeight[row];
573 
574  int w = m.left() + m.right() + ( numColumns - 1 ) * spacing();
575  for ( uint col = 0; col < numColumns; col++ )
576  w += colWidth[col];
577 
578  return QSize( w, h );
579 }
580 
587 {
588  return m_data->numRows;
589 }
590 
597 {
598  return m_data->numColumns;
599 }
600 
601 #if QWT_MOC_INCLUDE
602 #include "moc_qwt_dyngrid_layout.cpp"
603 #endif
QwtDynGridLayout::PrivateData::numColumns
uint numColumns
Definition: qwt_dyngrid_layout.cpp:36
QwtDynGridLayout::takeAt
virtual QLayoutItem * takeAt(int index) QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:172
QwtDynGridLayout::maxColumns
uint maxColumns() const
Return the upper limit for the number of columns.
Definition: qwt_dyngrid_layout.cpp:119
QwtDynGridLayout::isEmpty
virtual bool isEmpty() const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:137
QwtDynGridLayout::invalidate
virtual void invalidate() QWT_OVERRIDE
Invalidate all internal caches.
Definition: qwt_dyngrid_layout.cpp:95
QwtDynGridLayout::QwtDynGridLayout
QwtDynGridLayout(QWidget *, int margin=0, int spacing=-1)
Definition: qwt_dyngrid_layout.cpp:58
QwtDynGridLayout::itemCount
uint itemCount() const
Definition: qwt_dyngrid_layout.cpp:145
QVector< QSize >
QwtDynGridLayout::PrivateData
Definition: qwt_dyngrid_layout.cpp:15
QwtDynGridLayout::numColumns
uint numColumns() const
Definition: qwt_dyngrid_layout.cpp:596
QwtDynGridLayout::numRows
uint numRows() const
Definition: qwt_dyngrid_layout.cpp:586
QwtDynGridLayout::PrivateData::itemList
QList< QLayoutItem * > itemList
Definition: qwt_dyngrid_layout.cpp:32
QwtDynGridLayout::PrivateData::maxColumns
uint maxColumns
Definition: qwt_dyngrid_layout.cpp:34
QList< QLayoutItem * >
QwtDynGridLayout::heightForWidth
virtual int heightForWidth(int) const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:455
QwtDynGridLayout::columnsForWidth
virtual uint columnsForWidth(int width) const
Calculate the number of columns for a given width.
Definition: qwt_dyngrid_layout.cpp:256
QwtDynGridLayout::sizeHint
virtual QSize sizeHint() const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:550
QwtDynGridLayout::PrivateData::updateLayoutCache
void updateLayoutCache()
Definition: qwt_dyngrid_layout.cpp:37
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
QwtDynGridLayout::addItem
virtual void addItem(QLayoutItem *) QWT_OVERRIDE
Add an item to the next free position.
Definition: qwt_dyngrid_layout.cpp:128
QwtDynGridLayout::maxRowWidth
int maxRowWidth(int numColumns) const
Definition: qwt_dyngrid_layout.cpp:285
QwtDynGridLayout::setMaxColumns
void setMaxColumns(uint maxColumns)
Definition: qwt_dyngrid_layout.cpp:106
QwtDynGridLayout::layoutItems
QList< QRect > layoutItems(const QRect &, uint numColumns) const
Definition: qwt_dyngrid_layout.cpp:344
QwtDynGridLayout::PrivateData::PrivateData
PrivateData()
Definition: qwt_dyngrid_layout.cpp:25
QwtDynGridLayout::~QwtDynGridLayout
virtual ~QwtDynGridLayout()
Destructor.
Definition: qwt_dyngrid_layout.cpp:88
QwtDynGridLayout::PrivateData::numRows
uint numRows
Definition: qwt_dyngrid_layout.cpp:35
qwt_dyngrid_layout.h
QwtDynGridLayout::itemAt
virtual QLayoutItem * itemAt(int index) const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:157
QwtDynGridLayout::expandingDirections
virtual Qt::Orientations expandingDirections() const QWT_OVERRIDE
Returns whether this layout can make use of more space than sizeHint().
Definition: qwt_dyngrid_layout.cpp:211
QwtDynGridLayout::stretchGrid
void stretchGrid(const QRect &rect, uint numColumns, QVector< int > &rowHeight, QVector< int > &colWidth) const
Definition: qwt_dyngrid_layout.cpp:491
QwtDynGridLayout::layoutGrid
void layoutGrid(uint numColumns, QVector< int > &rowHeight, QVector< int > &colWidth) const
Definition: qwt_dyngrid_layout.cpp:419
QwtDynGridLayout::maxItemWidth
virtual int maxItemWidth() const
Definition: qwt_dyngrid_layout.cpp:316
QwtDynGridLayout::PrivateData::expanding
Qt::Orientations expanding
Definition: qwt_dyngrid_layout.cpp:38
QwtDynGridLayout::m_data
PrivateData * m_data
Definition: qwt_dyngrid_layout.h:80
QwtDynGridLayout::count
virtual int count() const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:182
QwtDynGridLayout::hasHeightForWidth
virtual bool hasHeightForWidth() const QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:446
QwtDynGridLayout::PrivateData::isDirty
bool isDirty
Definition: qwt_dyngrid_layout.cpp:40
QwtDynGridLayout::setGeometry
virtual void setGeometry(const QRect &) QWT_OVERRIDE
Definition: qwt_dyngrid_layout.cpp:222
QwtDynGridLayout::PrivateData::itemSizeHints
QVector< QSize > itemSizeHints
Definition: qwt_dyngrid_layout.cpp:41
QwtDynGridLayout::setExpandingDirections
void setExpandingDirections(Qt::Orientations)
Definition: qwt_dyngrid_layout.cpp:196
QwtDynGridLayout::init
void init()
Definition: qwt_dyngrid_layout.cpp:80


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:45