diff --git a/src/kblocklayout.cpp b/src/kblocklayout.cpp index 0537a40..0d9692d 100644 --- a/src/kblocklayout.cpp +++ b/src/kblocklayout.cpp @@ -1,270 +1,270 @@ /* * This file is part of the Baloo KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* KBlockLayout is based on the FlowLayout example from QT4. Copyright (C) 2004-2006 Trolltech ASA. All rights reserved. Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. Contact: Nokia Corporation (qt-info@nokia.com) */ #include "kblocklayout.h" #include #include #include class KBlockLayout::Private { public: Private() : alignment(Qt::AlignLeft|Qt::AlignTop) { } int smartSpacing(QStyle::PixelMetric pm) const { QObject *parent = q->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { QWidget *pw = static_cast(parent); return pw->style()->pixelMetric(pm, nullptr, pw); } else { return static_cast(parent)->spacing(); } } QList itemList; int m_hSpace; int m_vSpace; Qt::Alignment alignment; KBlockLayout* q; }; KBlockLayout::KBlockLayout( QWidget* parent, int margin, int hSpacing, int vSpacing ) : QLayout(parent), d( new Private() ) { d->q = this; setContentsMargins(margin, margin, margin, margin); setSpacing(hSpacing, vSpacing); } KBlockLayout::KBlockLayout( int margin, int hSpacing, int vSpacing ) : d( new Private() ) { d->q = this; setContentsMargins(margin, margin, margin, margin); setSpacing(hSpacing, vSpacing); } KBlockLayout::~KBlockLayout() { QLayoutItem* item; while ((item = takeAt(0))) delete item; delete d; } void KBlockLayout::setAlignment( Qt::Alignment a ) { d->alignment = a; } Qt::Alignment KBlockLayout::alignment() const { return d->alignment; } int KBlockLayout::horizontalSpacing() const { if (d->m_hSpace >= 0) { return d->m_hSpace; } else { return d->smartSpacing(QStyle::PM_LayoutHorizontalSpacing); } } int KBlockLayout::verticalSpacing() const { if (d->m_vSpace >= 0) { return d->m_vSpace; } else { return d->smartSpacing(QStyle::PM_LayoutVerticalSpacing); } } void KBlockLayout::setSpacing( int h, int v ) { d->m_hSpace = h; d->m_vSpace = v; QLayout::setSpacing( h ); } void KBlockLayout::addItem( QLayoutItem* item ) { d->itemList.append(item); } int KBlockLayout::count() const { return d->itemList.size(); } QLayoutItem *KBlockLayout::itemAt( int index ) const { return d->itemList.value(index); } QLayoutItem *KBlockLayout::takeAt( int index ) { if (index >= 0 && index < d->itemList.size()) return d->itemList.takeAt(index); else return nullptr; } Qt::Orientations KBlockLayout::expandingDirections() const { - return nullptr; + return {}; } bool KBlockLayout::hasHeightForWidth() const { return true; } int KBlockLayout::heightForWidth( int width ) const { int height = doLayout(QRect(0, 0, width, 0), true); return height; } void KBlockLayout::setGeometry( const QRect& rect ) { QLayout::setGeometry(rect); doLayout(rect, false); } QSize KBlockLayout::sizeHint() const { // TODO: try to get the items into a square QSize size; for (QLayoutItem* item : qAsConst(d->itemList)) { const QSize itemSize = item->minimumSize(); size.rwidth() += itemSize.width(); if (itemSize.height() > size.height()) { size.setHeight(itemSize.height()); } } size.rwidth() += horizontalSpacing() * d->itemList.count(); size += QSize(2*margin(), 2*margin()); return size; } QSize KBlockLayout::minimumSize() const { QSize size; for (QLayoutItem* item : qAsConst(d->itemList)) { size = size.expandedTo(item->minimumSize()); } size += QSize(2*margin(), 2*margin()); return size; } struct Row { Row( const QList& i, int h, int w ) : items(i), height(h), width(w) { } QList items; int height; int width; }; int KBlockLayout::doLayout( const QRect& rect, bool testOnly ) const { int x = rect.x(); int y = rect.y(); int lineHeight = 0; // 1. calculate lines QList rows; QList rowItems; for( int i = 0; i < d->itemList.count(); ++i ) { QLayoutItem* item = d->itemList[i]; int nextX = x + item->sizeHint().width() + horizontalSpacing(); if (nextX - horizontalSpacing() > rect.right() && lineHeight > 0) { rows.append( Row( rowItems, lineHeight, x - horizontalSpacing() ) ); rowItems.clear(); x = rect.x(); y = y + lineHeight + verticalSpacing(); nextX = x + item->sizeHint().width() + horizontalSpacing(); lineHeight = 0; } rowItems.append( item ); x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } // append the last row rows.append( Row( rowItems, lineHeight, x-horizontalSpacing() ) ); int finalHeight = y + lineHeight - rect.y(); if( testOnly ) return finalHeight; // 2. place the items y = rect.y(); for (const Row& row : qAsConst(rows)) { x = rect.x(); if( alignment() & Qt::AlignRight ) x += (rect.width() - row.width); else if( alignment() & Qt::AlignHCenter ) x += (rect.width() - row.width)/2; for (QLayoutItem* item : qAsConst(row.items)) { int yy = y; if( alignment() & Qt::AlignBottom ) yy += (row.height - item->sizeHint().height()); else if( alignment() & Qt::AlignVCenter ) yy += (row.height - item->sizeHint().height())/2; item->setGeometry(QRect(QPoint(x, yy), item->sizeHint())); x += item->sizeHint().width() + horizontalSpacing(); if( alignment() & Qt::AlignJustify ) x += (rect.width() - row.width)/qMax(row.items.count()-1,1); } y = y + row.height + verticalSpacing(); } return finalHeight; }