Qt 4.8
Typedefs | Functions
qlayoutengine.cpp File Reference
#include "qlayout.h"
#include "private/qlayoutengine_p.h"
#include "qvector.h"
#include "qwidget.h"
#include <qlist.h>
#include <qalgorithms.h>
#include <qdebug.h>

Go to the source code of this file.

Typedefs

typedef qint64 Fixed64
 

Functions

static int fRound (Fixed64 i)
 
void qGeomCalc (QVector< QLayoutStruct > &chain, int start, int count, int pos, int space, int spacer)
 
Q_GUI_EXPORT QSize qSmartMaxSize (const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy, Qt::Alignment align)
 
Q_GUI_EXPORT QSize qSmartMaxSize (const QWidgetItem *i, Qt::Alignment align)
 
Q_GUI_EXPORT QSize qSmartMaxSize (const QWidget *w, Qt::Alignment align)
 
Q_GUI_EXPORT QSize qSmartMinSize (const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
 
Q_GUI_EXPORT QSize qSmartMinSize (const QWidgetItem *i)
 
Q_GUI_EXPORT QSize qSmartMinSize (const QWidget *w)
 
Q_GUI_EXPORT int qSmartSpacing (const QLayout *layout, QStyle::PixelMetric pm)
 
static Fixed64 toFixed (int i)
 

Typedef Documentation

◆ Fixed64

typedef qint64 Fixed64

Definition at line 57 of file qlayoutengine.cpp.

Function Documentation

◆ fRound()

static int fRound ( Fixed64  i)
inlinestatic

Definition at line 59 of file qlayoutengine.cpp.

Referenced by qGeomCalc().

59  {
60  return (i % 256 < 128) ? i / 256 : 1 + i / 256;
61 }

◆ qGeomCalc()

void qGeomCalc ( QVector< QLayoutStruct > &  chain,
int  start,
int  count,
int  pos,
int  space,
int  spacer 
)

Definition at line 78 of file qlayoutengine.cpp.

Referenced by QBoxLayoutPrivate::calcHfw(), QGridLayoutPrivate::distribute(), distributeMultiBox(), QSplitterPrivate::doResize(), QDockAreaLayoutInfo::fitItems(), QDockAreaLayout::fitLayout(), QGridLayoutPrivate::heightForWidth(), QToolBarLayout::layoutActions(), QTabBarPrivate::layoutTabs(), QBoxLayout::setGeometry(), and QFormLayout::setGeometry().

80 {
81  int cHint = 0;
82  int cMin = 0;
83  int cMax = 0;
84  int sumStretch = 0;
85  int sumSpacing = 0;
86  int expandingCount = 0;
87 
88  bool allEmptyNonstretch = true;
89  int pendingSpacing = -1;
90  int spacerCount = 0;
91  int i;
92 
93  for (i = start; i < start + count; i++) {
94  QLayoutStruct *data = &chain[i];
95 
96  data->done = false;
97  cHint += data->smartSizeHint();
98  cMin += data->minimumSize;
99  cMax += data->maximumSize;
100  sumStretch += data->stretch;
101  if (!data->empty) {
102  /*
103  Using pendingSpacing, we ensure that the spacing for the last
104  (non-empty) item is ignored.
105  */
106  if (pendingSpacing >= 0) {
107  sumSpacing += pendingSpacing;
108  ++spacerCount;
109  }
110  pendingSpacing = data->effectiveSpacer(spacer);
111  }
112  if (data->expansive)
113  expandingCount++;
114  allEmptyNonstretch = allEmptyNonstretch && data->empty && !data->expansive && data->stretch <= 0;
115  }
116 
117  int extraspace = 0;
118 
119  if (space < cMin + sumSpacing) {
120  /*
121  Less space than minimumSize; take from the biggest first
122  */
123 
124  int minSize = cMin + sumSpacing;
125 
126  // shrink the spacers proportionally
127  if (spacer >= 0) {
128  spacer = minSize > 0 ? spacer * space / minSize : 0;
129  sumSpacing = spacer * spacerCount;
130  }
131 
132  QList<int> list;
133 
134  for (i = start; i < start + count; i++)
135  list << chain.at(i).minimumSize;
136 
137  qSort(list);
138 
139  int space_left = space - sumSpacing;
140 
141  int sum = 0;
142  int idx = 0;
143  int space_used=0;
144  int current = 0;
145  while (idx < count && space_used < space_left) {
146  current = list.at(idx);
147  space_used = sum + current * (count - idx);
148  sum += current;
149  ++idx;
150  }
151  --idx;
152  int deficit = space_used - space_left;
153 
154  int items = count - idx;
155  /*
156  * If we truncate all items to "current", we would get "deficit" too many pixels. Therefore, we have to remove
157  * deficit/items from each item bigger than maxval. The actual value to remove is deficitPerItem + remainder/items
158  * "rest" is the accumulated error from using integer arithmetic.
159  */
160  int deficitPerItem = deficit/items;
161  int remainder = deficit % items;
162  int maxval = current - deficitPerItem;
163 
164  int rest = 0;
165  for (i = start; i < start + count; i++) {
166  int maxv = maxval;
167  rest += remainder;
168  if (rest >= items) {
169  maxv--;
170  rest-=items;
171  }
172  QLayoutStruct *data = &chain[i];
173  data->size = qMin(data->minimumSize, maxv);
174  data->done = true;
175  }
176  } else if (space < cHint + sumSpacing) {
177  /*
178  Less space than smartSizeHint(), but more than minimumSize.
179  Currently take space equally from each, as in Qt 2.x.
180  Commented-out lines will give more space to stretchier
181  items.
182  */
183  int n = count;
184  int space_left = space - sumSpacing;
185  int overdraft = cHint - space_left;
186 
187  // first give to the fixed ones:
188  for (i = start; i < start + count; i++) {
189  QLayoutStruct *data = &chain[i];
190  if (!data->done
191  && data->minimumSize >= data->smartSizeHint()) {
192  data->size = data->smartSizeHint();
193  data->done = true;
194  space_left -= data->smartSizeHint();
195  // sumStretch -= data->stretch;
196  n--;
197  }
198  }
199  bool finished = n == 0;
200  while (!finished) {
201  finished = true;
202  Fixed64 fp_over = toFixed(overdraft);
203  Fixed64 fp_w = 0;
204 
205  for (i = start; i < start+count; i++) {
206  QLayoutStruct *data = &chain[i];
207  if (data->done)
208  continue;
209  // if (sumStretch <= 0)
210  fp_w += fp_over / n;
211  // else
212  // fp_w += (fp_over * data->stretch) / sumStretch;
213  int w = fRound(fp_w);
214  data->size = data->smartSizeHint() - w;
215  fp_w -= toFixed(w); // give the difference to the next
216  if (data->size < data->minimumSize) {
217  data->done = true;
218  data->size = data->minimumSize;
219  finished = false;
220  overdraft -= data->smartSizeHint() - data->minimumSize;
221  // sumStretch -= data->stretch;
222  n--;
223  break;
224  }
225  }
226  }
227  } else { // extra space
228  int n = count;
229  int space_left = space - sumSpacing;
230  // first give to the fixed ones, and handle non-expansiveness
231  for (i = start; i < start + count; i++) {
232  QLayoutStruct *data = &chain[i];
233  if (!data->done
234  && (data->maximumSize <= data->smartSizeHint()
235  || (!allEmptyNonstretch && data->empty &&
236  !data->expansive && data->stretch == 0))) {
237  data->size = data->smartSizeHint();
238  data->done = true;
239  space_left -= data->size;
240  sumStretch -= data->stretch;
241  if (data->expansive)
242  expandingCount--;
243  n--;
244  }
245  }
246  extraspace = space_left;
247 
248  /*
249  Do a trial distribution and calculate how much it is off.
250  If there are more deficit pixels than surplus pixels, give
251  the minimum size items what they need, and repeat.
252  Otherwise give to the maximum size items, and repeat.
253 
254  Paul Olav Tvete has a wonderful mathematical proof of the
255  correctness of this principle, but unfortunately this
256  comment is too small to contain it.
257  */
258  int surplus, deficit;
259  do {
260  surplus = deficit = 0;
261  Fixed64 fp_space = toFixed(space_left);
262  Fixed64 fp_w = 0;
263  for (i = start; i < start + count; i++) {
264  QLayoutStruct *data = &chain[i];
265  if (data->done)
266  continue;
267  extraspace = 0;
268  if (sumStretch > 0) {
269  fp_w += (fp_space * data->stretch) / sumStretch;
270  } else if (expandingCount > 0) {
271  fp_w += (fp_space * (data->expansive ? 1 : 0)) / expandingCount;
272  } else {
273  fp_w += fp_space * 1 / n;
274  }
275  int w = fRound(fp_w);
276  data->size = w;
277  fp_w -= toFixed(w); // give the difference to the next
278  if (w < data->smartSizeHint()) {
279  deficit += data->smartSizeHint() - w;
280  } else if (w > data->maximumSize) {
281  surplus += w - data->maximumSize;
282  }
283  }
284  if (deficit > 0 && surplus <= deficit) {
285  // give to the ones that have too little
286  for (i = start; i < start+count; i++) {
287  QLayoutStruct *data = &chain[i];
288  if (!data->done && data->size < data->smartSizeHint()) {
289  data->size = data->smartSizeHint();
290  data->done = true;
291  space_left -= data->smartSizeHint();
292  sumStretch -= data->stretch;
293  if (data->expansive)
294  expandingCount--;
295  n--;
296  }
297  }
298  }
299  if (surplus > 0 && surplus >= deficit) {
300  // take from the ones that have too much
301  for (i = start; i < start + count; i++) {
302  QLayoutStruct *data = &chain[i];
303  if (!data->done && data->size > data->maximumSize) {
304  data->size = data->maximumSize;
305  data->done = true;
306  space_left -= data->maximumSize;
307  sumStretch -= data->stretch;
308  if (data->expansive)
309  expandingCount--;
310  n--;
311  }
312  }
313  }
314  } while (n > 0 && surplus != deficit);
315  if (n == 0)
316  extraspace = space_left;
317  }
318 
319  /*
320  As a last resort, we distribute the unwanted space equally
321  among the spacers (counting the start and end of the chain). We
322  could, but don't, attempt a sub-pixel allocation of the extra
323  space.
324  */
325  int extra = extraspace / (spacerCount + 2);
326  int p = pos + extra;
327  for (i = start; i < start+count; i++) {
328  QLayoutStruct *data = &chain[i];
329  data->pos = p;
330  p += data->size;
331  if (!data->empty)
332  p += data->effectiveSpacer(spacer) + extra;
333  }
334 
335 #ifdef QLAYOUT_EXTRA_DEBUG
336  qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos
337  << "space" << space << "spacer" << spacer;
338  for (i = start; i < start + count; ++i) {
339  qDebug() << i << ':' << chain[i].minimumSize << chain[i].smartSizeHint()
340  << chain[i].maximumSize << "stretch" << chain[i].stretch
341  << "empty" << chain[i].empty << "expansive" << chain[i].expansive
342  << "spacing" << chain[i].spacing;
343  qDebug() << "result pos" << chain[i].pos << "size" << chain[i].size;
344  }
345 #endif
346 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static Fixed64 toFixed(int i)
qint64 Fixed64
bool empty() const
This function is provided for STL compatibility.
Definition: qvector.h:285
static int fRound(Fixed64 i)
int effectiveSpacer(int uniformSpacer) const
Q_CORE_EXPORT void qDebug(const char *,...)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static const char * data(const QByteArray &arr)
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ qSmartMaxSize() [1/3]

Q_GUI_EXPORT QSize qSmartMaxSize ( const QSize sizeHint,
const QSize minSize,
const QSize maxSize,
const QSizePolicy sizePolicy,
Qt::Alignment  align 
)

Definition at line 393 of file qlayoutengine.cpp.

Referenced by QLayout::closestAcceptableSize(), QWidgetItem::maximumSize(), qSmartMaxSize(), QWidgetItemV2::updateCacheIfNecessary(), and QScrollAreaPrivate::updateScrollBars().

396 {
397  if (align & Qt::AlignHorizontal_Mask && align & Qt::AlignVertical_Mask)
399  QSize s = maxSize;
400  QSize hint = sizeHint.expandedTo(minSize);
401  if (s.width() == QWIDGETSIZE_MAX && !(align & Qt::AlignHorizontal_Mask))
402  if (!(sizePolicy.horizontalPolicy() & QSizePolicy::GrowFlag))
403  s.setWidth(hint.width());
404 
405  if (s.height() == QWIDGETSIZE_MAX && !(align & Qt::AlignVertical_Mask))
406  if (!(sizePolicy.verticalPolicy() & QSizePolicy::GrowFlag))
407  s.setHeight(hint.height());
408 
409  if (align & Qt::AlignHorizontal_Mask)
411  if (align & Qt::AlignVertical_Mask)
413  return s;
414 }
Policy horizontalPolicy() const
Definition: qsizepolicy.h:118
#define QWIDGETSIZE_MAX
Defines the maximum size for a QWidget object.
Definition: qwidget.h:1087
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
int width() const
Returns the width.
Definition: qsize.h:126
Policy verticalPolicy() const
Definition: qsizepolicy.h:119
int height() const
Returns the height.
Definition: qsize.h:129
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
static const int QLAYOUTSIZE_MAX
Definition: qlayoutitem.h:56

◆ qSmartMaxSize() [2/3]

Q_GUI_EXPORT QSize qSmartMaxSize ( const QWidgetItem i,
Qt::Alignment  align 
)

Definition at line 416 of file qlayoutengine.cpp.

417 {
418  QWidget *w = ((QWidgetItem*)i)->widget();
419 
421  w->sizePolicy(), align);
422 }
QSize maximumSize
the widget&#39;s maximum size in pixels
Definition: qwidget.h:173
QSize minimumSize
the widget&#39;s minimum size
Definition: qwidget.h:172
Q_GUI_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy, Qt::Alignment align)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
QSize minimumSizeHint
the recommended minimum size for the widget
Definition: qwidget.h:196
The QWidgetItem class is a layout item that represents a widget.
Definition: qlayoutitem.h:122
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195

