You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

146 lines
4.9 KiB

/*
* Copyright 2019 by Marco Martin <mart@kde.org>
*
* This program 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, or
* (at your option) any later version.
*
* This program 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 program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "abstractlayoutmanager.h"
#include "itemcontainer.h"
#include <cmath>
AbstractLayoutManager::AbstractLayoutManager(AppletsLayout *layout)
: QObject(layout)
, m_layout(layout)
{
}
AbstractLayoutManager::~AbstractLayoutManager()
{
}
AppletsLayout *AbstractLayoutManager::layout() const
{
return m_layout;
}
QSizeF AbstractLayoutManager::cellSize() const
{
return m_cellSize;
}
QSizeF AbstractLayoutManager::cellAlignedContainingSize(const QSizeF &size) const
{
return QSizeF(m_cellSize.width() * ceil(size.width() / m_cellSize.width()), m_cellSize.height() * ceil(size.height() / m_cellSize.height()));
}
void AbstractLayoutManager::setCellSize(const QSizeF &size)
{
m_cellSize = size;
}
QRectF AbstractLayoutManager::candidateGeometry(ItemContainer *item) const
{
const QRectF originalItemRect = QRectF(item->x(), item->y(), item->width(), item->height());
// TODO: a default minimum size
QSizeF minimumSize = QSize(m_layout->minimumItemWidth(), m_layout->minimumItemHeight());
if (item->layoutAttached()) {
minimumSize = QSizeF(qMax(minimumSize.width(), item->layoutAttached()->property("minimumWidth").toReal()),
qMax(minimumSize.height(), item->layoutAttached()->property("minimumHeight").toReal()));
}
const QRectF ltrRect = nextAvailableSpace(item, minimumSize, AppletsLayout::LeftToRight);
const QRectF rtlRect = nextAvailableSpace(item, minimumSize, AppletsLayout::RightToLeft);
const QRectF ttbRect = nextAvailableSpace(item, minimumSize, AppletsLayout::TopToBottom);
const QRectF bttRect = nextAvailableSpace(item, minimumSize, AppletsLayout::BottomToTop);
// Take the closest rect, unless the item prefers a particular positioning strategy
QMap<int, QRectF> distances;
if (!ltrRect.isEmpty()) {
const int dist =
item->preferredLayoutDirection() == AppletsLayout::LeftToRight ? 0 : QPointF(originalItemRect.center() - ltrRect.center()).manhattanLength();
distances[dist] = ltrRect;
}
if (!rtlRect.isEmpty()) {
const int dist =
item->preferredLayoutDirection() == AppletsLayout::RightToLeft ? 0 : QPointF(originalItemRect.center() - rtlRect.center()).manhattanLength();
distances[dist] = rtlRect;
}
if (!ttbRect.isEmpty()) {
const int dist =
item->preferredLayoutDirection() == AppletsLayout::TopToBottom ? 0 : QPointF(originalItemRect.center() - ttbRect.center()).manhattanLength();
distances[dist] = ttbRect;
}
if (!bttRect.isEmpty()) {
const int dist =
item->preferredLayoutDirection() == AppletsLayout::BottomToTop ? 0 : QPointF(originalItemRect.center() - bttRect.center()).manhattanLength();
distances[dist] = bttRect;
}
if (distances.isEmpty()) {
// Failure to layout, completely full
return originalItemRect;
} else {
return distances.first();
}
}
void AbstractLayoutManager::positionItem(ItemContainer *item)
{
// Give it a sane size if uninitialized: this may change size hints
if (item->width() <= 0 || item->height() <= 0) {
item->setSize(QSizeF(qMax(m_layout->minimumItemWidth(), m_layout->defaultItemWidth()), //
qMax(m_layout->minimumItemHeight(), m_layout->defaultItemHeight())));
}
QRectF candidate = candidateGeometry(item);
item->setPosition(candidate.topLeft());
item->setSize(candidate.size());
}
void AbstractLayoutManager::positionItemAndAssign(ItemContainer *item)
{
releaseSpace(item);
positionItem(item);
assignSpace(item);
}
bool AbstractLayoutManager::assignSpace(ItemContainer *item)
{
if (assignSpaceImpl(item)) {
emit layoutNeedsSaving();
return true;
} else {
return false;
}
}
void AbstractLayoutManager::releaseSpace(ItemContainer *item)
{
releaseSpaceImpl(item);
emit layoutNeedsSaving();
}
void AbstractLayoutManager::layoutGeometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_UNUSED(newGeometry);
Q_UNUSED(oldGeometry);
// NOTE: Empty base implementation, don't put anything here
}
#include "moc_abstractlayoutmanager.cpp"