30 #include <QResizeEvent> 32 #include <QApplication> 41 struct KLFFlowLayoutItem :
public QLayoutItem
44 : QLayoutItem(a), item(li), hstretch(0), vstretch(0)
48 virtual ~KLFFlowLayoutItem();
52 return item->expandingDirections();
54 virtual QRect geometry()
const 57 return item->geometry();
59 virtual bool hasHeightForWidth()
const 61 return item->hasHeightForWidth();
63 virtual int heightForWidth(
int w)
const 65 return item->heightForWidth(w);
67 virtual void invalidate()
71 virtual bool isEmpty()
const 73 return item->isEmpty();
75 virtual QLayout *layout()
77 return item->layout();
79 virtual QSize maximumSize()
const 81 return item->maximumSize();
83 virtual int minimumHeightForWidth(
int w)
const 85 return item->minimumHeightForWidth(w);
87 virtual QSize minimumSize()
const 89 return item->minimumSize();
91 virtual void setGeometry(
const QRect& r)
93 klfDbg(
"item/widget="<<item->widget()<<
"; setGeom: "<<r) ;
96 virtual QSize sizeHint()
const 98 return item->sizeHint();
100 virtual QSpacerItem * spacerItem()
102 return item->spacerItem();
104 virtual QWidget * widget()
107 return item->widget();
119 KLFFlowLayoutItem::~KLFFlowLayoutItem()
123 struct KLFFlowLayoutPrivate
131 mainLayout =
new QBoxLayout(QBoxLayout::TopToBottom, NULL);
132 mainLayout->setContentsMargins(0,0,0,0);
135 geom = effectiveGeom =
QRect(0, 0, 640, 480);
136 marginsSize =
QSize(0,0);
139 min_size =
QSize(0,0);
152 QBoxLayout *mainLayout;
180 void removeItemFromSubLayouts(KLFFlowLayoutItem* fi)
184 for (k = 0; k < layoutLines.
size(); ++k) {
186 while ((item = layoutLines[k]->itemAt(n)) != NULL) {
188 layoutLines[k]->
takeAt(n);
199 for (k = 0; k < layoutLines.
size(); ++k) {
203 while ((item = layoutLines[k]->takeAt(0)) != NULL) {
204 KLFFlowLayoutItem *fi =
dynamic_cast<KLFFlowLayoutItem*
>(item);
210 mainLayout->removeItem(layoutLines[k]);
211 delete layoutLines[k];
212 layoutLines[k] = NULL;
233 int maxminheight = 0;
234 int summinheight = 0;
240 QStyle *
style = NULL;
241 QWidget *pwidget = K->parentWidget();
243 style = pwidget->style();
245 style = qApp->style();
248 int fitwidth = effectiveGeom.
width();
252 KLFFlowLayoutItem *item;
253 KLFFlowLayoutItem *prevItem = NULL;
255 for (k = 0; k < items.
size(); ++k) {
258 QSize mins = item->minimumSize();
259 QSize maxs = item->maximumSize();
260 QSize sh = item->sizeHint();
265 QSizePolicy::ControlTypes t = QSizePolicy::DefaultType;
266 if (prevItem != NULL)
267 t = prevItem->controlTypes();
271 spaceX = style->combinedLayoutSpacing(t, item->controlTypes(), Qt::Horizontal);
275 spaceY = style->combinedLayoutSpacing(t, item->controlTypes(), Qt::Vertical);
277 if (x + sh.
width() > fitwidth) {
279 shwidth = qMax(shwidth, x);
280 height += spaceY + thislheight;
286 int nextX = x + sh.
width() + spaceX;
290 maxminwidth = qMax(mins.
width(), maxminwidth);
291 maxminheight = qMax(mins.
height(), maxminheight);
292 summinwidth += mins.
width();
293 summinheight += mins.
height();
294 if (maxwidth < (
int)0x7fffffff)
295 maxwidth += maxs.
width() + spaceX;
296 if (maxheight < (
int)0x7fffffff)
297 maxheight += maxs.
height() + spaceY;
298 thislheight = qMax(item->sizeHint().height(), thislheight);
303 height += thislheight;
307 data->height = height;
315 data->minsize =
QSize(maxminwidth, height);
316 data->sizehint =
QSize(shwidth, height);
320 data->maxsize =
QSize(maxwidth, maxheight);
331 klfDbg(
"geom is not valid yet, returning.") ;
338 int left, top, right, bottom;
339 K->getContentsMargins(&left, &top, &right, &bottom);
340 effectiveGeom = geom.
adjusted(+left, +top, -right, -bottom);
341 marginsSize =
QSize(left+right, top+bottom);
343 klfDbg(
"geom = "<<geom<<
"; mainlayout/setgeom, effGeom="<<effectiveGeom) ;
349 klfDbg(
"calculated lines. minsize="<<sizedat.minsize<<
"; maxsize="<<sizedat.maxsize<<
", height=" 354 for (k = 0; k < lines.
size(); ++k) {
356 QBoxLayout *linelyt =
new QBoxLayout(QBoxLayout::LeftToRight, NULL);
357 linelyt->setSpacing(hspc);
361 linelyt->addStretch(0x7fffffff);
363 for (n = 0; n < lines[k].
size(); ++n) {
368 a = (a & ~
Qt::AlignHorizontal_Mask);
372 lines[k][n]->item->setAlignment(a);
373 linelyt->addItem(lines[k][n]);
374 for (i = 0; i < linelyt->count() && linelyt->itemAt(i) != lines[k][n]; ++i)
376 #if QT_VERSION >= 0x040500 378 if (i < linelyt->count()) {
379 linelyt->setStretch(i, lines[k][n]->hstretch);
382 linevstretch = qMax(linevstretch, lines[k][n]->vstretch);
386 linelyt->addStretch(0x7fffffff);
388 mainLayout->addLayout(linelyt, linevstretch);
389 layoutLines << linelyt;
392 hfw_w = geom.
width();
393 hfw_h = sizedat.height;
395 min_size = sizedat.minsize;
396 size_hint = sizedat.sizehint;
397 max_size = sizedat.maxsize;
407 if (K->sizeConstraint() == QLayout::SetDefaultConstraint)
408 K->setSizeConstraint(QLayout::SetMinimumSize);
420 d =
new KLFFlowLayoutPrivate(
this);
421 addChildLayout(d->mainLayout);
422 setContentsMargins(margin, margin, margin, margin);
426 d->mainLayout->setSpacing(d->vspc);
431 delete d->mainLayout;
437 return QLayout::event(event);
442 return QLayout::eventFilter(obj, event);
448 KLFFlowLayoutItem *fi =
new KLFFlowLayoutItem(item, item->alignment());
449 fi->hstretch = hstretch;
450 fi->vstretch = vstretch;
457 w->installEventFilter(
this);
459 QWidgetItem *wi =
new QWidgetItem(w);
460 wi->setAlignment(align);
461 addItem(wi, hstretch, vstretch);
466 addItem(l, hstretch, vstretch);
486 d->mainLayout->setSpacing(d->vspc);
499 return d->items.size();
504 if (index < 0 || index >= d->items.size())
507 return d->items[index]->item;
512 if (index < 0 || index >= d->items.size())
515 KLFFlowLayoutItem *fi = d->items.takeAt(index);
516 d->removeItemFromSubLayouts(fi);
517 QLayoutItem *item = fi->item;
525 return Qt::Horizontal | d->mainLayout->expandingDirections();
533 if (d->hfw_w != width) {
544 QSize s = d->min_size + d->marginsSize;
545 klfDbg(
"minimumSize is "<<s) ;
551 QSize s = d->max_size;
552 klfDbg(
"maximumSize is "<<s) ;
559 if (d->geom != rect) {
563 QLayout::setGeometry(rect);
565 d->mainLayout->setGeometry(d->effectiveGeom);
570 QSize s = d->size_hint + d->marginsSize;
571 klfDbg(
"sizeHint is "<<s) ;
578 QLayout::invalidate();
579 d->mainLayout->invalidate();
586 while ((it =
takeAt(0)) != NULL) {
587 if (deleteItems && it->widget() != NULL)
588 it->widget()->deleteLater();
589 if (deleteItems && it->layout() != NULL)
590 todelete << it->layout();
595 foreach (QLayoutItem *item, todelete) {
A Layout that places widgets left to right, top to bottom.
int horizontalSpacing() const
virtual void addWidget(QWidget *w, int hstretch=0, int vstretch=0, Qt::Alignment align=0)
virtual void addLayout(QLayout *l, int hstretch=0, int vstretch=0)
Base declarations for klatexformula and some utilities.
virtual bool event(QEvent *event)
void setHorizontalSpacing(int spacing)
Distribute the extra space inbetween the widgets to fill the line.
void setVerticalSpacing(int spacing)
#define klfDbg(streamableItems)
print debug stream items
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
virtual QLayoutItem * itemAt(int index) const
int verticalSpacing() const
virtual int heightForWidth(int width) const
virtual bool eventFilter(QObject *obj, QEvent *event)
virtual int count() const
Leave all extra space at end of line.
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Asserting Non-NULL pointers (NON-FATAL)
virtual bool hasHeightForWidth() const
#define KLF_DEBUG_TIME_BLOCK(msg)
Utility to time the execution of a block.
virtual QSize maximumSize() const
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const
virtual void invalidate()
KLFFlowLayout(QWidget *parent, int margin=-1, int hspacing=-1, int vspacing=-1)
Leave all extra space at beginning of line.
virtual Qt::Orientations expandingDirections() const
virtual QLayoutItem * takeAt(int index)
QSize expandedTo(const QSize &otherSize) const
virtual QSize minimumSize() const
virtual QSize sizeHint() const
void setGeometry(const QRect &rect)
virtual void addItem(QLayoutItem *item)
Give the extra space to the widgets to stretch, don't flush.
void clearAll(bool deleteItems=true)