Qt 4.8
qgridlayoutengine.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qglobal.h"
43 
44 #ifndef QT_NO_GRAPHICSVIEW
45 
46 #include <math.h>
47 
48 #include "qgraphicslayoutitem.h"
49 #include "qgridlayoutengine_p.h"
50 #include "qstyleoption.h"
51 #include "qvarlengtharray.h"
52 
53 #include <QtDebug>
54 #include <QtCore/qmath.h>
55 
57 
58 template <typename T>
59 static void insertOrRemoveItems(QVector<T> &items, int index, int delta)
60 {
61  int count = items.count();
62  if (index < count) {
63  if (delta > 0) {
64  items.insert(index, delta, T());
65  } else if (delta < 0) {
66  items.remove(index, qMin(-delta, count - index));
67  }
68  }
69 }
70 
71 static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired)
72 {
73  Q_ASSERT(sumDesired != 0.0);
74  return desired * qPow(sumAvailable / sumDesired, desired / sumDesired);
75 }
76 
77 static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize)
78 {
79  if (descent < 0.0)
80  return -1.0;
81 
82  Q_ASSERT(descent >= 0.0);
83  Q_ASSERT(ascent >= 0.0);
84  Q_ASSERT(targetSize >= ascent + descent);
85 
86  qreal extra = targetSize - (ascent + descent);
87  return descent + (extra / qreal(2.0));
88 }
89 
90 static qreal compare(const QGridLayoutBox &box1, const QGridLayoutBox &box2, int which)
91 {
92  qreal size1 = box1.q_sizes(which);
93  qreal size2 = box2.q_sizes(which);
94 
95  if (which == MaximumSize) {
96  return size2 - size1;
97  } else {
98  return size1 - size2;
99  }
100 }
101 
102 void QGridLayoutBox::add(const QGridLayoutBox &other, int stretch, qreal spacing)
103 {
104  Q_ASSERT(q_minimumDescent < 0.0);
105 
106  q_minimumSize += other.q_minimumSize + spacing;
107  q_preferredSize += other.q_preferredSize + spacing;
108  q_maximumSize += ((stretch == 0) ? other.q_preferredSize : other.q_maximumSize) + spacing;
109 }
110 
112 {
115 
118  qreal maxMax;
119  if (q_maximumSize == FLT_MAX && other.q_maximumSize != FLT_MAX)
120  maxMax = other.q_maximumSize;
121  else if (other.q_maximumSize == FLT_MAX && q_maximumSize != FLT_MAX)
122  maxMax = q_maximumSize;
123  else
124  maxMax = qMax(q_maximumSize, other.q_maximumSize);
125 
126  q_maximumSize = qMax(q_minimumSize, maxMax);
128  q_maximumSize);
129 }
130 
132 {
137 
138  Q_ASSERT((q_minimumDescent < 0.0) == (q_minimumAscent < 0.0));
139 }
140 
141 #ifdef QT_DEBUG
142 void QGridLayoutBox::dump(int indent) const
143 {
144  qDebug("%*sBox (%g <= %g <= %g [%g/%g])", indent, "", q_minimumSize, q_preferredSize,
146 }
147 #endif
148 
149 bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2)
150 {
151  for (int i = 0; i < NSizes; ++i) {
152  if (box1.q_sizes(i) != box2.q_sizes(i))
153  return false;
154  }
155  return box1.q_minimumDescent == box2.q_minimumDescent
156  && box1.q_minimumAscent == box2.q_minimumAscent;
157 }
158 
160 {
161  ignore.fill(false, count);
162  boxes.fill(QGridLayoutBox(), count);
163  multiCellMap.clear();
164  stretches.fill(0, count);
165  spacings.fill(0.0, count);
166  hasIgnoreFlag = false;
167 }
168 
170 {
171  MultiCellMap::const_iterator i = multiCellMap.constBegin();
172  for (; i != multiCellMap.constEnd(); ++i) {
173  int start = i.key().first;
174  int span = i.key().second;
175  int end = start + span;
176  const QGridLayoutBox &box = i.value().q_box;
177  int stretch = i.value().q_stretch;
178 
179  QGridLayoutBox totalBox = this->totalBox(start, end);
180  QVarLengthArray<QGridLayoutBox> extras(span);
181  QVarLengthArray<qreal> dummy(span);
182  QVarLengthArray<qreal> newSizes(span);
183 
184  for (int j = 0; j < NSizes; ++j) {
185  qreal extra = compare(box, totalBox, j);
186  if (extra > 0.0) {
187  calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(),
188  0, totalBox, rowInfo);
189 
190  for (int k = 0; k < span; ++k)
191  extras[k].q_sizes(j) = newSizes[k];
192  }
193  }
194 
195  for (int k = 0; k < span; ++k) {
196  boxes[start + k].combine(extras[k]);
197  if (stretch != 0)
198  stretches[start + k] = qMax(stretches[start + k], stretch);
199  }
200  }
201  multiCellMap.clear();
202 }
203 
205  qreal *sizes, qreal *descents,
206  const QGridLayoutBox &totalBox,
207  const QGridLayoutRowInfo &rowInfo)
208 {
209  Q_ASSERT(end > start);
210 
211  targetSize = qMax(totalBox.q_minimumSize, targetSize);
212 
213  int n = end - start;
214  QVarLengthArray<qreal> newSizes(n);
215  QVarLengthArray<qreal> factors(n);
216  qreal sumFactors = 0.0;
217  int sumStretches = 0;
218  qreal sumAvailable;
219 
220  for (int i = 0; i < n; ++i) {
221  if (stretches[start + i] > 0)
222  sumStretches += stretches[start + i];
223  }
224 
225  if (targetSize < totalBox.q_preferredSize) {
226  stealBox(start, end, MinimumSize, positions, sizes);
227 
228  sumAvailable = targetSize - totalBox.q_minimumSize;
229  if (sumAvailable > 0.0) {
230  qreal sumDesired = totalBox.q_preferredSize - totalBox.q_minimumSize;
231 
232  for (int i = 0; i < n; ++i) {
233  if (ignore.testBit(start + i)) {
234  factors[i] = 0.0;
235  continue;
236  }
237 
238  const QGridLayoutBox &box = boxes.at(start + i);
239  qreal desired = box.q_preferredSize - box.q_minimumSize;
240  factors[i] = growthFactorBelowPreferredSize(desired, sumAvailable, sumDesired);
241  sumFactors += factors[i];
242  }
243 
244  for (int i = 0; i < n; ++i) {
245  Q_ASSERT(sumFactors > 0.0);
246  qreal delta = sumAvailable * factors[i] / sumFactors;
247  newSizes[i] = sizes[i] + delta;
248  }
249  }
250  } else {
251  bool isLargerThanMaximum = (targetSize > totalBox.q_maximumSize);
252  if (isLargerThanMaximum) {
253  stealBox(start, end, MaximumSize, positions, sizes);
254  sumAvailable = targetSize - totalBox.q_maximumSize;
255  } else {
256  stealBox(start, end, PreferredSize, positions, sizes);
257  sumAvailable = targetSize - totalBox.q_preferredSize;
258  }
259 
260  if (sumAvailable > 0.0) {
261  qreal sumCurrentAvailable = sumAvailable;
262  bool somethingHasAMaximumSize = false;
263 
264  qreal sumSizes = 0.0;
265  for (int i = 0; i < n; ++i)
266  sumSizes += sizes[i];
267 
268  for (int i = 0; i < n; ++i) {
269  if (ignore.testBit(start + i)) {
270  newSizes[i] = 0.0;
271  factors[i] = 0.0;
272  continue;
273  }
274 
275  const QGridLayoutBox &box = boxes.at(start + i);
276  qreal boxSize;
277 
278  qreal desired;
279  if (isLargerThanMaximum) {
280  boxSize = box.q_maximumSize;
281  desired = rowInfo.boxes.value(start + i).q_maximumSize - boxSize;
282  } else {
283  boxSize = box.q_preferredSize;
284  desired = box.q_maximumSize - boxSize;
285  }
286  if (desired == 0.0) {
287  newSizes[i] = sizes[i];
288  factors[i] = 0.0;
289  } else {
290  Q_ASSERT(desired > 0.0);
291 
292  int stretch = stretches[start + i];
293  if (sumStretches == 0) {
294  if (hasIgnoreFlag) {
295  factors[i] = (stretch < 0) ? qreal(1.0) : qreal(0.0);
296  } else {
297  factors[i] = (stretch < 0) ? sizes[i] : qreal(0.0);
298  }
299  } else if (stretch == sumStretches) {
300  factors[i] = 1.0;
301  } else if (stretch <= 0) {
302  factors[i] = 0.0;
303  } else {
304  qreal ultimateSize;
305  qreal ultimateSumSizes;
306  qreal x = ((stretch * sumSizes)
307  - (sumStretches * boxSize))
308  / (sumStretches - stretch);
309  if (x >= 0.0) {
310  ultimateSize = boxSize + x;
311  ultimateSumSizes = sumSizes + x;
312  } else {
313  ultimateSize = boxSize;
314  ultimateSumSizes = (sumStretches * boxSize)
315  / stretch;
316  }
317 
318  /*
319  We multiply these by 1.5 to give some space for a smooth transition
320  (at the expense of the stretch factors, which are not fully respected
321  during the transition).
322  */
323  ultimateSize = ultimateSize * 3 / 2;
324  ultimateSumSizes = ultimateSumSizes * 3 / 2;
325 
326  qreal beta = ultimateSumSizes - sumSizes;
327  if (!beta) {
328  factors[i] = 1;
329  } else {
330  qreal alpha = qMin(sumCurrentAvailable, beta);
331  qreal ultimateFactor = (stretch * ultimateSumSizes / sumStretches)
332  - (boxSize);
333  qreal transitionalFactor = sumCurrentAvailable * (ultimateSize - boxSize) / beta;
334 
335  factors[i] = ((alpha * ultimateFactor)
336  + ((beta - alpha) * transitionalFactor)) / beta;
337  }
338 
339  }
340  sumFactors += factors[i];
341  if (desired < sumCurrentAvailable)
342  somethingHasAMaximumSize = true;
343 
344  newSizes[i] = -1.0;
345  }
346  }
347 
348  bool keepGoing = somethingHasAMaximumSize;
349  while (keepGoing) {
350  keepGoing = false;
351 
352  for (int i = 0; i < n; ++i) {
353  if (newSizes[i] >= 0.0)
354  continue;
355 
356  qreal maxBoxSize;
357  if (isLargerThanMaximum)
358  maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize;
359  else
360  maxBoxSize = boxes.at(start + i).q_maximumSize;
361 
362  qreal avail = sumCurrentAvailable * factors[i] / sumFactors;
363  if (sizes[i] + avail >= maxBoxSize) {
364  newSizes[i] = maxBoxSize;
365  sumCurrentAvailable -= maxBoxSize - sizes[i];
366  sumFactors -= factors[i];
367  keepGoing = (sumCurrentAvailable > 0.0);
368  if (!keepGoing)
369  break;
370  }
371  }
372  }
373 
374  for (int i = 0; i < n; ++i) {
375  if (newSizes[i] < 0.0) {
376  qreal delta = (sumFactors == 0.0) ? qreal(0.0)
377  : sumCurrentAvailable * factors[i] / sumFactors;
378  newSizes[i] = sizes[i] + delta;
379  }
380  }
381  }
382  }
383 
384  if (sumAvailable > 0) {
385  qreal offset = 0;
386  for (int i = 0; i < n; ++i) {
387  qreal delta = newSizes[i] - sizes[i];
388  positions[i] += offset;
389  sizes[i] += delta;
390  offset += delta;
391  }
392 
393 #if 0 // some "pixel allocation"
394  int surplus = targetSize - (positions[n - 1] + sizes[n - 1]);
395  Q_ASSERT(surplus >= 0 && surplus <= n);
396 
397  int prevSurplus = -1;
398  while (surplus > 0 && surplus != prevSurplus) {
399  prevSurplus = surplus;
400 
401  int offset = 0;
402  for (int i = 0; i < n; ++i) {
403  const QGridLayoutBox &box = boxes.at(start + i);
404  int delta = (!ignore.testBit(start + i) && surplus > 0
405  && factors[i] > 0 && sizes[i] < box.q_maximumSize)
406  ? 1 : 0;
407 
408  positions[i] += offset;
409  sizes[i] += delta;
410  offset += delta;
411  surplus -= delta;
412  }
413  }
414  Q_ASSERT(surplus == 0);
415 #endif
416  }
417 
418  if (descents) {
419  for (int i = 0; i < n; ++i) {
420  if (ignore.testBit(start + i))
421  continue;
422  const QGridLayoutBox &box = boxes.at(start + i);
423  descents[i] = fixedDescent(box.q_minimumDescent, box.q_minimumAscent, sizes[i]);
424  }
425  }
426 }
427 
429 {
430  QGridLayoutBox result;
431  if (start < end) {
432  result.q_maximumSize = 0.0;
433  qreal nextSpacing = 0.0;
434  for (int i = start; i < end; ++i) {
435  if (ignore.testBit(i))
436  continue;
437  result.add(boxes.at(i), stretches.at(i), nextSpacing);
438  nextSpacing = spacings.at(i);
439  }
440  }
441  return result;
442 }
443 
444 void QGridLayoutRowData::stealBox(int start, int end, int which, qreal *positions, qreal *sizes)
445 {
446  qreal offset = 0.0;
447  qreal nextSpacing = 0.0;
448 
449  for (int i = start; i < end; ++i) {
450  qreal avail = 0.0;
451 
452  if (!ignore.testBit(i)) {
453  const QGridLayoutBox &box = boxes.at(i);
454  avail = box.q_sizes(which);
455  offset += nextSpacing;
456  nextSpacing = spacings.at(i);
457  }
458 
459  *positions++ = offset;
460  *sizes++ = avail;
461  offset += avail;
462  }
463 }
464 
465 #ifdef QT_DEBUG
466 void QGridLayoutRowData::dump(int indent) const
467 {
468  qDebug("%*sData", indent, "");
469 
470  for (int i = 0; i < ignore.count(); ++i) {
471  qDebug("%*s Row %d (stretch %d, spacing %g)", indent, "", i, stretches.at(i),
472  spacings.at(i));
473  if (ignore.testBit(i))
474  qDebug("%*s Ignored", indent, "");
475  boxes.at(i).dump(indent + 2);
476  }
477 
478  MultiCellMap::const_iterator it = multiCellMap.constBegin();
479  while (it != multiCellMap.constEnd()) {
480  qDebug("%*s Multi-cell entry <%d, %d> (stretch %d)", indent, "", it.key().first,
481  it.key().second, it.value().q_stretch);
482  it.value().q_box.dump(indent + 2);
483  }
484 }
485 #endif
486 
488  int row, int column, int rowSpan, int columnSpan,
489  Qt::Alignment alignment, int itemAtIndex)
490  : q_engine(engine), q_layoutItem(layoutItem), q_alignment(alignment)
491 {
492  q_firstRows[Hor] = column;
493  q_firstRows[Ver] = row;
496  q_stretches[Hor] = -1;
497  q_stretches[Ver] = -1;
498 
499  q_engine->insertItem(this, itemAtIndex);
500 }
501 
503 {
504  return q_firstRows[orientation == Qt::Vertical];
505 }
506 
508 {
509  return q_firstRows[orientation == Qt::Horizontal];
510 }
511 
513 {
514  return firstRow(orientation) + rowSpan(orientation) - 1;
515 }
516 
518 {
519  return firstColumn(orientation) + columnSpan(orientation) - 1;
520 }
521 
523 {
524  return q_rowSpans[orientation == Qt::Vertical];
525 }
526 
528 {
529  return q_rowSpans[orientation == Qt::Horizontal];
530 }
531 
533 {
534  q_firstRows[orientation == Qt::Vertical] = row;
535 }
536 
538 {
539  q_rowSpans[orientation == Qt::Vertical] = rowSpan;
540 }
541 
543 {
544  int stretch = q_stretches[orientation == Qt::Vertical];
545  if (stretch >= 0)
546  return stretch;
547 
548  QSizePolicy::Policy policy = sizePolicy(orientation);
549 
550  if (policy & QSizePolicy::ExpandFlag) {
551  return 1;
552  } else if (policy & QSizePolicy::GrowFlag) {
553  return -1; // because we max it up
554  } else {
555  return 0;
556  }
557 }
558 
560 {
561  Q_ASSERT(stretch >= 0); // ### deal with too big stretches
562  q_stretches[orientation == Qt::Vertical] = stretch;
563 }
564 
566 {
568  return (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy()
569  : sizePolicy.verticalPolicy();
570 }
571 
572 /*
573  returns true if the size policy returns true for either hasHeightForWidth()
574  or hasWidthForHeight()
575  */
577 {
580 }
581 
583 {
584  if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth())
585  return Qt::Vertical;
586  else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight())
587  return Qt::Horizontal;
588 }
589 
590 QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const
591 {
592  return q_layoutItem->sizePolicy().controlType();
593 }
594 
595 QSizeF QGridLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
596 {
597  return q_layoutItem->effectiveSizeHint(which, constraint);
598 }
599 
601 {
602  QGridLayoutBox result;
603  QSizePolicy::Policy policy = sizePolicy(orientation);
604 
605  if (orientation == Qt::Horizontal) {
606  QSizeF constraintSize(-1.0, constraint);
607 
608  result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).width();
609 
610  if (policy & QSizePolicy::ShrinkFlag) {
611  result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).width();
612  } else {
613  result.q_minimumSize = result.q_preferredSize;
614  }
615 
617  result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).width();
618  } else {
619  result.q_maximumSize = result.q_preferredSize;
620  }
621  } else {
622  QSizeF constraintSize(constraint, -1.0);
623 
624  result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).height();
625 
626  if (policy & QSizePolicy::ShrinkFlag) {
627  result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).height();
628  } else {
629  result.q_minimumSize = result.q_preferredSize;
630  }
631 
633  result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).height();
634  } else {
635  result.q_maximumSize = result.q_preferredSize;
636  }
637 
638  result.q_minimumDescent = sizeHint(Qt::MinimumDescent, constraintSize).height();
639  if (result.q_minimumDescent >= 0.0)
640  result.q_minimumAscent = result.q_minimumSize - result.q_minimumDescent;
641  }
642  if (policy & QSizePolicy::IgnoreFlag)
643  result.q_preferredSize = result.q_minimumSize;
644 
645  return result;
646 }
647 
649  qreal rowDescent) const
650 {
651  rowDescent = -1.0; // ### This disables the descent
652 
654  if (vBox.q_minimumDescent < 0.0 || rowDescent < 0.0) {
655  qreal cellWidth = width;
656  qreal cellHeight = height;
657 
658 
659  QSizeF size = effectiveMaxSize(QSizeF(-1,-1));
660  if (hasDynamicConstraint()) {
662  if (size.width() > cellWidth)
663  size = effectiveMaxSize(QSizeF(cellWidth, -1));
664  } else if (size.height() > cellHeight) {
665  size = effectiveMaxSize(QSizeF(-1, cellHeight));
666  }
667  }
668  size = size.boundedTo(QSizeF(cellWidth, cellHeight));
669  width = size.width();
670  height = size.height();
671 
672  Qt::Alignment align = q_engine->effectiveAlignment(this);
673  switch (align & Qt::AlignHorizontal_Mask) {
674  case Qt::AlignHCenter:
675  x += (cellWidth - width)/2;
676  break;
677  case Qt::AlignRight:
678  x += cellWidth - width;
679  break;
680  default:
681  break;
682  }
683  switch (align & Qt::AlignVertical_Mask) {
684  case Qt::AlignVCenter:
685  y += (cellHeight - height)/2;
686  break;
687  case Qt::AlignBottom:
688  y += cellHeight - height;
689  break;
690  default:
691  break;
692  }
693  return QRectF(x, y, width, height);
694  } else {
695  qreal descent = vBox.q_minimumDescent;
696  qreal ascent = vBox.q_minimumSize - descent;
697  return QRectF(x, y + height - rowDescent - ascent, width, ascent + descent);
698  }
699 }
700 
702 {
703  q_layoutItem->setGeometry(rect);
704 }
705 
707 {
709  qSwap(q_rowSpans[Hor], q_rowSpans[Ver]);
710  qSwap(q_stretches[Hor], q_stretches[Ver]);
711 }
712 
713 void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation)
714 {
715  int oldFirstRow = firstRow(orientation);
716  if (oldFirstRow >= row) {
717  setFirstRow(oldFirstRow + delta, orientation);
718  } else if (lastRow(orientation) >= row) {
719  setRowSpan(rowSpan(orientation) + delta, orientation);
720  }
721 }
731 {
732  QSizeF size = constraint;
735  if (!vGrow || !hGrow) {
736  QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint);
737  if (!vGrow)
738  size.setHeight(pref.height());
739  if (!hGrow)
740  size.setWidth(pref.width());
741  }
742 
743  if (!size.isValid()) {
745  if (size.width() == -1)
746  size.setWidth(maxSize.width());
747  if (size.height() == -1)
748  size.setHeight(maxSize.height());
749  }
750  return size;
751 }
752 
753 #ifdef QT_DEBUG
754 void QGridLayoutItem::dump(int indent) const
755 {
756  qDebug("%*s%p (%d, %d) %d x %d", indent, "", q_layoutItem, firstRow(), firstColumn(),
757  rowSpan(), columnSpan());
758 
759  if (q_stretches[Hor] >= 0)
760  qDebug("%*s Horizontal stretch: %d", indent, "", q_stretches[Hor]);
761  if (q_stretches[Ver] >= 0)
762  qDebug("%*s Vertical stretch: %d", indent, "", q_stretches[Ver]);
763  if (q_alignment != 0)
764  qDebug("%*s Alignment: %x", indent, "", uint(q_alignment));
765  qDebug("%*s Horizontal size policy: %x Vertical size policy: %x",
767 }
768 #endif
769 
771 {
772  count += delta;
773 
774  insertOrRemoveItems(stretches, row, delta);
775  insertOrRemoveItems(spacings, row, delta);
776  insertOrRemoveItems(alignments, row, delta);
777  insertOrRemoveItems(boxes, row, delta);
778 }
779 
780 #ifdef QT_DEBUG
781 void QGridLayoutRowInfo::dump(int indent) const
782 {
783  qDebug("%*sInfo (count: %d)", indent, "", count);
784  for (int i = 0; i < count; ++i) {
785  QString message;
786 
787  if (stretches.value(i).value() >= 0)
788  message += QString::fromAscii(" stretch %1").arg(stretches.value(i).value());
789  if (spacings.value(i).value() >= 0.0)
790  message += QString::fromAscii(" spacing %1").arg(spacings.value(i).value());
791  if (alignments.value(i) != 0)
792  message += QString::fromAscii(" alignment %1").arg(int(alignments.value(i)), 16);
793 
794  if (!message.isEmpty() || boxes.value(i) != QGridLayoutBox()) {
795  qDebug("%*s Row %d:%s", indent, "", i, qPrintable(message));
796  if (boxes.value(i) != QGridLayoutBox())
797  boxes.value(i).dump(indent + 1);
798  }
799  }
800 }
801 #endif
802 
804 {
805  m_visualDirection = Qt::LeftToRight;
806  invalidate();
807 }
808 
810 {
811  return q_infos[orientation == Qt::Vertical].count;
812 }
813 
815 {
816  return q_infos[orientation == Qt::Horizontal].count;
817 }
818 
820 {
821  return q_items.count();
822 }
823 
825 {
826  Q_ASSERT(index >= 0 && index < itemCount());
827  return q_items.at(index);
828 }
829 
831 {
832  for (int i = 0; i < q_items.size(); ++i) {
833  if (item == q_items.at(i)->layoutItem())
834  return i;
835  }
836  return -1;
837 }
838 
840 {
841  ensureEffectiveFirstAndLastRows();
842  return q_cachedEffectiveFirstRows[orientation == Qt::Vertical];
843 }
844 
846 {
847  ensureEffectiveFirstAndLastRows();
848  return q_cachedEffectiveLastRows[orientation == Qt::Vertical];
849 }
850 
851 void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations)
852 {
853  Q_ASSERT(spacing >= 0.0);
854  if (orientations & Qt::Horizontal)
855  q_defaultSpacings[Hor].setUserValue(spacing);
856  if (orientations & Qt::Vertical)
857  q_defaultSpacings[Ver].setUserValue(spacing);
858 
859  invalidate();
860 }
861 
863 {
864  if (q_defaultSpacings[orientation == Qt::Vertical].isDefault()) {
865  QStyle *style = styleInfo.style();
866  QStyleOption option;
867  option.initFrom(styleInfo.widget());
868  qreal defaultSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing
869  : QStyle::PM_LayoutHorizontalSpacing, &option, styleInfo.widget());
870  q_defaultSpacings[orientation == Qt::Vertical].setCachedValue(defaultSpacing);
871  }
872  return q_defaultSpacings[orientation == Qt::Vertical].value();
873 }
874 
875 void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation orientation)
876 {
877  Q_ASSERT(row >= 0);
878 
879  QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
880  if (row >= rowInfo.spacings.count())
881  rowInfo.spacings.resize(row + 1);
882  if (spacing >= 0)
883  rowInfo.spacings[row].setUserValue(spacing);
884  else
885  rowInfo.spacings[row] = QLayoutParameter<qreal>();
886  invalidate();
887 }
888 
890 {
891  QLayoutParameter<qreal> spacing = q_infos[orientation == Qt::Vertical].spacings.value(row);
892  if (!spacing.isDefault())
893  return spacing.value();
894  return q_defaultSpacings[orientation == Qt::Vertical].value();
895 }
896 
897 void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientation orientation)
898 {
899  Q_ASSERT(row >= 0);
900  Q_ASSERT(stretch >= 0);
901 
902  maybeExpandGrid(row, -1, orientation);
903 
904  QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
905  if (row >= rowInfo.stretches.count())
906  rowInfo.stretches.resize(row + 1);
907  rowInfo.stretches[row].setUserValue(stretch);
908 }
909 
911 {
912  QStretchParameter stretch = q_infos[orientation == Qt::Vertical].stretches.value(row);
913  if (!stretch.isDefault())
914  return stretch.value();
915  return 0;
916 }
917 
919  Qt::Orientation orientation)
920 {
921  Q_ASSERT(stretch >= 0);
922 
923  if (QGridLayoutItem *item = findLayoutItem(layoutItem))
924  item->setStretchFactor(stretch, orientation);
925 }
926 
928 {
929  if (QGridLayoutItem *item = findLayoutItem(layoutItem))
930  return item->stretchFactor(orientation);
931  return 0;
932 }
933 
935  Qt::Orientation orientation)
936 {
937  Q_ASSERT(row >= 0);
938  Q_ASSERT(size >= 0.0);
939 
940  maybeExpandGrid(row, -1, orientation);
941 
942  QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
943  if (row >= rowInfo.boxes.count())
944  rowInfo.boxes.resize(row + 1);
945  rowInfo.boxes[row].q_sizes(which) = size;
946 }
947 
949 {
950  return q_infos[orientation == Qt::Vertical].boxes.value(row).q_sizes(which);
951 }
952 
953 void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment,
954  Qt::Orientation orientation)
955 {
956  Q_ASSERT(row >= 0);
957 
958  maybeExpandGrid(row, -1, orientation);
959 
960  QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
961  if (row >= rowInfo.alignments.count())
962  rowInfo.alignments.resize(row + 1);
963  rowInfo.alignments[row] = alignment;
964 }
965 
966 Qt::Alignment QGridLayoutEngine::rowAlignment(int row, Qt::Orientation orientation) const
967 {
968  Q_ASSERT(row >= 0);
969  return q_infos[orientation == Qt::Vertical].alignments.value(row);
970 }
971 
973 {
974  if (QGridLayoutItem *item = findLayoutItem(layoutItem))
975  item->setAlignment(alignment);
976  invalidate();
977 }
978 
980 {
981  if (QGridLayoutItem *item = findLayoutItem(layoutItem))
982  return item->alignment();
983  return 0;
984 }
985 
987 {
988  Qt::Alignment align = layoutItem->alignment();
989  if (!(align & Qt::AlignVertical_Mask)) {
990  // no vertical alignment, respect the row alignment
991  int y = layoutItem->firstRow();
992  align |= (rowAlignment(y, Qt::Vertical) & Qt::AlignVertical_Mask);
993  }
994  if (!(align & Qt::AlignHorizontal_Mask)) {
995  // no horizontal alignment, respect the column alignment
996  int x = layoutItem->firstColumn();
997  align |= (rowAlignment(x, Qt::Horizontal) & Qt::AlignHorizontal_Mask);
998  }
999  return align;
1000 }
1001 
1012 {
1013  maybeExpandGrid(item->lastRow(), item->lastColumn());
1014 
1015  if (index == -1)
1016  q_items.append(item);
1017  else
1018  q_items.insert(index, item);
1019 
1020  for (int i = item->firstRow(); i <= item->lastRow(); ++i) {
1021  for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) {
1022  if (itemAt(i, j))
1023  qWarning("QGridLayoutEngine::addItem: Cell (%d, %d) already taken", i, j);
1024  setItemAt(i, j, item);
1025  }
1026  }
1027 }
1028 
1030 {
1031  insertItem(item, -1);
1032 }
1033 
1035 {
1036  Q_ASSERT(q_items.contains(item));
1037 
1038  invalidate();
1039 
1040  for (int i = item->firstRow(); i <= item->lastRow(); ++i) {
1041  for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) {
1042  if (itemAt(i, j) == item)
1043  setItemAt(i, j, 0);
1044  }
1045  }
1046 
1047  q_items.removeAll(item);
1048 }
1049 
1051 {
1052  for (int i = q_items.count() - 1; i >= 0; --i) {
1053  QGridLayoutItem *item = q_items.at(i);
1054  if (item->layoutItem() == layoutItem)
1055  return item;
1056  }
1057  return 0;
1058 }
1059 
1060 QGridLayoutItem *QGridLayoutEngine::itemAt(int row, int column, Qt::Orientation orientation) const
1061 {
1062  if (orientation == Qt::Horizontal)
1063  qSwap(row, column);
1064  if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount()))
1065  return 0;
1066  return q_grid.at((row * internalGridColumnCount()) + column);
1067 }
1068 
1070 {
1071  q_cachedEffectiveFirstRows[Hor] = -1;
1072  q_cachedEffectiveFirstRows[Ver] = -1;
1073  q_cachedEffectiveLastRows[Hor] = -1;
1074  q_cachedEffectiveLastRows[Ver] = -1;
1075  q_cachedDataForStyleInfo.invalidate();
1076  q_cachedSize = QSizeF();
1077  q_cachedConstraintOrientation = UnknownConstraint;
1078 }
1079 
1080 static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
1081 {
1082  if (dir == Qt::RightToLeft)
1083  geom->moveRight(contentsRect.right() - (geom->left() - contentsRect.left()));
1084 }
1085 
1087  const QRectF &contentsGeometry)
1088 {
1089  if (rowCount() < 1 || columnCount() < 1)
1090  return;
1091 
1092  ensureGeometries(styleInfo, contentsGeometry.size());
1093 
1094  for (int i = q_items.count() - 1; i >= 0; --i) {
1095  QGridLayoutItem *item = q_items.at(i);
1096 
1097  qreal x = q_xx[item->firstColumn()];
1098  qreal y = q_yy[item->firstRow()];
1099  qreal width = q_widths[item->lastColumn()];
1100  qreal height = q_heights[item->lastRow()];
1101 
1102  if (item->columnSpan() != 1)
1103  width += q_xx[item->lastColumn()] - x;
1104  if (item->rowSpan() != 1)
1105  height += q_yy[item->lastRow()] - y;
1106 
1107  QRectF geom = item->geometryWithin(contentsGeometry.x() + x, contentsGeometry.y() + y,
1108  width, height, q_descents[item->lastRow()]);
1109  visualRect(&geom, visualDirection(), contentsGeometry);
1110  item->setGeometry(geom);
1111  }
1112 }
1113 
1114 // ### candidate for deletion
1116  const QRectF &contentsGeometry, int row, int column, int rowSpan,
1117  int columnSpan) const
1118 {
1119  if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount())
1120  || rowSpan < 1 || columnSpan < 1)
1121  return QRectF();
1122 
1123  ensureGeometries(styleInfo, contentsGeometry.size());
1124 
1125  int lastColumn = qMax(column + columnSpan, columnCount()) - 1;
1126  int lastRow = qMax(row + rowSpan, rowCount()) - 1;
1127 
1128  qreal x = q_xx[column];
1129  qreal y = q_yy[row];
1130  qreal width = q_widths[lastColumn];
1131  qreal height = q_heights[lastRow];
1132 
1133  if (columnSpan != 1)
1134  width += q_xx[lastColumn] - x;
1135  if (rowSpan != 1)
1136  height += q_yy[lastRow] - y;
1137 
1138  return QRectF(contentsGeometry.x() + x, contentsGeometry.y() + y, width, height);
1139 }
1140 
1142  const QSizeF &constraint) const
1143 {
1144  QGridLayoutBox sizehint_totalBoxes[NOrientations];
1145 
1146  bool sizeHintCalculated = false;
1147 
1148  if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) {
1149  if (constraintOrientation() == Qt::Vertical) {
1150  //We have items whose height depends on their width
1151  if (constraint.width() >= 0) {
1152  if (q_cachedDataForStyleInfo != styleInfo)
1153  ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
1154  else
1155  sizehint_totalBoxes[Hor] = q_totalBoxes[Hor];
1156  QVector<qreal> sizehint_xx;
1157  QVector<qreal> sizehint_widths;
1158 
1159  sizehint_xx.resize(columnCount());
1160  sizehint_widths.resize(columnCount());
1161  qreal width = constraint.width();
1162  //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
1163  //constraints to find the row heights
1164  q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(),
1165  0, sizehint_totalBoxes[Hor], q_infos[Hor]);
1166  ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical);
1167  sizeHintCalculated = true;
1168  }
1169  } else {
1170  if (constraint.height() >= 0) {
1171  //We have items whose width depends on their height
1172  ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
1173  QVector<qreal> sizehint_yy;
1174  QVector<qreal> sizehint_heights;
1175 
1176  sizehint_yy.resize(rowCount());
1177  sizehint_heights.resize(rowCount());
1178  qreal height = constraint.height();
1179  //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
1180  //constraints to find the column widths
1181  q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(),
1182  0, sizehint_totalBoxes[Ver], q_infos[Ver]);
1183  ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal);
1184  sizeHintCalculated = true;
1185  }
1186  }
1187  }
1188 
1189  if (!sizeHintCalculated) {
1190  //No items with height for width, so it doesn't matter which order we do these in
1191  if (q_cachedDataForStyleInfo != styleInfo) {
1192  ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
1193  ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
1194  } else {
1195  sizehint_totalBoxes[Hor] = q_totalBoxes[Hor];
1196  sizehint_totalBoxes[Ver] = q_totalBoxes[Ver];
1197  }
1198  }
1199 
1200  switch (which) {
1201  case Qt::MinimumSize:
1202  return QSizeF(sizehint_totalBoxes[Hor].q_minimumSize, sizehint_totalBoxes[Ver].q_minimumSize);
1203  case Qt::PreferredSize:
1204  return QSizeF(sizehint_totalBoxes[Hor].q_preferredSize, sizehint_totalBoxes[Ver].q_preferredSize);
1205  case Qt::MaximumSize:
1206  return QSizeF(sizehint_totalBoxes[Hor].q_maximumSize, sizehint_totalBoxes[Ver].q_maximumSize);
1207  case Qt::MinimumDescent:
1208  return QSizeF(-1.0, sizehint_totalBoxes[Hor].q_minimumDescent); // ### doesn't work
1209  default:
1210  break;
1211  }
1212  return QSizeF();
1213 }
1214 
1215 QSizePolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const
1216 {
1217  Qt::Orientation orientation = (side == Top || side == Bottom) ? Qt::Vertical : Qt::Horizontal;
1218  int row = (side == Top || side == Left) ? effectiveFirstRow(orientation)
1219  : effectiveLastRow(orientation);
1220  QSizePolicy::ControlTypes result = 0;
1221 
1222  for (int column = columnCount(orientation) - 1; column >= 0; --column) {
1223  if (QGridLayoutItem *item = itemAt(row, column, orientation))
1224  result |= item->controlTypes(side);
1225  }
1226  return result;
1227 }
1228 
1230 {
1231  invalidate();
1232 
1233  for (int i = q_items.count() - 1; i >= 0; --i)
1234  q_items.at(i)->transpose();
1235 
1236  qSwap(q_defaultSpacings[Hor], q_defaultSpacings[Ver]);
1237  qSwap(q_infos[Hor], q_infos[Ver]);
1238 
1239  regenerateGrid();
1240 }
1241 
1243 {
1244  m_visualDirection = direction;
1245 }
1246 
1248 {
1249  return m_visualDirection;
1250 }
1251 
1252 #ifdef QT_DEBUG
1253 void QGridLayoutEngine::dump(int indent) const
1254 {
1255  qDebug("%*sEngine", indent, "");
1256 
1257  qDebug("%*s Items (%d)", indent, "", q_items.count());
1258  int i;
1259  for (i = 0; i < q_items.count(); ++i)
1260  q_items.at(i)->dump(indent + 2);
1261 
1262  qDebug("%*s Grid (%d x %d)", indent, "", internalGridRowCount(),
1263  internalGridColumnCount());
1264  for (int row = 0; row < internalGridRowCount(); ++row) {
1265  QString message = QLatin1String("[ ");
1266  for (int column = 0; column < internalGridColumnCount(); ++column) {
1267  message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3);
1268  message += QLatin1Char(' ');
1269  }
1270  message += QLatin1Char(']');
1271  qDebug("%*s %s", indent, "", qPrintable(message));
1272  }
1273 
1274  if (q_defaultSpacings[Hor].value() >= 0.0 || q_defaultSpacings[Ver].value() >= 0.0)
1275  qDebug("%*s Default spacings: %g %g", indent, "", q_defaultSpacings[Hor].value(),
1276  q_defaultSpacings[Ver].value());
1277 
1278  qDebug("%*s Column and row info", indent, "");
1279  q_infos[Hor].dump(indent + 2);
1280  q_infos[Ver].dump(indent + 2);
1281 
1282  qDebug("%*s Column and row data", indent, "");
1283  q_columnData.dump(indent + 2);
1284  q_rowData.dump(indent + 2);
1285 
1286  qDebug("%*s Geometries output", indent, "");
1287  QVector<qreal> *cellPos = &q_yy;
1288  for (int pass = 0; pass < 2; ++pass) {
1289  QString message;
1290  for (i = 0; i < cellPos->count(); ++i) {
1291  message += QLatin1String((message.isEmpty() ? "[" : ", "));
1292  message += QString::number(cellPos->at(i));
1293  }
1294  message += QLatin1Char(']');
1295  qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message));
1296  cellPos = &q_xx;
1297  }
1298 }
1299 #endif
1300 
1301 void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation orientation)
1302 {
1303  invalidate(); // ### move out of here?
1304 
1305  if (orientation == Qt::Horizontal)
1306  qSwap(row, column);
1307 
1308  if (row < rowCount() && column < columnCount())
1309  return;
1310 
1311  int oldGridRowCount = internalGridRowCount();
1312  int oldGridColumnCount = internalGridColumnCount();
1313 
1314  q_infos[Ver].count = qMax(row + 1, rowCount());
1315  q_infos[Hor].count = qMax(column + 1, columnCount());
1316 
1317  int newGridRowCount = internalGridRowCount();
1318  int newGridColumnCount = internalGridColumnCount();
1319 
1320  int newGridSize = newGridRowCount * newGridColumnCount;
1321  if (newGridSize != q_grid.count()) {
1322  q_grid.resize(newGridSize);
1323 
1324  if (newGridColumnCount != oldGridColumnCount) {
1325  for (int i = oldGridRowCount - 1; i >= 1; --i) {
1326  for (int j = oldGridColumnCount - 1; j >= 0; --j) {
1327  int oldIndex = (i * oldGridColumnCount) + j;
1328  int newIndex = (i * newGridColumnCount) + j;
1329 
1330  Q_ASSERT(newIndex > oldIndex);
1331  q_grid[newIndex] = q_grid[oldIndex];
1332  q_grid[oldIndex] = 0;
1333  }
1334  }
1335  }
1336  }
1337 }
1338 
1340 {
1341  q_grid.fill(0);
1342 
1343  for (int i = q_items.count() - 1; i >= 0; --i) {
1344  QGridLayoutItem *item = q_items.at(i);
1345 
1346  for (int j = item->firstRow(); j <= item->lastRow(); ++j) {
1347  for (int k = item->firstColumn(); k <= item->lastColumn(); ++k) {
1348  setItemAt(j, k, item);
1349  }
1350  }
1351  }
1352 }
1353 
1354 void QGridLayoutEngine::setItemAt(int row, int column, QGridLayoutItem *item)
1355 {
1356  Q_ASSERT(row >= 0 && row < rowCount());
1357  Q_ASSERT(column >= 0 && column < columnCount());
1358  q_grid[(row * internalGridColumnCount()) + column] = item;
1359 }
1360 
1361 void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation)
1362 {
1363  int oldRowCount = rowCount(orientation);
1364  Q_ASSERT(uint(row) <= uint(oldRowCount));
1365 
1366  invalidate();
1367 
1368  // appending rows (or columns) is easy
1369  if (row == oldRowCount && delta > 0) {
1370  maybeExpandGrid(oldRowCount + delta - 1, -1, orientation);
1371  return;
1372  }
1373 
1374  q_infos[orientation == Qt::Vertical].insertOrRemoveRows(row, delta);
1375 
1376  for (int i = q_items.count() - 1; i >= 0; --i)
1377  q_items.at(i)->insertOrRemoveRows(row, delta, orientation);
1378 
1379  q_grid.resize(internalGridRowCount() * internalGridColumnCount());
1380  regenerateGrid();
1381 }
1382 
1384  qreal *colPositions, qreal *colSizes,
1385  Qt::Orientation orientation) const
1386 {
1388  const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
1389  const QGridLayoutRowInfo &columnInfo = q_infos[orientation == Qt::Horizontal];
1390  LayoutSide top = (orientation == Qt::Vertical) ? Top : Left;
1391  LayoutSide bottom = (orientation == Qt::Vertical) ? Bottom : Right;
1392 
1393  QStyle *style = styleInfo.style();
1394  QStyleOption option;
1395  option.initFrom(styleInfo.widget());
1396 
1397  const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation == Qt::Vertical];
1398  qreal innerSpacing = 0.0;
1399  if (style)
1400  innerSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing
1402  &option, styleInfo.widget());
1403  if (innerSpacing >= 0.0)
1404  defaultSpacing.setCachedValue(innerSpacing);
1405 
1406  for (int row = 0; row < rowInfo.count; ++row) {
1407  bool rowIsEmpty = true;
1408  bool rowIsIdenticalToPrevious = (row > 0);
1409 
1410  for (int column = 0; column < columnInfo.count; ++column) {
1411  QGridLayoutItem *item = itemAt(row, column, orientation);
1412 
1413  if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation))
1414  rowIsIdenticalToPrevious = false;
1415 
1416  if (item)
1417  rowIsEmpty = false;
1418  }
1419 
1420  if ((rowIsEmpty || rowIsIdenticalToPrevious)
1421  && rowInfo.spacings.value(row).isDefault()
1422  && rowInfo.stretches.value(row).isDefault()
1423  && rowInfo.boxes.value(row) == QGridLayoutBox())
1424  rowData->ignore.setBit(row, true);
1425 
1426  if (rowInfo.spacings.value(row).isUser()) {
1427  rowData->spacings[row] = rowInfo.spacings.at(row).value();
1428  } else if (!defaultSpacing.isDefault()) {
1429  rowData->spacings[row] = defaultSpacing.value();
1430  }
1431 
1432  rowData->stretches[row] = rowInfo.stretches.value(row).value();
1433  }
1434 
1435  struct RowAdHocData {
1436  int q_row;
1437  unsigned int q_hasButtons : 8;
1438  unsigned int q_hasNonButtons : 8;
1439 
1440  inline RowAdHocData() : q_row(-1), q_hasButtons(false), q_hasNonButtons(false) {}
1441  inline void init(int row) {
1442  this->q_row = row;
1443  q_hasButtons = false;
1444  q_hasNonButtons = false;
1445  }
1446  inline bool hasOnlyButtons() const { return q_hasButtons && !q_hasNonButtons; }
1447  inline bool hasOnlyNonButtons() const { return q_hasNonButtons && !q_hasButtons; }
1448  };
1449  RowAdHocData lastRowAdHocData;
1450  RowAdHocData nextToLastRowAdHocData;
1451  RowAdHocData nextToNextToLastRowAdHocData;
1452 
1453  rowData->hasIgnoreFlag = false;
1454  for (int row = 0; row < rowInfo.count; ++row) {
1455  if (rowData->ignore.testBit(row))
1456  continue;
1457 
1458  QGridLayoutBox &rowBox = rowData->boxes[row];
1459  if (option.state & QStyle::State_Window) {
1460  nextToNextToLastRowAdHocData = nextToLastRowAdHocData;
1461  nextToLastRowAdHocData = lastRowAdHocData;
1462  lastRowAdHocData.init(row);
1463  }
1464 
1465  bool userRowStretch = rowInfo.stretches.value(row).isUser();
1466  int &rowStretch = rowData->stretches[row];
1467 
1468  bool hasIgnoreFlag = true;
1469  for (int column = 0; column < columnInfo.count; ++column) {
1470  QGridLayoutItem *item = itemAt(row, column, orientation);
1471  if (item) {
1472  int itemRow = item->firstRow(orientation);
1473  int itemColumn = item->firstColumn(orientation);
1474 
1475  if (itemRow == row && itemColumn == column) {
1476  int itemStretch = item->stretchFactor(orientation);
1477  if (!(item->sizePolicy(orientation) & QSizePolicy::IgnoreFlag))
1478  hasIgnoreFlag = false;
1479  int itemRowSpan = item->rowSpan(orientation);
1480 
1481  int effectiveRowSpan = 1;
1482  for (int i = 1; i < itemRowSpan; ++i) {
1483  if (!rowData->ignore.testBit(i + itemRow))
1484  ++effectiveRowSpan;
1485  }
1486 
1488  if (effectiveRowSpan == 1) {
1489  box = &rowBox;
1490  if (!userRowStretch && itemStretch != 0)
1491  rowStretch = qMax(rowStretch, itemStretch);
1492  } else {
1493  QGridLayoutMultiCellData &multiCell =
1494  rowData->multiCellMap[qMakePair(row, effectiveRowSpan)];
1495  box = &multiCell.q_box;
1496  multiCell.q_stretch = itemStretch;
1497  }
1498  // Items with constraints need to be passed the constraint
1499  if (colSizes && colPositions && item->hasDynamicConstraint() && orientation == item->dynamicConstraintOrientation()) {
1500  /* Get the width of the item by summing up the widths of the columns that it spans.
1501  * We need to have already calculated the widths of the columns by calling
1502  * q_columns->calculateGeometries() before hand and passing the value in the colSizes
1503  * and colPositions parameters.
1504  * The variable name is still colSizes even when it actually has the row sizes
1505  */
1506  qreal length = colSizes[item->lastColumn(orientation)];
1507  if (item->columnSpan(orientation) != 1)
1508  length += colPositions[item->lastColumn(orientation)] - colPositions[item->firstColumn(orientation)];
1509  box->combine(item->box(orientation, length));
1510  } else {
1511  box->combine(item->box(orientation));
1512  }
1513 
1514  if (effectiveRowSpan == 1) {
1515  QSizePolicy::ControlTypes controls = item->controlTypes(top);
1516  if (controls & ButtonMask)
1517  lastRowAdHocData.q_hasButtons = true;
1518  if (controls & ~ButtonMask)
1519  lastRowAdHocData.q_hasNonButtons = true;
1520  }
1521  }
1522  }
1523  }
1524  if (row < rowInfo.boxes.count()) {
1525  QGridLayoutBox rowBoxInfo = rowInfo.boxes.at(row);
1526  rowBoxInfo.normalize();
1527  rowBox.q_minimumSize = qMax(rowBox.q_minimumSize, rowBoxInfo.q_minimumSize);
1528  rowBox.q_maximumSize = qMax(rowBox.q_minimumSize,
1529  (rowBoxInfo.q_maximumSize != FLT_MAX ?
1530  rowBoxInfo.q_maximumSize : rowBox.q_maximumSize));
1531  rowBox.q_preferredSize = qBound(rowBox.q_minimumSize,
1532  qMax(rowBox.q_preferredSize, rowBoxInfo.q_preferredSize),
1533  rowBox.q_maximumSize);
1534  }
1535  if (hasIgnoreFlag)
1536  rowData->hasIgnoreFlag = true;
1537  }
1538 
1539  /*
1540  Heuristic: Detect button boxes that don't use QSizePolicy::ButtonBox.
1541  This is somewhat ad hoc but it usually does the trick.
1542  */
1543  bool lastRowIsButtonBox = (lastRowAdHocData.hasOnlyButtons()
1544  && nextToLastRowAdHocData.hasOnlyNonButtons());
1545  bool lastTwoRowsIsButtonBox = (lastRowAdHocData.hasOnlyButtons()
1546  && nextToLastRowAdHocData.hasOnlyButtons()
1547  && nextToNextToLastRowAdHocData.hasOnlyNonButtons()
1548  && orientation == Qt::Vertical);
1549 
1550  if (defaultSpacing.isDefault()) {
1551  int prevRow = -1;
1552  for (int row = 0; row < rowInfo.count; ++row) {
1553  if (rowData->ignore.testBit(row))
1554  continue;
1555 
1556  if (prevRow != -1 && !rowInfo.spacings.value(prevRow).isUser()) {
1557  qreal &rowSpacing = rowData->spacings[prevRow];
1558  for (int column = 0; column < columnInfo.count; ++column) {
1559  QGridLayoutItem *item1 = itemAt(prevRow, column, orientation);
1560  QGridLayoutItem *item2 = itemAt(row, column, orientation);
1561 
1562  if (item1 && item2 && item1 != item2) {
1563  QSizePolicy::ControlTypes controls1 = item1->controlTypes(bottom);
1564  QSizePolicy::ControlTypes controls2 = item2->controlTypes(top);
1565 
1566  if (controls2 & QSizePolicy::PushButton) {
1567  if ((row == nextToLastRowAdHocData.q_row && lastTwoRowsIsButtonBox)
1568  || (row == lastRowAdHocData.q_row && lastRowIsButtonBox)) {
1569  controls2 &= ~QSizePolicy::PushButton;
1570  controls2 |= QSizePolicy::ButtonBox;
1571  }
1572  }
1573 
1574  qreal spacing = style->combinedLayoutSpacing(controls1, controls2,
1575  orientation, &option,
1576  styleInfo.widget());
1577  if (orientation == Qt::Horizontal) {
1578  qreal width1 = rowData->boxes.at(prevRow).q_minimumSize;
1579  qreal width2 = rowData->boxes.at(row).q_minimumSize;
1580  QRectF rect1 = item1->geometryWithin(0.0, 0.0, width1, FLT_MAX, -1.0);
1581  QRectF rect2 = item2->geometryWithin(0.0, 0.0, width2, FLT_MAX, -1.0);
1582  spacing -= (width1 - (rect1.x() + rect1.width())) + rect2.x();
1583  } else {
1584  const QGridLayoutBox &box1 = rowData->boxes.at(prevRow);
1585  const QGridLayoutBox &box2 = rowData->boxes.at(row);
1586  qreal height1 = box1.q_minimumSize;
1587  qreal height2 = box2.q_minimumSize;
1588  qreal rowDescent1 = fixedDescent(box1.q_minimumDescent,
1589  box1.q_minimumAscent, height1);
1590  qreal rowDescent2 = fixedDescent(box2.q_minimumDescent,
1591  box2.q_minimumAscent, height2);
1592  QRectF rect1 = item1->geometryWithin(0.0, 0.0, FLT_MAX, height1,
1593  rowDescent1);
1594  QRectF rect2 = item2->geometryWithin(0.0, 0.0, FLT_MAX, height2,
1595  rowDescent2);
1596  spacing -= (height1 - (rect1.y() + rect1.height())) + rect2.y();
1597  }
1598  rowSpacing = qMax(spacing, rowSpacing);
1599  }
1600  }
1601  }
1602  prevRow = row;
1603  }
1604  } else if (lastRowIsButtonBox || lastTwoRowsIsButtonBox) {
1605  /*
1606  Even for styles that define a uniform spacing, we cheat a
1607  bit and use the window margin as the spacing. This
1608  significantly improves the look of dialogs.
1609  */
1610  int prevRow = lastRowIsButtonBox ? nextToLastRowAdHocData.q_row
1611  : nextToNextToLastRowAdHocData.q_row;
1612  if (!defaultSpacing.isUser() && !rowInfo.spacings.value(prevRow).isUser()) {
1613  qreal windowMargin = style->pixelMetric(orientation == Qt::Vertical
1616  &option, styleInfo.widget());
1617 
1618  qreal &rowSpacing = rowData->spacings[prevRow];
1619  rowSpacing = qMax(windowMargin, rowSpacing);
1620  }
1621  }
1622 }
1623 
1625 {
1626  if (q_cachedEffectiveFirstRows[Hor] == -1 && !q_items.isEmpty()) {
1627  int rowCount = this->rowCount();
1628  int columnCount = this->columnCount();
1629 
1630  q_cachedEffectiveFirstRows[Ver] = rowCount;
1631  q_cachedEffectiveFirstRows[Hor] = columnCount;
1632  q_cachedEffectiveLastRows[Ver] = -1;
1633  q_cachedEffectiveLastRows[Hor] = -1;
1634 
1635  for (int i = q_items.count() - 1; i >= 0; --i) {
1636  const QGridLayoutItem *item = q_items.at(i);
1637 
1638  for (int j = 0; j < NOrientations; ++j) {
1639  Qt::Orientation orientation = (j == Hor) ? Qt::Horizontal : Qt::Vertical;
1640  if (item->firstRow(orientation) < q_cachedEffectiveFirstRows[j])
1641  q_cachedEffectiveFirstRows[j] = item->firstRow(orientation);
1642  if (item->lastRow(orientation) > q_cachedEffectiveLastRows[j])
1643  q_cachedEffectiveLastRows[j] = item->lastRow(orientation);
1644  }
1645  }
1646  }
1647 }
1648 
1650  const QLayoutStyleInfo &styleInfo,
1651  qreal *colPositions, qreal *colSizes,
1652  Qt::Orientation orientation) const
1653 {
1654  rowData->reset(rowCount(orientation));
1655  fillRowData(rowData, styleInfo, colPositions, colSizes, orientation);
1656  const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
1657  rowData->distributeMultiCells(rowInfo);
1658  *totalBox = rowData->totalBox(0, rowCount(orientation));
1659  //We have items whose width depends on their height
1660 }
1661 
1667 {
1668  if (q_cachedConstraintOrientation == UnknownConstraint) {
1669  for (int i = q_items.count() - 1; i >= 0; --i) {
1670  QGridLayoutItem *item = q_items.at(i);
1671  if (item->hasDynamicConstraint()) {
1672  Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation();
1673  if (q_cachedConstraintOrientation == UnknownConstraint) {
1674  q_cachedConstraintOrientation = itemConstraintOrientation;
1675  } else if (q_cachedConstraintOrientation != itemConstraintOrientation) {
1676  q_cachedConstraintOrientation = UnfeasibleConstraint;
1677  qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and"
1678  " vertical constraint in the same layout");
1679  return false;
1680  }
1681  }
1682  }
1683  if (q_cachedConstraintOrientation == UnknownConstraint)
1684  q_cachedConstraintOrientation = NoConstraint;
1685  }
1686  return true;
1687 }
1688 
1690 {
1691  if (!ensureDynamicConstraint())
1692  return false;
1693  return q_cachedConstraintOrientation != NoConstraint;
1694 }
1695 
1696 /*
1697  * return value is only valid if hasConstraint() returns true
1698  */
1700 {
1701  (void)ensureDynamicConstraint();
1702  return (Qt::Orientation)q_cachedConstraintOrientation;
1703 }
1704 
1706  const QSizeF &size) const
1707 {
1708  if (q_cachedDataForStyleInfo == styleInfo && q_cachedSize == size)
1709  return;
1710 
1711  q_cachedDataForStyleInfo = styleInfo;
1712  q_cachedSize = size;
1713 
1714  q_xx.resize(columnCount());
1715  q_widths.resize(columnCount());
1716  q_yy.resize(rowCount());
1717  q_heights.resize(rowCount());
1718  q_descents.resize(rowCount());
1719 
1720  if (constraintOrientation() != Qt::Horizontal) {
1721  //We might have items whose width depends on their height
1722  ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
1723  //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
1724  //constraints to find the row heights
1725  q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
1726  0, q_totalBoxes[Hor], q_infos[Hor] );
1727  ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical);
1728  //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
1729  q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
1730  q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
1731  } else {
1732  //We have items whose height depends on their width
1733  ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
1734  //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
1735  //constraints to find the column widths
1736  q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
1737  q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
1738  ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal);
1739  //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
1740  q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
1741  0, q_totalBoxes[Hor], q_infos[Hor]);
1742  }
1743 }
1744 
1746 
1747 #endif //QT_NO_GRAPHICSVIEW
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
int q_firstRows[NOrientations]
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Returns the effective size hint for this QGraphicsLayoutItem.
virtual void setGeometry(const QRectF &rect)
This virtual function sets the geometry of the QGraphicsLayoutItem to rect, which is in parent coordi...
void setCachedValue(T value) const
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
qreal right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:527
void addItem(QGridLayoutItem *item)
static QGraphicsLayoutItemPrivate * get(QGraphicsLayoutItem *q)
void setRowStretchFactor(int row, int stretch, Qt::Orientation orientation=Qt::Vertical)
double qreal
Definition: qglobal.h:1193
Qt::Alignment effectiveAlignment(const QGridLayoutItem *layoutItem) const
void setSpacing(qreal spacing, Qt::Orientations orientations)
QGridLayoutEngine * q_engine
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
void setBit(int i)
Sets the bit at index position i to 1.
Definition: qbitarray.h:128
Qt::Orientation dynamicConstraintOrientation() const
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void distributeMultiCells(const QGridLayoutRowInfo &rowInfo)
bool ensureDynamicConstraint() const
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
void fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, qreal *colPositions, qreal *colSizes, Qt::Orientation orientation=Qt::Vertical) const
void setGeometry(const QRectF &rect)
void remove(int i)
Removes the element at index position i.
Definition: qvector.h:374
void removeItem(QGridLayoutItem *item)
int effectiveFirstRow(Qt::Orientation orientation=Qt::Vertical) const
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
#define it(className, varName)
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
void setRowSpan(int rowSpan, Qt::Orientation orientation=Qt::Vertical)
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
qreal width() const
Returns the width.
Definition: qsize.h:284
Qt::Alignment q_alignment
void dump(int indent=0) const
void ensureEffectiveFirstAndLastRows() const
qreal height() const
Returns the height.
Definition: qsize.h:287
qreal left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:525
static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired)
QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem *layoutItem, int row, int column, int rowSpan=1, int columnSpan=1, Qt::Alignment alignment=0, int itemAtIndex=-1)
static bool ignore(const char *test, const char *const *table)
Definition: qaxserver.cpp:660
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation=Qt::Vertical)
void dump(int indent=0) const
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool hasDynamicConstraint() const
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:281
void setWidth(qreal w)
Sets the width to the given width.
Definition: qsize.h:290
bool testBit(int i) const
Returns true if the bit at index position i is 1; otherwise returns false.
Definition: qbitarray.h:124
QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, const QSizeF &constraint) const
int effectiveLastRow(Qt::Orientation orientation=Qt::Vertical) const
void setRowSizeHint(Qt::SizeHint which, int row, qreal size, Qt::Orientation orientation=Qt::Vertical)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
QSizePolicy::ControlTypes controlTypes(LayoutSide side) const
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
void setVisualDirection(Qt::LayoutDirection direction)
void ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const
QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent) const
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
int rowStretchFactor(int row, Qt::Orientation orientation=Qt::Vertical) const
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
Q_CORE_EXPORT void qDebug(const char *,...)
QVector< Qt::Alignment > alignments
void insertOrRemoveRows(int row, int delta)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setAlignment(QGraphicsLayoutItem *layoutItem, Qt::Alignment alignment)
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const
QStyle * style() const
QVector< QGridLayoutBox > boxes
QVector< QStretchParameter > stretches
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static const QCssKnownValue positions[NumKnownPositionModes - 1]
Definition: qcssparser.cpp:329
T value(int i) const
Returns the value at index position i in the vector.
Definition: qvector.h:559
static bool init
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
LayoutDirection
Definition: qnamespace.h:1580
Q_CORE_EXPORT void qWarning(const char *,...)
unsigned int uint
Definition: qglobal.h:996
QVector< int > stretches
qreal spacing(const QLayoutStyleInfo &styleInfo, Qt::Orientation orientation) const
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts...
QGridLayoutBox totalBox(int start, int end) const
void add(const QGridLayoutBox &other, int stretch, qreal spacing)
QVector< QLayoutParameter< qreal > > spacings
Qt::Alignment alignment(QGraphicsLayoutItem *layoutItem) const
qreal qPow(qreal x, qreal y)
Definition: qmath.h:244
QGraphicsLayoutItem * layoutItem() const
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
static void insertOrRemoveItems(QVector< T > &items, int index, int delta)
QVector< qreal > spacings
void moveRight(qreal pos)
Moves the rectangle horizontally, leaving the rectangle&#39;s right edge at the given x coordinate...
Definition: qrect.h:693
void dump(int indent=0) const
void dump(int indent=0) const
void insert(int i, const T &t)
Inserts value at index position i in the vector.
Definition: qvector.h:362
QSizeF effectiveMaxSize(const QSizeF &constraint) const
bool hasDynamicConstraint() const
SizeHint
Definition: qnamespace.h:1708
int q_rowSpans[NOrientations]
void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, const QLayoutStyleInfo &styleInfo, qreal *colPositions, qreal *colSizes, Qt::Orientation orientation) const
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize)
void dump(int indent=0) const
QGridLayoutItem * itemAt(int index) const
int q_stretches[NOrientations]
QWidget * widget() const
QRectF cellRect(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry, int row, int column, int rowSpan, int columnSpan) const
qreal & q_sizes(int which)
QSizeF boundedTo(const QSizeF &) const
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition: qsize.h:350
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
QSizePolicy sizePolicy() const
Returns the current size policy.
void setItemAt(int row, int column, QGridLayoutItem *item)
void setFirstRow(int row, Qt::Orientation orientation=Qt::Vertical)
void setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, Qt::Orientation orientation)
Qt::Orientation constraintOrientation() const
void insertItem(QGridLayoutItem *item, int index)
The index is only used by QGraphicsLinearLayout to ensure that itemAt() reflects the order of visual ...
QGridLayoutBox box(Qt::Orientation orientation, qreal constraint=-1.0) const
Q_OUTOFLINE_TEMPLATE QPair< T1, T2 > qMakePair(const T1 &x, const T2 &y)
Definition: qpair.h:102
bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2)
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
void setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation)
void combine(const QGridLayoutBox &other)
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation=Qt::Vertical)
quint16 index
void stealBox(int start, int end, int which, qreal *positions, qreal *sizes)
Qt::Alignment alignment() const
void setHeight(qreal h)
Sets the height to the given height.
Definition: qsize.h:293
qreal rowSizeHint(Qt::SizeHint which, int row, Qt::Orientation orientation=Qt::Vertical) const
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
Qt::LayoutDirection visualDirection() const
int stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const
QSizePolicy::ControlTypes controlTypes(LayoutSide side) const
void calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, qreal *descents, const QGridLayoutBox &totalBox, const QGridLayoutRowInfo &rowInfo)
QVector< QGridLayoutBox > boxes
void setRowSpacing(int row, qreal spacing, Qt::Orientation orientation=Qt::Vertical)
QGridLayoutItem * findLayoutItem(QGraphicsLayoutItem *layoutItem) const
qreal rowSpacing(int row, Qt::Orientation orientation=Qt::Vertical) const
static const KeyPair *const end
Orientation
Definition: qnamespace.h:174
void maybeExpandGrid(int row, int column, Qt::Orientation orientation=Qt::Vertical)
#define qPrintable(string)
Definition: qglobal.h:1750
ControlType controlType() const
Definition: qlayout.cpp:1670
Qt::Alignment rowAlignment(int row, Qt::Orientation orientation) const
int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1, QSizePolicy::ControlTypes controls2, Qt::Orientation orientation, QStyleOption *option=0, QWidget *widget=0) const
Returns the spacing that should be used between controls1 and controls2 in a layout.
Definition: qstyle.cpp:2438
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
int indexOf(QGraphicsLayoutItem *item) const
static qreal compare(const QGridLayoutBox &box1, const QGridLayoutBox &box2, int which)
void setGeometries(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry)
QGraphicsLayoutItem * q_layoutItem
int stretchFactor(Qt::Orientation orientation) const
Qt::LayoutDirection direction
static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
void setStretchFactor(int stretch, Qt::Orientation orientation)