◆ qSmartMaxSize() [3/3]

Q_GUI_EXPORT QSize qSmartMaxSize ( const QWidget w,
Qt::Alignment  align 
)

Definition at line 424 of file qlayoutengine.cpp.

425 {
427  w->sizePolicy(), align);
428 }
QSize maximumSize
the widget&#39;s maximum size in pixels
Definition: qwidget.h:173
QSize minimumSize
the widget&#39;s minimum size
Definition: qwidget.h:172
Q_GUI_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy, Qt::Alignment align)
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
QSize minimumSizeHint
the recommended minimum size for the widget
Definition: qwidget.h:196
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195

◆ qSmartMinSize() [1/3]

Q_GUI_EXPORT QSize qSmartMinSize ( const QSize sizeHint,
const QSize minSizeHint,
const QSize minSize,
const QSize maxSize,
const QSizePolicy sizePolicy 
)

Definition at line 348 of file qlayoutengine.cpp.

Referenced by QSplitterPrivate::addContribution(), QMdiAreaPrivate::appendChild(), QWorkspace::cascade(), QLayout::closestAcceptableSize(), QSplitterPrivate::doMove(), QSplitterPrivate::doResize(), QStatusBar::event(), QSplitterPrivate::findWidgetJustBeforeOrJustAfter(), menuBarHeightForWidth(), QStackedLayout::minimumSize(), QToolBarAreaLayoutItem::minimumSize(), QWidgetItem::minimumSize(), QSplitter::minimumSizeHint(), QWidgetResizeHandler::mouseMoveEvent(), qSmartMinSize(), QSplitterPrivate::recalc(), QStatusBar::reformat(), QSplitterPrivate::setGeo(), QSplitterPrivate::setSizes_helper(), QMdiArea::showEvent(), QWidgetItemV2::updateCacheIfNecessary(), QStyledItemDelegate::updateEditorGeometry(), and QScrollAreaPrivate::updateScrollBars().

