Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit ab83f607 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Refactor out the old version of absolutePosition

parent ebc6fdc1
......@@ -73,7 +73,7 @@ QPointF KoConnectionShapePrivate::escapeDirection(int handleId) const
KoConnectionPoint::EscapeDirection ed = attachedShape->connectionPoint(connectionPointId).escapeDirection;
if (ed == KoConnectionPoint::AllDirections) {
QPointF handlePoint = q->shapeToDocument(handles[handleId]);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::CenteredPosition);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::Center);
/*
* Determine the best escape direction from the position of the handle point
......@@ -88,11 +88,11 @@ QPointF KoConnectionShapePrivate::escapeDirection(int handleId) const
* of the orthogonal direction.
*/
// define our edge points in the right order
const KoFlake::Position corners[4] = {
KoFlake::BottomRightCorner,
KoFlake::BottomLeftCorner,
KoFlake::TopLeftCorner,
KoFlake::TopRightCorner
const KoFlake::AnchorPosition corners[4] = {
KoFlake::BottomRight,
KoFlake::BottomLeft,
KoFlake::TopLeft,
KoFlake::TopRight
};
QPointF vHandle = handlePoint-centerPoint;
......@@ -130,7 +130,7 @@ QPointF KoConnectionShapePrivate::escapeDirection(int handleId) const
}
} else if (ed == KoConnectionPoint::HorizontalDirections) {
QPointF handlePoint = q->shapeToDocument(handles[handleId]);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::CenteredPosition);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::Center);
// use horizontal direction pointing away from center point
if (handlePoint.x() < centerPoint.x())
direction = QPointF(-1.0, 0.0);
......@@ -138,7 +138,7 @@ QPointF KoConnectionShapePrivate::escapeDirection(int handleId) const
direction = QPointF(1.0, 0.0);
} else if (ed == KoConnectionPoint::VerticalDirections) {
QPointF handlePoint = q->shapeToDocument(handles[handleId]);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::CenteredPosition);
QPointF centerPoint = attachedShape->absolutePosition(KoFlake::Center);
// use vertical direction pointing away from center point
if (handlePoint.y() < centerPoint.y())
direction = QPointF(0.0, -1.0);
......
......@@ -68,15 +68,6 @@ namespace KoFlake
ShapeOnTop ///< return the shape highest z-ordering, regardless of selection.
};
/// position. See KoShape::absolutePosition()
enum Position {
TopLeftCorner, ///< the top left corner
TopRightCorner, ///< the top right corner
BottomLeftCorner, ///< the bottom left corner
BottomRightCorner, ///< the bottom right corner
CenteredPosition ///< the centred corner
};
/**
* Used to see which style type is active
*/
......
......@@ -685,21 +685,6 @@ QPainterPath KoShape::shadowOutline() const
return QPainterPath();
}
QPointF KoShape::absolutePosition(KoFlake::Position anchor) const
{
const QRectF rc = outlineRect();
QPointF point;
switch (anchor) {
case KoFlake::TopLeftCorner: point = rc.topLeft(); break;
case KoFlake::TopRightCorner: point = rc.topRight(); break;
case KoFlake::BottomLeftCorner: point = rc.bottomLeft(); break;
case KoFlake::BottomRightCorner: point = rc.bottomRight(); break;
case KoFlake::CenteredPosition: point = rc.center(); break;
}
return absoluteTransformation(0).map(point);
}
QPointF KoShape::absolutePosition(KoFlake::AnchorPosition anchor) const
{
const QRectF rc = outlineRect();
......@@ -715,18 +700,6 @@ QPointF KoShape::absolutePosition(KoFlake::AnchorPosition anchor) const
return absoluteTransformation(0).map(point);
}
void KoShape::setAbsolutePosition(const QPointF &newPosition, KoFlake::Position anchor)
{
Q_D(KoShape);
QPointF currentAbsPosition = absolutePosition(anchor);
QPointF translate = newPosition - currentAbsPosition;
QTransform translateMatrix;
translateMatrix.translate(translate.x(), translate.y());
applyAbsoluteTransformation(translateMatrix);
notifyChanged();
d->shapeChanged(PositionChanged);
}
void KoShape::setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor)
{
Q_D(KoShape);
......@@ -1952,14 +1925,14 @@ QTransform KoShape::parseOdfTransform(const QString &transform)
scaleMatrix.scale(params[0].toDouble(), params[0].toDouble());
matrix = matrix * scaleMatrix;
} else if (cmd == "skewx") {
QPointF p = absolutePosition(KoFlake::TopLeftCorner);
QPointF p = absolutePosition(KoFlake::TopLeft);
QTransform shearMatrix;
shearMatrix.translate(p.x(), p.y());
shearMatrix.shear(tan(-params[0].toDouble()), 0.0F);
shearMatrix.translate(-p.x(), -p.y());
matrix = matrix * shearMatrix;
} else if (cmd == "skewy") {
QPointF p = absolutePosition(KoFlake::TopLeftCorner);
QPointF p = absolutePosition(KoFlake::TopLeft);
QTransform shearMatrix;
shearMatrix.translate(p.x(), p.y());
shearMatrix.shear(0.0F, tan(-params[0].toDouble()));
......
......@@ -801,9 +801,7 @@ public:
* @param anchor The place on the (unaltered) shape that you want the position of.
* @return the point that is the absolute, centered position of this shape.
*/
QPointF absolutePosition(KoFlake::Position anchor = KoFlake::CenteredPosition) const;
QPointF absolutePosition(KoFlake::AnchorPosition anchor) const;
QPointF absolutePosition(KoFlake::AnchorPosition anchor = KoFlake::Center) const;
/**
* Move this shape to an absolute position where the end location will be the same
......@@ -819,9 +817,7 @@ public:
* @param newPosition the new absolute center of the shape.
* @param anchor The place on the (unaltered) shape that you set the position of.
*/
void setAbsolutePosition(const QPointF &newPosition, KoFlake::Position anchor = KoFlake::CenteredPosition);
void setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor);
void setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor = KoFlake::Center);
/**
* Set a data object on the shape to be used by an application.
......
......@@ -510,12 +510,12 @@ bool BoundingBoxSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy *pr
rect.moveCenter(mousePosition);
QPointF snappedPoint = mousePosition;
KoFlake::Position pointId[5] = {
KoFlake::TopLeftCorner,
KoFlake::TopRightCorner,
KoFlake::BottomRightCorner,
KoFlake::BottomLeftCorner,
KoFlake::CenteredPosition
KoFlake::AnchorPosition pointId[5] = {
KoFlake::TopLeft,
KoFlake::TopRight,
KoFlake::BottomRight,
KoFlake::BottomLeft,
KoFlake::Center
};
QList<KoShape*> shapes = proxy->shapesInRect(rect, true);
......
......@@ -116,8 +116,8 @@ void KoShapeGroupCommand::redo()
if (d->shouldNormalize && dynamic_cast<KoShapeGroup*>(d->container)) {
QRectF bound = d->containerBoundingRect();
QPointF oldGroupPosition = d->container->absolutePosition(KoFlake::TopLeftCorner);
d->container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeftCorner);
QPointF oldGroupPosition = d->container->absolutePosition(KoFlake::TopLeft);
d->container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeft);
d->container->setSize(bound.size());
if (d->container->shapeCount() > 0) {
......@@ -190,7 +190,7 @@ void KoShapeGroupCommand::undo()
}
if (d->shouldNormalize && dynamic_cast<KoShapeGroup*>(d->container)) {
QPointF oldGroupPosition = d->container->absolutePosition(KoFlake::TopLeftCorner);
QPointF oldGroupPosition = d->container->absolutePosition(KoFlake::TopLeft);
if (d->container->shapeCount() > 0) {
bool boundingRectInitialized = false;
QRectF bound;
......@@ -207,7 +207,7 @@ void KoShapeGroupCommand::undo()
Q_FOREACH (KoShape * child, d->container->shapes())
child->setAbsolutePosition(child->absolutePosition() + positionOffset);
d->container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeftCorner);
d->container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeft);
d->container->setSize(bound.size());
}
}
......
......@@ -96,11 +96,11 @@ void TestPosition::testAbsolutePosition()
shape1->setPosition(QPointF(10, 10));
QCOMPARE(shape1->absolutePosition(), QPointF(10 + 25, 10 + 25));
QCOMPARE(shape1->absolutePosition(KoFlake::CenteredPosition), QPointF(10 + 25, 10 + 25));
QCOMPARE(shape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(10 + 50, 10));
QCOMPARE(shape1->absolutePosition(KoFlake::BottomRightCorner), QPointF(10, 10 + 50));
QCOMPARE(shape1->absolutePosition(KoFlake::Center), QPointF(10 + 25, 10 + 25));
QCOMPARE(shape1->absolutePosition(KoFlake::TopLeft), QPointF(10 + 50, 10));
QCOMPARE(shape1->absolutePosition(KoFlake::BottomRight), QPointF(10, 10 + 50));
QCOMPARE(container2->absolutePosition(KoFlake::TopLeftCorner), QPointF(200, 200));
QCOMPARE(container2->absolutePosition(KoFlake::TopLeft), QPointF(200, 200));
}
void TestPosition::testSetAbsolutePosition()
......@@ -135,20 +135,20 @@ void TestPosition::testSetAbsolutePosition2()
shape1->setAbsolutePosition(QPointF(100, 100));
QCOMPARE(shape1->absolutePosition(), QPointF(100, 100));
shape1->setAbsolutePosition(QPointF(100, 100), KoFlake::TopLeftCorner);
QCOMPARE(shape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(100, 100));
shape1->setAbsolutePosition(QPointF(100, 100), KoFlake::TopLeft);
QCOMPARE(shape1->absolutePosition(KoFlake::TopLeft), QPointF(100, 100));
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::BottomRightCorner);
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::BottomRight);
QCOMPARE(childShape1->position(), QPointF(-150, -150));
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::BottomLeftCorner);
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::BottomLeft);
QCOMPARE(childShape1->position(), QPointF(-100, -150));
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::TopRightCorner);
childShape1->setAbsolutePosition(QPointF(0, 0), KoFlake::TopRight);
QCOMPARE(childShape1->position(), QPointF(-150, -100));
container2->setInheritsTransform(childShape2, true);
childShape2->setAbsolutePosition(QPointF(0, 0), KoFlake::TopLeftCorner);
childShape2->setAbsolutePosition(QPointF(0, 0), KoFlake::TopLeft);
QCOMPARE(childShape2->position(), QPointF(-200, 200));
}
......
......@@ -142,7 +142,7 @@ void TestShapeContainer::testScaling()
QList<QPointF> oldPositions;
for(int i=0; i< transformShapes.size(); i++) {
oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeftCorner));
oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft));
}
KoShapeTransformCommand* transformCommand;
......@@ -150,7 +150,7 @@ void TestShapeContainer::testScaling()
transformCommand->redo();
for(int i=0; i< transformShapes.size(); i++) {
QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeftCorner), oldPositions.at(i)*0.5);
QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft), oldPositions.at(i)*0.5);
}
transformShapes.takeLast();
......@@ -158,7 +158,7 @@ void TestShapeContainer::testScaling()
ungroupCmd->redo();
for(int i=0; i< transformShapes.size(); i++) {
QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeftCorner), oldPositions.at(i)*0.5);
QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft), oldPositions.at(i)*0.5);
}
}
......@@ -200,15 +200,15 @@ void TestShapeContainer::testScaling2()
QList<QPointF> oldPositions;
for(int i=0; i< transformShapes.size(); i++) {
oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeftCorner));
oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft));
}
KoShapeTransformCommand* transformCommand;
transformCommand = new KoShapeTransformCommand(transformShapes, oldTransformations, newTransformations);
transformCommand->redo();
QRectF r1(shape1->absolutePosition(KoFlake::TopLeftCorner), shape1->absolutePosition(KoFlake::BottomRightCorner));
QRectF r2(shape2->absolutePosition(KoFlake::TopLeftCorner), shape2->absolutePosition(KoFlake::BottomRightCorner));
QRectF r1(shape1->absolutePosition(KoFlake::TopLeft), shape1->absolutePosition(KoFlake::BottomRight));
QRectF r2(shape2->absolutePosition(KoFlake::TopLeft), shape2->absolutePosition(KoFlake::BottomRight));
QSizeF shapeSize=r1.united(r2).size();
selection = new KoSelection();
......
......@@ -145,19 +145,19 @@ void TestShapeGroupCommand::testToplevelGroup()
cmd1->redo();
QCOMPARE(toplevelShape1->parent(), toplevelGroup);
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 50));
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(50, 50));
QCOMPARE(toplevelShape1->position(), QPointF(0, 0));
QCOMPARE(toplevelShape2->parent(), toplevelGroup);
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 150));
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(50, 150));
QCOMPARE(toplevelShape2->position(), QPointF(0, 100));
QCOMPARE(toplevelGroup->position(), QPointF(50, 50));
cmd1->undo();
QVERIFY(toplevelShape1->parent() == 0);
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 50));
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(50, 50));
QCOMPARE(toplevelShape1->position(), QPointF(50, 50));
QVERIFY(toplevelShape2->parent() == 0);
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 150));
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(50, 150));
QCOMPARE(toplevelShape2->position(), QPointF(50, 150));
}
......@@ -180,20 +180,20 @@ void TestShapeGroupCommand::testSublevelGroup()
cmd1->redo();
QCOMPARE(toplevelShape1->parent(), toplevelGroup);
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 50));
QCOMPARE(toplevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(50, 50));
QCOMPARE(toplevelShape1->position(), QPointF(0, 0));
QCOMPARE(toplevelShape2->parent(), toplevelGroup);
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(50, 150));
QCOMPARE(toplevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(50, 150));
QCOMPARE(toplevelShape2->position(), QPointF(0, 100));
QCOMPARE(toplevelGroup->position(), QPointF(50, 50));
QCOMPARE(sublevelShape1->parent(), sublevelGroup);
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 150));
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(150, 150));
QCOMPARE(sublevelShape1->position(), QPointF(0, 0));
QCOMPARE(sublevelShape2->parent(), sublevelGroup);
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(250, 150));
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(250, 150));
QCOMPARE(sublevelShape2->position(), QPointF(100, 0));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 150));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeft), QPointF(150, 150));
QCOMPARE(sublevelGroup->position(), QPointF(100, 100));
// check that the shapes are added in the correct order
......@@ -218,14 +218,14 @@ void TestShapeGroupCommand::testAddToToplevelGroup()
cmd2->redo();
QVERIFY(extraShape1->parent() == toplevelGroup);
QCOMPARE(extraShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 50));
QCOMPARE(extraShape1->absolutePosition(KoFlake::TopLeft), QPointF(150, 50));
QCOMPARE(extraShape1->position(), QPointF(100, 0));
QCOMPARE(toplevelGroup->position(), QPointF(50, 50));
cmd2->undo();
QVERIFY(extraShape1->parent() == 0);
QCOMPARE(extraShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 50));
QCOMPARE(extraShape1->absolutePosition(KoFlake::TopLeft), QPointF(150, 50));
QCOMPARE(extraShape1->position(), QPointF(150, 50));
QCOMPARE(toplevelGroup->position(), QPointF(50, 50));
}
......@@ -246,25 +246,25 @@ void TestShapeGroupCommand::testAddToSublevelGroup()
cmd2->redo();
QVERIFY(extraShape2->parent() == sublevelGroup);
QCOMPARE(extraShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(250, 50));
QCOMPARE(extraShape2->absolutePosition(KoFlake::TopLeft), QPointF(250, 50));
QCOMPARE(extraShape2->position(), QPointF(100, 0));
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 150));
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(150, 150));
QCOMPARE(sublevelShape1->position(), QPointF(0, 100));
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(250, 150));
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(250, 150));
QCOMPARE(sublevelShape2->position(), QPointF(100, 100));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 50));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeft), QPointF(150, 50));
QCOMPARE(sublevelGroup->position(), QPointF(100, 0));
cmd2->undo();
QVERIFY(extraShape2->parent() == 0);
QCOMPARE(extraShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(250, 50));
QCOMPARE(extraShape2->absolutePosition(KoFlake::TopLeft), QPointF(250, 50));
QCOMPARE(extraShape2->position(), QPointF(250, 50));
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 150));
QCOMPARE(sublevelShape1->absolutePosition(KoFlake::TopLeft), QPointF(150, 150));
QCOMPARE(sublevelShape1->position(), QPointF(0, 0));
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeftCorner), QPointF(250, 150));
QCOMPARE(sublevelShape2->absolutePosition(KoFlake::TopLeft), QPointF(250, 150));
QCOMPARE(sublevelShape2->position(), QPointF(100, 0));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeftCorner), QPointF(150, 150));
QCOMPARE(sublevelGroup->absolutePosition(KoFlake::TopLeft), QPointF(150, 150));
QCOMPARE(sublevelGroup->position(), QPointF(100, 100));
}
......
This diff is collapsed.
......@@ -194,26 +194,26 @@ void KisShapeCommandsTest::testResizeShape(bool normalizeGroup)
chk.checkImage(p.image, "00_initial_layer_update");
qDebug() << "Before:";
qDebug() << ppVar(group->absolutePosition(KoFlake::TopLeftCorner));
qDebug() << ppVar(group->absolutePosition(KoFlake::BottomRightCorner));
qDebug() << ppVar(group->absolutePosition(KoFlake::TopLeft));
qDebug() << ppVar(group->absolutePosition(KoFlake::BottomRight));
qDebug() << ppVar(group->outlineRect());
qDebug() << ppVar(group->transformation());
QCOMPARE(group->absolutePosition(KoFlake::TopLeftCorner), QPointF(5,5));
QCOMPARE(group->absolutePosition(KoFlake::BottomRightCorner), QPointF(60,60));
QCOMPARE(group->absolutePosition(KoFlake::TopLeft), QPointF(5,5));
QCOMPARE(group->absolutePosition(KoFlake::BottomRight), QPointF(60,60));
const QPointF stillPoint = group->absolutePosition(KoFlake::BottomRightCorner);
const QPointF stillPoint = group->absolutePosition(KoFlake::BottomRight);
KoFlake::resizeShape(group, 1.2, 1.4, stillPoint, false, true, QTransform());
qDebug() << "After:";
qDebug() << ppVar(group->absolutePosition(KoFlake::TopLeftCorner));
qDebug() << ppVar(group->absolutePosition(KoFlake::BottomRightCorner));
qDebug() << ppVar(group->absolutePosition(KoFlake::TopLeft));
qDebug() << ppVar(group->absolutePosition(KoFlake::BottomRight));
qDebug() << ppVar(group->outlineRect());
qDebug() << ppVar(group->transformation());
QCOMPARE(group->absolutePosition(KoFlake::TopLeftCorner), QPointF(-6,-17));
QCOMPARE(group->absolutePosition(KoFlake::BottomRightCorner), QPointF(60,60));
QCOMPARE(group->absolutePosition(KoFlake::TopLeft), QPointF(-6,-17));
QCOMPARE(group->absolutePosition(KoFlake::BottomRight), QPointF(60,60));
}
void KisShapeCommandsTest::testResizeShape()
......
......@@ -15,7 +15,6 @@ set(kritawidgets_LIB_SRCS
KoResourceItemChooserContextMenu.cpp
KoAspectButton.cpp
KoPagePreviewWidget.cpp
KoPositionSelector.cpp
KoSliderCombo.cpp
KoColorPopupButton.cpp
KoConfigAuthorPage.cpp
......
/* This file is part of the KDE project
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
* Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
*
* 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.
*/
#include "KoPositionSelector.h"
#include <QRadioButton>
#include <QGridLayout>
#include <QButtonGroup>
#include <QPainter>
#include <WidgetsDebug.h>
#include <QStyleOption>
#define GAP 0
class Q_DECL_HIDDEN KoPositionSelector::Private
{
public:
Private()
: position(KoFlake::TopLeftCorner)
{
topLeft = createButton(KoFlake::TopLeftCorner);
topLeft->setChecked(true);
topRight = createButton(KoFlake::TopRightCorner);
center = createButton(KoFlake::CenteredPosition);
bottomRight = createButton(KoFlake::BottomRightCorner);
bottomLeft = createButton(KoFlake::BottomLeftCorner);
}
QRadioButton *createButton(int id) {
QRadioButton *b = new QRadioButton();
buttonGroup.addButton(b, id);
return b;
}
QRadioButton *topLeft, *topRight, *center, *bottomRight, *bottomLeft;
QButtonGroup buttonGroup;
KoFlake::Position position;
};
class RadioLayout : public QLayout {
public:
RadioLayout(QWidget *parent)
: QLayout(parent)
{
}
~RadioLayout() override
{
Q_FOREACH ( const Item & item, items )
delete item.child;
items.clear();
}
void setGeometry (const QRect &geom) override {
QSize prefSize = calcSizes();
qreal columnWidth, rowHeight;
if (geom.width() <= minimum.width())
columnWidth = geom.width() / (qreal) maxCol;
else
columnWidth = prefSize.width() + GAP;
if (geom.height() <= minimum.height())
rowHeight = geom.height() / (qreal) maxRow;
else
rowHeight = prefSize.height() + GAP;
// padding inside row and column so that radio button is centered
QPoint padding( qRound(0.5 * (columnWidth - prefSize.width())), qRound(0.5 * (rowHeight - prefSize.height())));
// offset so that all the radio button are centered within the widget
qreal offsetX = 0.5 * (geom.width()- static_cast<qreal>(maxCol) * columnWidth);
qreal offsetY = 0.5 * (geom.height() - static_cast<qreal>(maxRow) * rowHeight);
QPoint offset( qRound(offsetX), qRound(offsetY));
Q_FOREACH (const Item & item, items) {
QPoint point( qRound(item.column * columnWidth), qRound(item.row * rowHeight) );
QRect rect(point + offset + padding + geom.topLeft(), prefSize);
item.child->setGeometry(rect);
}
}
QSize calcSizes() {
QSize prefSize;
maxRow = 0;
maxCol = 0;
Q_FOREACH (const Item & item, items) {
if(prefSize.isEmpty()) {
QAbstractButton *but = dynamic_cast<QAbstractButton*> (item.child->widget());
Q_ASSERT(but);
QStyleOptionButton opt;
opt.initFrom(but);
prefSize = QSize(but->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, &opt, but),
but->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight, &opt, but));
}
maxRow = qMax(maxRow, item.row);
maxCol = qMax(maxCol, item.column);
}
maxCol++; maxRow++; // due to being zero-based.
preferred = QSize(maxCol * prefSize.width() + (maxCol-1) * GAP, maxRow * prefSize.height() + (maxRow-1) * GAP);
minimum = QSize(maxCol * prefSize.width(), maxRow * prefSize.height());
return prefSize;
}
QLayoutItem *itemAt (int index) const override {
if( index < count() )
return items.at(index).child;
else
return 0;
}
QLayoutItem *takeAt (int index) override {
Q_ASSERT(index < count());
Item item = items.takeAt(index);
return item.child;
}
int count () const override {
return items.count();
}
void addItem(QLayoutItem *) override {
Q_ASSERT(0);
}
QSize sizeHint() const override {
if(preferred.isEmpty())
const_cast<RadioLayout*> (this)->calcSizes();
return preferred;
}
QSize minimumSize() const override {
if(minimum.isEmpty())
const_cast<RadioLayout*> (this)->calcSizes();
return minimum;
}
void addWidget(QRadioButton *widget, int row, int column) {
addChildWidget(widget);
Item newItem;
newItem.child = new QWidgetItem(widget);
newItem.row = row;
newItem.column = column;
items.append(newItem);
}
private:
struct Item {
QLayoutItem *child;
int column;
int row;
};
QList<Item> items;
QSize preferred, minimum;
int maxCol, maxRow;
};
KoPositionSelector::KoPositionSelector(QWidget *parent)
: QWidget(parent),
d(new Private())
{
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
RadioLayout *lay = new RadioLayout(this);
lay->addWidget(d->topLeft, 0, 0);
lay->addWidget(d->topRight, 0, 2);
lay->addWidget(d->center, 1, 1);
lay->addWidget(d->bottomRight, 2, 2);
lay->addWidget(d->bottomLeft, 2, 0);
setLayout(lay);
connect(&d->buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(positionChanged(int)));
}
KoPositionSelector::~KoPositionSelector() {
delete d;
}
KoFlake::Position KoPositionSelector::position() const {
return d->position;
}
void KoPositionSelector::setPosition(KoFlake::Position position) {
d->position = position;
switch(d->position) {
case KoFlake::TopLeftCorner:
d->topLeft->setChecked(true);
break;
case KoFlake::TopRightCorner:
d->topRight->setChecked(true);
break;
case KoFlake::CenteredPosition:
d->center->setChecked(true);
break;
case KoFlake::BottomLeftCorner:
d->bottomLeft->setChecked(true);
break;
case KoFlake::BottomRightCorner:
d->bottomRight->setChecked(true);
break;
}
}
void KoPositionSelector::positionChanged(int position) {
d->position = static_cast<KoFlake::Position> (position);
emit positionSelected(d->position);