Revision 1 (by moose, 2006/03/06 10:35:57) Initial Import
/****************************************************************************
**
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#include <QtGui>

#include <QStyle>
#include "flowlayout.h"

FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing)
    : QLayout(parent)
{
    setMargin(margin);
    setSpacing(spacing);
}

FlowLayout::FlowLayout(int spacing)
{
    setSpacing(spacing);
}

FlowLayout::~FlowLayout()
{
    QLayoutItem *item;
    while ((item = takeAt(0)))
        delete item;
}

void FlowLayout::addItem(QLayoutItem *item)
{
    itemList.append(item);
}

int FlowLayout::count() const
{
    return itemList.size();
}

QLayoutItem *FlowLayout::itemAt(int index) const
{
    return itemList.value(index);
}

QLayoutItem *FlowLayout::takeAt(int index)
{
    if (index >= 0 && index < itemList.size())
        return itemList.takeAt(index);
    else
        return 0;
}

Qt::Orientations FlowLayout::expandingDirections() const
{
    return 0;
}

bool FlowLayout::hasHeightForWidth() const
{
    return true;
}

int FlowLayout::heightForWidth(int width) const
{
    int height = doLayout(QRect(0, 0, width, 0), true);
//	printf("heightForWidth, w:%i, h:%i\n", width, height);
    return height;
}

void FlowLayout::setGeometry(const QRect &rect)
{
    QLayout::setGeometry(rect);
    doLayout(rect, false);
}

QSize FlowLayout::sizeHint() const
{
    return minimumSize();
}

QSize FlowLayout::minimumSize() const
{
    QSize size;

    QWidget *wid = ((FlowLayout *)this)->parentWidget();
    if(wid) {
	    int height = doLayout(QRect(0, 0, wid->width() - wid->style()->pixelMetric(QStyle::PM_ScrollBarExtent)*2 - margin()*2, 0), false);
       size = QSize(wid->width() - wid->style()->pixelMetric(QStyle::PM_ScrollBarExtent)*2 - margin()*2, height);
    }
    else {
       QLayoutItem *item;
       foreach (item, itemList)
          size = size.expandedTo(item->minimumSize());
    }

    size += QSize(2*margin(), 2*margin());

    return size;
}

int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
    QRect r = rect;
    int lineHeight = 0;

    QWidget *wid = ((FlowLayout *)this)->parentWidget();
    int w = 0;
    if(wid) {
        w = wid->style()->pixelMetric(QStyle::PM_ScrollBarExtent)*2;
			r = QRect(r.left(), r.top(), r.width()-w, r.height());
    }

    int x = r.x() + margin();
    int y = r.y() + margin();

    QLayoutItem *item;
    foreach (item, itemList) {
        int nextX = x + item->sizeHint().width() + spacing();
        if (nextX - spacing() > r.right() && lineHeight > 0) {
            x = r.x() + margin();
            y = y + lineHeight + spacing();
            nextX = x + item->sizeHint().width() + spacing();
            lineHeight = 0;
        }

        if (!testOnly)
            item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));

        x = nextX;
        lineHeight = qMax(lineHeight, item->sizeHint().height());
    }
//	printf("doLayout, %i\n", y + lineHeight - r.y());
    return y + lineHeight - r.y();
}