351 {
352  QSize s(0, 0);
353 
354  if (sizePolicy.horizontalPolicy() != QSizePolicy::Ignored) {
355  if (sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag)
356  s.setWidth(minSizeHint.width());
357  else
358  s.setWidth(qMax(sizeHint.width(), minSizeHint.width()));
359  }
360 
361  if (sizePolicy.verticalPolicy() != QSizePolicy::Ignored) {
362  if (sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag) {
363  s.setHeight(minSizeHint.height());
364  } else {
365  s.setHeight(qMax(sizeHint.height(), minSizeHint.height()));
366  }
367  }
368 
369  s = s.boundedTo(maxSize);
370  if (minSize.width() > 0)
371  s.setWidth(minSize.width());
372  if (minSize.height() > 0)
373  s.setHeight(minSize.height());
374 
375  return s.expandedTo(QSize(0,0));
376 }
Policy horizontalPolicy() const
Definition: qsizepolicy.h:118
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
int width() const
Returns the width.
Definition: qsize.h:126
Policy verticalPolicy() const
Definition: qsizepolicy.h:119
int height() const
Returns the height.
Definition: qsize.h:129
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53

◆ qSmartMinSize() [2/3]

Q_GUI_EXPORT QSize qSmartMinSize ( const QWidgetItem i)

