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 
12 #include <qvector.h>
13 #include <qlist.h>
14 
16 {
17 public:
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 
59  int margin, int spacing ):
60  QLayout( parent )
61 {
62  init();
63 
64  setSpacing( spacing );
65  setContentsMargins( margin, margin, margin, margin );
66 }
67 
73 {
74  init();
75  setSpacing( spacing );
76 }
77 
82 {
85 }
86 
88 
90 {
91  qDeleteAll( d_data->itemList );
92  delete d_data;
93 }
94 
97 {
98  d_data->isDirty = true;
99  QLayout::invalidate();
100 }
101 
108 {
110 }
111 
121 {
122  return d_data->maxColumns;
123 }
124 
129 void QwtDynGridLayout::addItem( QLayoutItem *item )
130 {
131  d_data->itemList.append( item );
132  invalidate();
133 }
134 
139 {
140  return d_data->itemList.isEmpty();
141 }
142 
147 {
148  return d_data->itemList.count();
149 }
150 
158 QLayoutItem *QwtDynGridLayout::itemAt( int index ) const
159 {
160  if ( index < 0 || index >= d_data->itemList.count() )
161  return NULL;
162 
163  return d_data->itemList.at( index );
164 }
165 
173 QLayoutItem *QwtDynGridLayout::takeAt( int index )
174 {
175  if ( index < 0 || index >= d_data->itemList.count() )
176  return NULL;
177 
178  d_data->isDirty = true;
179  return d_data->itemList.takeAt( index );
180 }
181 
184 {
185  return d_data->itemList.count();
186 }
187 
197 void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding )
198 {
199  d_data->expanding = expanding;
200 }
201 
213 {
214  return d_data->expanding;
215 }
216 
223 void QwtDynGridLayout::setGeometry( const QRect &rect )
224 {
225  QLayout::setGeometry( rect );
226 
227  if ( isEmpty() )
228  return;
229 
230  d_data->numColumns = columnsForWidth( rect.width() );
232  if ( itemCount() % d_data->numColumns )
233  d_data->numRows++;
234 
235  const QList<QRect> itemGeometries = layoutItems( rect, d_data->numColumns );
236 
237  int index = 0;
238  for ( QList<QLayoutItem*>::const_iterator it = d_data->itemList.constBegin();
239  it != d_data->itemList.constEnd(); ++it )
240  {
241  ( *it )->setGeometry( itemGeometries[index] );
242  index++;
243  }
244 }
245 
257 uint QwtDynGridLayout::columnsForWidth( int width ) const
258 {
259  if ( isEmpty() )
260  return 0;
261 
262  uint maxColumns = itemCount();
263  if ( d_data->maxColumns > 0 )
264  maxColumns = qMin( d_data->maxColumns, maxColumns );
265 
266  if ( maxRowWidth( maxColumns ) <= width )
267  return maxColumns;
268 
269  for ( uint numColumns = 2; numColumns <= maxColumns; numColumns++ )
270  {
271  const int rowWidth = maxRowWidth( numColumns );
272  if ( rowWidth > width )
273  return numColumns - 1;
274  }
275 
276  return 1; // At least 1 column
277 }
278 
287 {
288  int col;
289 
290  QVector<int> colWidth( numColumns );
291  for ( col = 0; col < numColumns; col++ )
292  colWidth[col] = 0;
293 
294  if ( d_data->isDirty )
296 
297  for ( int index = 0;
298  index < d_data->itemSizeHints.count(); index++ )
299  {
300  col = index % numColumns;
301  colWidth[col] = qMax( colWidth[col],
302  d_data->itemSizeHints[index].width() );
303  }
304 
305  const QMargins m = contentsMargins();
306 
307  int rowWidth = m.left() + m.right() + ( numColumns - 1 ) * spacing();
308  for ( col = 0; col < numColumns; col++ )
309  rowWidth += colWidth[col];
310 
311  return rowWidth;
312 }
313 
318 {
319  if ( isEmpty() )
320  return 0;
321 
322  if ( d_data->isDirty )
324 
325  int w = 0;
326  for ( int i = 0; i < d_data->itemSizeHints.count(); i++ )
327  {
328  const int itemW = d_data->itemSizeHints[i].width();
329  if ( itemW > w )
330  w = itemW;
331  }
332 
333  return w;
334 }
335 
346  uint numColumns ) const
347 {
348  QList<QRect> itemGeometries;
349  if ( numColumns == 0 || isEmpty() )
350  return itemGeometries;
351 
352  uint numRows = itemCount() / numColumns;
353  if ( numColumns % itemCount() )
354  numRows++;
355 
356  if ( numRows == 0 )
357  return itemGeometries;
358 
359  QVector<int> rowHeight( numRows );
360  QVector<int> colWidth( numColumns );
361 
362  layoutGrid( numColumns, rowHeight, colWidth );
363 
364  bool expandH, expandV;
365  expandH = expandingDirections() & Qt::Horizontal;
366  expandV = expandingDirections() & Qt::Vertical;
367 
368  if ( expandH || expandV )
369  stretchGrid( rect, numColumns, rowHeight, colWidth );
370 
371  const int maxColumns = d_data->maxColumns;
373  const QRect alignedRect = alignmentRect( rect );
375 
376  const int xOffset = expandH ? 0 : alignedRect.x();
377  const int yOffset = expandV ? 0 : alignedRect.y();
378 
379  QVector<int> colX( numColumns );
380  QVector<int> rowY( numRows );
381 
382  const int xySpace = spacing();
383 
384  const QMargins m = contentsMargins();
385 
386  rowY[0] = yOffset + m.top();
387  for ( uint r = 1; r < numRows; r++ )
388  rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace;
389 
390  colX[0] = xOffset + m.left();
391  for ( uint c = 1; c < numColumns; c++ )
392  colX[c] = colX[c-1] + colWidth[c-1] + xySpace;
393 
394  const int itemCount = d_data->itemList.size();
395  itemGeometries.reserve( itemCount );
396 
397  for ( int i = 0; i < itemCount; i++ )
398  {
399  const int row = i / numColumns;
400  const int col = i % numColumns;
401 
402  const QRect itemGeometry( colX[col], rowY[row],
403  colWidth[col], rowHeight[row] );
404  itemGeometries.append( itemGeometry );
405  }
406 
407  return itemGeometries;
408 }
409 
410 
421  QVector<int>& rowHeight, QVector<int>& colWidth ) const
422 {
423  if ( numColumns <= 0 )
424  return;
425 
426  if ( d_data->isDirty )
428 
429  for ( int index = 0; index < d_data->itemSizeHints.count(); index++ )
430  {
431  const int row = index / numColumns;
432  const int col = index % numColumns;
433 
434  const QSize &size = d_data->itemSizeHints[index];
435 
436  rowHeight[row] = ( col == 0 )
437  ? size.height() : qMax( rowHeight[row], size.height() );
438  colWidth[col] = ( row == 0 )
439  ? size.width() : qMax( colWidth[col], size.width() );
440  }
441 }
442 
448 {
449  return true;
450 }
451 
456 int QwtDynGridLayout::heightForWidth( int width ) const
457 {
458  if ( isEmpty() )
459  return 0;
460 
461  const uint numColumns = columnsForWidth( width );
462  uint numRows = itemCount() / numColumns;
463  if ( itemCount() % numColumns )
464  numRows++;
465 
466  QVector<int> rowHeight( numRows );
467  QVector<int> colWidth( numColumns );
468 
469  layoutGrid( numColumns, rowHeight, colWidth );
470 
471  const QMargins m = contentsMargins();
472 
473  int h = m.top() + m.bottom() + ( numRows - 1 ) * spacing();
474  for ( uint row = 0; row < numRows; row++ )
475  h += rowHeight[row];
476 
477  return h;
478 }
479 
492 void QwtDynGridLayout::stretchGrid( const QRect &rect,
493  uint numColumns, QVector<int>& rowHeight, QVector<int>& colWidth ) const
494 {
495  if ( numColumns == 0 || isEmpty() )
496  return;
497 
498  bool expandH, expandV;
499  expandH = expandingDirections() & Qt::Horizontal;
500  expandV = expandingDirections() & Qt::Vertical;
501 
502  const QMargins m = contentsMargins();
503 
504  if ( expandH )
505  {
506  int xDelta = rect.width() - m.left() - m.right() - ( numColumns - 1 ) * spacing();
507  for ( uint col = 0; col < numColumns; col++ )
508  xDelta -= colWidth[col];
509 
510  if ( xDelta > 0 )
511  {
512  for ( uint col = 0; col < numColumns; col++ )
513  {
514  const int space = xDelta / ( numColumns - col );
515  colWidth[col] += space;
516  xDelta -= space;
517  }
518  }
519  }
520 
521  if ( expandV )
522  {
523  uint numRows = itemCount() / numColumns;
524  if ( itemCount() % numColumns )
525  numRows++;
526 
527  int yDelta = rect.height() - m.top() - m.bottom() - ( numRows - 1 ) * spacing();
528  for ( uint row = 0; row < numRows; row++ )
529  yDelta -= rowHeight[row];
530 
531  if ( yDelta > 0 )
532  {
533  for ( uint row = 0; row < numRows; row++ )
534  {
535  const int space = yDelta / ( numRows - row );
536  rowHeight[row] += space;
537  yDelta -= space;
538  }
539  }
540  }
541 }
542 
552 {
553  if ( isEmpty() )
554  return QSize();
555 
556  uint numColumns = itemCount();
557  if ( d_data->maxColumns > 0 )
558  numColumns = qMin( d_data->maxColumns, numColumns );
559 
560  uint numRows = itemCount() / numColumns;
561  if ( itemCount() % numColumns )
562  numRows++;
563 
564  QVector<int> rowHeight( numRows );
565  QVector<int> colWidth( numColumns );
566 
567  layoutGrid( numColumns, rowHeight, colWidth );
568 
569  const QMargins m = contentsMargins();
570 
571  int h = m.top() + m.bottom() + ( numRows - 1 ) * spacing();
572  for ( uint row = 0; row < numRows; row++ )
573  h += rowHeight[row];
574 
575  int w = m.left() + m.right() + ( numColumns - 1 ) * spacing();
576  for ( uint col = 0; col < numColumns; col++ )
577  w += colWidth[col];
578 
579  return QSize( w, h );
580 }
581 
588 {
589  return d_data->numRows;
590 }
591 
598 {
599  return d_data->numColumns;
600 }
601 
602 #if QWT_MOC_INCLUDE
603 #include "moc_qwt_dyngrid_layout.cpp"
604 #endif
virtual int heightForWidth(int) const QWT_OVERRIDE
virtual int maxItemWidth() const
QwtDynGridLayout(QWidget *, int margin=0, int spacing=-1)
virtual uint columnsForWidth(int width) const
Calculate the number of columns for a given width.
virtual bool hasHeightForWidth() const QWT_OVERRIDE
PrivateData * d_data
virtual QLayoutItem * takeAt(int index) QWT_OVERRIDE
void stretchGrid(const QRect &rect, uint numColumns, QVector< int > &rowHeight, QVector< int > &colWidth) const
void setMaxColumns(uint maxColumns)
virtual QSize sizeHint() const QWT_OVERRIDE
int maxRowWidth(int numColumns) const
virtual QLayoutItem * itemAt(int index) const QWT_OVERRIDE
QList< QRect > layoutItems(const QRect &, uint numColumns) const
virtual Qt::Orientations expandingDirections() const QWT_OVERRIDE
Returns whether this layout can make use of more space than sizeHint().
void layoutGrid(uint numColumns, QVector< int > &rowHeight, QVector< int > &colWidth) const
QList< QLayoutItem * > itemList
virtual void addItem(QLayoutItem *) QWT_OVERRIDE
Add an item to the next free position.
MQTTClient c
Definition: test10.c:1656
virtual void invalidate() QWT_OVERRIDE
Invalidate all internal caches.
uint maxColumns() const
Return the upper limit for the number of columns.
virtual ~QwtDynGridLayout()
Destructor.
virtual bool isEmpty() const QWT_OVERRIDE
virtual void setGeometry(const QRect &) QWT_OVERRIDE
uint numColumns() const
virtual int count() const QWT_OVERRIDE
void setExpandingDirections(Qt::Orientations)


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10