qwt_dyngrid_layout.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 #include "qwt_math.h"
12 #include <qvector.h>
13 #include <qlist.h>
14 
16 {
17 public:
19  isDirty( true )
20  {
21  }
22 
23  void updateLayoutCache();
24 
25  mutable QList<QLayoutItem*> itemList;
26 
27  uint maxColumns;
28  uint numRows;
29  uint numColumns;
30 
31  Qt::Orientations expanding;
32 
33  bool isDirty;
34  QVector<QSize> itemSizeHints;
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 
59  int margin, int spacing ):
60  QLayout( parent )
61 {
62  init();
63 
64  setSpacing( spacing );
65  setMargin( margin );
66 }
67 
73 {
74  init();
75  setSpacing( spacing );
76 }
77 
82 {
85  d_data->expanding = 0;
86 }
87 
89 
91 {
92  qDeleteAll( d_data->itemList );
93  delete d_data;
94 }
95 
98 {
99  d_data->isDirty = true;
100  QLayout::invalidate();
101 }
102 
109 {
111 }
112 
122 {
123  return d_data->maxColumns;
124 }
125 
130 void QwtDynGridLayout::addItem( QLayoutItem *item )
131 {
132  d_data->itemList.append( item );
133  invalidate();
134 }
135 
140 {
141  return d_data->itemList.isEmpty();
142 }
143 
148 {
149  return d_data->itemList.count();
150 }
151 
159 QLayoutItem *QwtDynGridLayout::itemAt( int index ) const
160 {
161  if ( index < 0 || index >= d_data->itemList.count() )
162  return NULL;
163 
164  return d_data->itemList.at( index );
165 }
166 
174 QLayoutItem *QwtDynGridLayout::takeAt( int index )
175 {
176  if ( index < 0 || index >= d_data->itemList.count() )
177  return NULL;
178 
179  d_data->isDirty = true;
180  return d_data->itemList.takeAt( index );
181 }
182 
185 {
186  return d_data->itemList.count();
187 }
188 
198 void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding )
199 {
200  d_data->expanding = expanding;
201 }
202 
214 {
215  return d_data->expanding;
216 }
217 
224 void QwtDynGridLayout::setGeometry( const QRect &rect )
225 {
226  QLayout::setGeometry( rect );
227 
228  if ( isEmpty() )
229  return;
230 
231  d_data->numColumns = columnsForWidth( rect.width() );
233  if ( itemCount() % d_data->numColumns )
234  d_data->numRows++;
235 
236  const QList<QRect> itemGeometries = layoutItems( rect, d_data->numColumns );
237 
238  int index = 0;
239  for ( QList<QLayoutItem*>::const_iterator it = d_data->itemList.constBegin();
240  it != d_data->itemList.constEnd(); ++it )
241  {
242  ( *it )->setGeometry( itemGeometries[index] );
243  index++;
244  }
245 }
246 
258 uint QwtDynGridLayout::columnsForWidth( int width ) const
259 {
260  if ( isEmpty() )
261  return 0;
262 
263  uint maxColumns = itemCount();
264  if ( d_data->maxColumns > 0 )
265  maxColumns = qMin( d_data->maxColumns, maxColumns );
266 
267  if ( maxRowWidth( maxColumns ) <= width )
268  return maxColumns;
269 
270  for ( uint numColumns = 2; numColumns <= maxColumns; numColumns++ )
271  {
272  const int rowWidth = maxRowWidth( numColumns );
273  if ( rowWidth > width )
274  return numColumns - 1;
275  }
276 
277  return 1; // At least 1 column
278 }
279 
288 {
289  int col;
290 
291  QVector<int> colWidth( numColumns );
292  for ( col = 0; col < numColumns; col++ )
293  colWidth[col] = 0;
294 
295  if ( d_data->isDirty )
297 
298  for ( int index = 0;
299  index < d_data->itemSizeHints.count(); index++ )
300  {
301  col = index % numColumns;
302  colWidth[col] = qMax( colWidth[col],
303  d_data->itemSizeHints[int( index )].width() );
304  }
305 
306  int rowWidth = 2 * margin() + ( 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 ( d_data->isDirty )
323 
324  int w = 0;
325  for ( int i = 0; i < d_data->itemSizeHints.count(); i++ )
326  {
327  const int itemW = d_data->itemSizeHints[i].width();
328  if ( itemW > w )
329  w = itemW;
330  }
331 
332  return w;
333 }
334 
344 QList<QRect> QwtDynGridLayout::layoutItems( const QRect &rect,
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 = d_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  rowY[0] = yOffset + margin();
384  for ( uint r = 1; r < numRows; r++ )
385  rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace;
386 
387  colX[0] = xOffset + margin();
388  for ( uint c = 1; c < numColumns; c++ )
389  colX[c] = colX[c-1] + colWidth[c-1] + xySpace;
390 
391  const int itemCount = d_data->itemList.size();
392 #if QT_VERSION >= 0x040700
393  itemGeometries.reserve( itemCount );
394 #endif
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 
420  QVector<int>& rowHeight, QVector<int>& colWidth ) const
421 {
422  if ( numColumns <= 0 )
423  return;
424 
425  if ( d_data->isDirty )
427 
428  for ( int index = 0; index < d_data->itemSizeHints.count(); index++ )
429  {
430  const int row = index / numColumns;
431  const int col = index % numColumns;
432 
433  const QSize &size = d_data->itemSizeHints[int( 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  int h = 2 * margin() + ( numRows - 1 ) * spacing();
471  for ( uint row = 0; row < numRows; row++ )
472  h += rowHeight[row];
473 
474  return h;
475 }
476 
489 void QwtDynGridLayout::stretchGrid( const QRect &rect,
490  uint numColumns, QVector<int>& rowHeight, QVector<int>& colWidth ) const
491 {
492  if ( numColumns == 0 || isEmpty() )
493  return;
494 
495  bool expandH, expandV;
496  expandH = expandingDirections() & Qt::Horizontal;
497  expandV = expandingDirections() & Qt::Vertical;
498 
499  if ( expandH )
500  {
501  int xDelta = rect.width() - 2 * margin() - ( numColumns - 1 ) * spacing();
502  for ( uint col = 0; col < numColumns; col++ )
503  xDelta -= colWidth[col];
504 
505  if ( xDelta > 0 )
506  {
507  for ( uint col = 0; col < numColumns; col++ )
508  {
509  const int space = xDelta / ( numColumns - col );
510  colWidth[col] += space;
511  xDelta -= space;
512  }
513  }
514  }
515 
516  if ( expandV )
517  {
518  uint numRows = itemCount() / numColumns;
519  if ( itemCount() % numColumns )
520  numRows++;
521 
522  int yDelta = rect.height() - 2 * margin() - ( numRows - 1 ) * spacing();
523  for ( uint row = 0; row < numRows; row++ )
524  yDelta -= rowHeight[row];
525 
526  if ( yDelta > 0 )
527  {
528  for ( uint row = 0; row < numRows; row++ )
529  {
530  const int space = yDelta / ( numRows - row );
531  rowHeight[row] += space;
532  yDelta -= space;
533  }
534  }
535  }
536 }
537 
547 {
548  if ( isEmpty() )
549  return QSize();
550 
551  uint numColumns = itemCount();
552  if ( d_data->maxColumns > 0 )
553  numColumns = qMin( d_data->maxColumns, numColumns );
554 
555  uint numRows = itemCount() / numColumns;
556  if ( itemCount() % numColumns )
557  numRows++;
558 
559  QVector<int> rowHeight( numRows );
560  QVector<int> colWidth( numColumns );
561 
562  layoutGrid( numColumns, rowHeight, colWidth );
563 
564  int h = 2 * margin() + ( numRows - 1 ) * spacing();
565  for ( uint row = 0; row < numRows; row++ )
566  h += rowHeight[row];
567 
568  int w = 2 * margin() + ( numColumns - 1 ) * spacing();
569  for ( uint col = 0; col < numColumns; col++ )
570  w += colWidth[col];
571 
572  return QSize( w, h );
573 }
574 
581 {
582  return d_data->numRows;
583 }
584 
591 {
592  return d_data->numColumns;
593 }
virtual int heightForWidth(int) const
void layoutGrid(uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const
virtual int maxItemWidth() const
virtual void setGeometry(const QRect &rect)
virtual uint columnsForWidth(int width) const
Calculate the number of columns for a given width.
QwtDynGridLayout(QWidget *, int margin=0, int space=-1)
void stretchGrid(const QRect &rect, uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const
virtual void addItem(QLayoutItem *)
Add an item to the next free position.
int maxRowWidth(int numCols) const
virtual void invalidate()
Invalidate all internal caches.
PrivateData * d_data
virtual bool isEmpty() const
void setMaxColumns(uint maxCols)
virtual int count() const
virtual QLayoutItem * itemAt(int index) const
virtual Qt::Orientations expandingDirections() const
Returns whether this layout can make use of more space than sizeHint().
QList< QLayoutItem * > itemList
uintptr_t size
TFSIMD_FORCE_INLINE const tfScalar & w() const
virtual bool hasHeightForWidth() const
QList< QRect > layoutItems(const QRect &, uint numCols) const
int i
uint maxColumns() const
Return the upper limit for the number of columns.
virtual ~QwtDynGridLayout()
Destructor.
uint numColumns() const
virtual QLayoutItem * takeAt(int index)
void setExpandingDirections(Qt::Orientations)
virtual QSize sizeHint() const


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17