Definition at line 378 of file qlayoutengine.cpp.

379 {
380  QWidget *w = ((QWidgetItem *)i)->widget();
381  return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
382  w->minimumSize(), w->maximumSize(),
383  w->sizePolicy());
384 }
QSize maximumSize
the widget&#39;s maximum size in pixels
Definition: qwidget.h:173
QSize minimumSize
the widget&#39;s minimum size
Definition: qwidget.h:172
Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize minimumSizeHint
the recommended minimum size for the widget
Definition: qwidget.h:196
The QWidgetItem class is a layout item that represents a widget.
Definition: qlayoutitem.h:122
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195

◆ qSmartMinSize() [3/3]

Q_GUI_EXPORT QSize qSmartMinSize ( const QWidget w)

Definition at line 386 of file qlayoutengine.cpp.

387 {
388  return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
389  w->minimumSize(), w->maximumSize(),
390  w->sizePolicy());
391 }
QSize maximumSize
the widget&#39;s maximum size in pixels
Definition: qwidget.h:173
QSize minimumSize
the widget&#39;s minimum size
Definition: qwidget.h:172
Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
QSize minimumSizeHint
the recommended minimum size for the widget
Definition: qwidget.h:196
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195

◆ qSmartSpacing()

Q_GUI_EXPORT int qSmartSpacing ( const QLayout layout,
QStyle::PixelMetric  pm 
)

Definition at line 430 of file qlayoutengine.cpp.

Referenced by QGridLayout::horizontalSpacing(), QLayout::setAlignment(), QFormLayout::setHorizontalSpacing(), QFormLayout::setVerticalSpacing(), QBoxLayout::spacing(), and QGridLayout::verticalSpacing().

431 {
432  QObject *parent = layout->parent();
433  if (!parent) {
434  return -1;
435  } else if (parent->isWidgetType()) {
436  QWidget *pw = static_cast<QWidget *>(parent);
437  return pw->style()->pixelMetric(pm, 0, pw);
438  } else {
439  return static_cast<QLayout *>(parent)->spacing();
440  }
441 }
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QStyle * style() const
Definition: qwidget.cpp:2742
The QLayout class is the base class of geometry managers.
Definition: qlayout.h:90
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273

◆ toFixed()

static Fixed64 toFixed ( int  i)
inlinestatic

Definition at line 58 of file qlayoutengine.cpp.

Referenced by qGeomCalc().

58 { return (Fixed64)i * 256; }
qint64 Fixed64