cpp move of nodelayout
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=796526
This commit is contained in:
parent
db5fcf95ff
commit
7dce58f009
@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License
|
|
||||||
* version 2, or (at your option) any later version, as published by the
|
|
||||||
* Free Software Foundation
|
|
||||||
*
|
|
||||||
* 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 General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser 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 "nodelayout.h"
|
|
||||||
|
|
||||||
#include <QPair>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
NodeLayout::NodeCoordinate::NodeCoordinate(qreal xRelative, qreal yRelative, qreal xAbsolute, qreal yAbsolute)
|
|
||||||
: xr(xRelative), xa(xAbsolute), yr(yRelative), ya(yAbsolute) {}
|
|
||||||
|
|
||||||
NodeLayout::NodeCoordinate NodeLayout::NodeCoordinate::simple(qreal x, qreal y,
|
|
||||||
CoordinateType xType, CoordinateType yType)
|
|
||||||
{
|
|
||||||
NodeLayout::NodeCoordinate coo;
|
|
||||||
switch (xType) {
|
|
||||||
case Relative:
|
|
||||||
coo.xr = x;
|
|
||||||
coo.xa = 0;
|
|
||||||
break;
|
|
||||||
case Absolute:
|
|
||||||
coo.xr = 0;
|
|
||||||
coo.xa = x;
|
|
||||||
break;
|
|
||||||
case InnerRelative:
|
|
||||||
coo.xr = x;
|
|
||||||
coo.xa = std::numeric_limits<float>::infinity();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (yType) {
|
|
||||||
case Relative:
|
|
||||||
coo.yr = y;
|
|
||||||
coo.ya = 0;
|
|
||||||
break;
|
|
||||||
case Absolute:
|
|
||||||
coo.yr = 0;
|
|
||||||
coo.ya = y;
|
|
||||||
break;
|
|
||||||
case InnerRelative:
|
|
||||||
coo.yr = y;
|
|
||||||
coo.ya = std::numeric_limits<float>::infinity();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return coo;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NodeLayout::Private {
|
|
||||||
public:
|
|
||||||
QMap <LayoutItem * , QPair < NodeCoordinate, NodeCoordinate > > items;
|
|
||||||
//QRectF geometry;
|
|
||||||
NodeLayout * parent;
|
|
||||||
QSizeF sizeHint;
|
|
||||||
|
|
||||||
Private(NodeLayout * parentLayout) {
|
|
||||||
parent = parentLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal calculateXPosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
|
|
||||||
{
|
|
||||||
return parentGeometry.left() + (coo.xr * parentGeometry.width()) + coo.xa;
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal calculateYPosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
|
|
||||||
{
|
|
||||||
return parentGeometry.top() + (coo.yr * parentGeometry.height()) + coo.ya;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF calculatePosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
|
|
||||||
{
|
|
||||||
Q_UNUSED( parentGeometry );
|
|
||||||
|
|
||||||
return QPointF(
|
|
||||||
calculateXPosition(coo, parent->geometry()),
|
|
||||||
calculateYPosition(coo, parent->geometry())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QRectF calculateRectangle(LayoutItem * item, QRectF geometry = QRectF()) const
|
|
||||||
{
|
|
||||||
if (geometry == QRectF()) {
|
|
||||||
geometry = parent->geometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF result;
|
|
||||||
if (!item || !items.contains(item)) {
|
|
||||||
return QRectF();
|
|
||||||
}
|
|
||||||
|
|
||||||
result.setTopLeft(calculatePosition(items[item].first, geometry));
|
|
||||||
|
|
||||||
if (items[item].second.xa != std::numeric_limits<float>::infinity()) {
|
|
||||||
result.setRight(calculateXPosition(items[item].second, geometry));
|
|
||||||
} else {
|
|
||||||
result.setWidth(item->sizeHint().width());
|
|
||||||
result.moveLeft(result.left() - items[item].second.xr * result.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (items[item].second.ya != std::numeric_limits<float>::infinity()) {
|
|
||||||
result.setBottom(calculateYPosition(items[item].second, geometry));
|
|
||||||
} else {
|
|
||||||
result.setHeight(item->sizeHint().height());
|
|
||||||
result.moveTop(result.top() - items[item].second.yr * result.height());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calculateSizeHint(LayoutItem * item = NULL) {
|
|
||||||
if (item == NULL) {
|
|
||||||
// Recalculate the sizeHint using all items
|
|
||||||
sizeHint = QSizeF();
|
|
||||||
foreach (LayoutItem * item, items.keys()) {
|
|
||||||
if (item) {
|
|
||||||
calculateSizeHint(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Calculate size hint for current item
|
|
||||||
const QRectF scaled = calculateRectangle(item, QRectF(0, 0, 1, 1));
|
|
||||||
|
|
||||||
// qMin(..., 1.0) so that for autosized elements we don't get smaller
|
|
||||||
// size than the item's size itself. The sizeHint for NodeLayout can
|
|
||||||
// not do anything smarter concerning the sizeHint when there are
|
|
||||||
// autosized elements.
|
|
||||||
|
|
||||||
qreal width = item->sizeHint().width() / qMin(scaled.width(), qreal(1.0));
|
|
||||||
qreal height = item->sizeHint().height() / qMin(scaled.height(), qreal(1.0));
|
|
||||||
|
|
||||||
if (width > sizeHint.width()) sizeHint.setWidth(width);
|
|
||||||
if (height > sizeHint.height()) sizeHint.setHeight(height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
NodeLayout::NodeLayout(LayoutItem * parent)
|
|
||||||
: Layout(parent), d(new Private(this))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeLayout::~NodeLayout()
|
|
||||||
{
|
|
||||||
releaseManagedItems();
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::Orientations NodeLayout::expandingDirections() const
|
|
||||||
{
|
|
||||||
return Qt::Horizontal | Qt::Vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::relayout()
|
|
||||||
{
|
|
||||||
foreach (LayoutItem * item, d->items.keys()) {
|
|
||||||
if (item) {
|
|
||||||
item->setGeometry(d->calculateRectangle(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::releaseManagedItems()
|
|
||||||
{
|
|
||||||
foreach (LayoutItem * item, d->items.keys()) {
|
|
||||||
item->unsetManagingLayout(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QSizeF NodeLayout::sizeHint() const
|
|
||||||
{
|
|
||||||
return d->sizeHint;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::addItem(LayoutItem * item)
|
|
||||||
{
|
|
||||||
NodeLayout::addItem(item, NodeCoordinate());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::addItem(LayoutItem * item, NodeCoordinate topLeft, NodeCoordinate bottomRight)
|
|
||||||
{
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->items[item] = QPair<NodeCoordinate, NodeCoordinate>(topLeft, bottomRight);
|
|
||||||
item->setManagingLayout(this);
|
|
||||||
d->calculateSizeHint(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::addItem(LayoutItem * item, NodeCoordinate node, qreal xr, qreal yr)
|
|
||||||
{
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->items[item] = QPair<NodeCoordinate, NodeCoordinate>(node,
|
|
||||||
NodeCoordinate::simple(xr, yr, NodeCoordinate::InnerRelative, NodeCoordinate::InnerRelative));
|
|
||||||
item->setManagingLayout(this);
|
|
||||||
d->calculateSizeHint(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeLayout::removeItem(LayoutItem * item)
|
|
||||||
{
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->unsetManagingLayout(this);
|
|
||||||
d->items.remove(item);
|
|
||||||
d->calculateSizeHint();
|
|
||||||
}
|
|
||||||
|
|
||||||
int NodeLayout::count() const
|
|
||||||
{
|
|
||||||
return d->items.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int NodeLayout::indexOf(LayoutItem * item) const
|
|
||||||
{
|
|
||||||
if (!item) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->items.keys().indexOf(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutItem * NodeLayout::itemAt(int i) const
|
|
||||||
{
|
|
||||||
if (i >= d->items.count()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->items.keys()[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutItem * NodeLayout::takeAt(int i)
|
|
||||||
{
|
|
||||||
if (i >= d->items.count()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutItem * item = itemAt(i);
|
|
||||||
removeItem(item);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user