Commit 16da0804 authored by Thomas Zander's avatar Thomas Zander

First (simple) version of connections between shapes.

This is just playing around, not much in API stability yet.

svn path=/trunk/koffice/; revision=637712
parent 257a62f1
......@@ -19,6 +19,7 @@ set(flake_SRCS
KoShape.cpp
KoShapeContainer.cpp
KoShapeGroup.cpp
KoShapeConnection.cpp
KoShapeManager.cpp
KoShapeMoveStrategy.cpp
KoShapeResizeStrategy.cpp
......
......@@ -38,6 +38,7 @@
#include <QPainter>
#include <QVariant>
#include <QPainterPath>
#include <QList>
#include <kdebug.h>
......@@ -98,6 +99,7 @@ public:
KoShapeApplicationData *appData;
QBrush backgroundBrush; ///< Stands for the background color / fill etc.
KoShapeBorderModel *border; ///< points to a border, or 0 if there is no border
QList<KoShapeConnection*> connections;
};
KoShape::KoShape()
......@@ -316,6 +318,11 @@ QMatrix KoShape::transformationMatrix(const KoViewConverter *converter) const {
}
matrix.shear( d->shearX, d->shearY );
matrix.scale( d->scaleX, d->scaleY );
if(false && converter) {
double zoomX, zoomY;
converter->zoom(&zoomX, &zoomY);
matrix.scale(zoomX, zoomY);
}
return matrix;
}
......@@ -602,6 +609,19 @@ const QMatrix& KoShape::matrix() const {
return d->matrix;
}
void KoShape::addConnection(KoShapeConnection *connection) {
d->connections.append(connection);
foreach(KoShapeManager *sm, d->shapeManagers)
sm->addShapeConnection( connection );
}
void KoShape::removeConnection(KoShapeConnection *connection) {
d->connections.removeAll(connection);
}
QList<KoShapeConnection*> KoShape::connections() const {
return d->connections;
}
// static
void KoShape::applyConversion(QPainter &painter, const KoViewConverter &converter) {
......
......@@ -39,6 +39,7 @@ class QVariant;
class KoSelection;
class KoPointerEvent;
class KoShapeContainer;
class KoShapeConnection;
class KoShapeBorderModel;
class KoShapeManager;
class KoShapeUserData;
......@@ -552,6 +553,8 @@ public:
*/
static void applyConversion(QPainter &painter, const KoViewConverter &converter);
QList<KoShapeConnection*> connections() const;
protected:
/**
* @brief Get the tag name used for saving
......@@ -626,6 +629,10 @@ protected:
/// return the current matrix that contains the rotation/scale/position of this shape
const QMatrix& matrix() const;
friend class KoShapeConnection;
void addConnection(KoShapeConnection *connection);
void removeConnection(KoShapeConnection *connection);
private:
/**
* @brief Get the style used for the shape
......
/* This file is part of the KDE project
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
*
* 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 "KoShapeConnection.h"
#include "KoShape.h"
#include "KoViewConverter.h"
#include <QPainter>
#include <QPen>
#include <QPointF>
class KoShapeConnection::Private {
public:
Private(KoShape *from, KoShape *to) : shape1(from), shape2(to) {}
KoShape * const shape1;
KoShape * const shape2;
QPointF point1, point2;
/*
Properties like ConnectionType
*/
};
KoShapeConnection::KoShapeConnection(KoShape *from, KoShape *to)
: d(new Private(from, to))
{
d->shape1->addConnection(this);
d->shape2->addConnection(this);
}
KoShapeConnection::~KoShapeConnection() {
d->shape1->removeConnection(this);
d->shape2->removeConnection(this);
delete d;
}
void KoShapeConnection::paint(QPainter &painter, const KoViewConverter &converter) {
QPointF a = converter.documentToView(d->shape1->absolutePosition());
QPointF b = converter.documentToView(d->shape2->absolutePosition());
QPen pen(Qt::black);
painter.setPen(pen);
painter.drawLine(a, b);
}
KoShape *KoShapeConnection::shape1() const {
return d->shape1;
}
KoShape *KoShapeConnection::shape2() const {
return d->shape2;
}
/* This file is part of the KDE project
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
*
* 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.
*/
#ifndef KOSHAPECONNECTION_H
#define KOSHAPECONNECTION_H
#include <flake_export.h>
class KoShape;
class QPainter;
class KoViewConverter;
class FLAKE_EXPORT KoShapeConnection {
public:
enum ConnectionType {
TautConnection,
CurvedConnection
// etc?
};
KoShapeConnection(KoShape *from, KoShape *to = 0);
~KoShapeConnection();
void paint(QPainter &painter, const KoViewConverter &converter);
KoShape *shape1() const;
KoShape *shape2() const;
private:
class Private;
Private * const d;
};
/*
TODO
KoShapeConnectionManager as a member of KoShapeManager ? Or 'integrated' in the KoShapeManager ?
This class will have an rtree of all the connectors.
This class will recalculate the perfect path when shapes move/etc.
ConnectionTool (under koffice/plugins)
Used to create new connections.
Add a strategy for InteractionTool that when it selects a connection it can be used to change
the properties or delete it.
*/
#endif
......@@ -22,6 +22,7 @@
#include "KoShapeManager.h"
#include "KoSelection.h"
#include "KoShape.h"
#include "KoShapeConnection.h"
#include "KoCanvasBase.h"
#include "KoShapeContainer.h"
#include "KoShapeBorderModel.h"
......@@ -33,13 +34,14 @@
class KoShapeManager::Private {
public:
Private(KoCanvasBase *c) : canvas(c), tree(4, 2) {
Private(KoCanvasBase *c) : canvas(c), tree(4, 2), connectionTree(4, 2) {
selection = new KoSelection();
}
QList<KoShape *> shapes;
KoSelection * selection;
KoCanvasBase * canvas;
KoRTree<KoShape *> tree;
KoRTree<KoShapeConnection *> connectionTree;
QSet<KoShape *> aggregate4update;
QHash<KoShape*, int> shapeIndexesBeforeUpdate;
};
......@@ -176,6 +178,12 @@ void KoShapeManager::paint( QPainter &painter, const KoViewConverter &converter,
painter.restore(); // for the matrix
}
foreach(KoShapeConnection *sc, d->connectionTree.intersects( clipRegion.boundingRect() ) ) {
painter.save();
sc->paint( painter, converter );
painter.restore();
}
#ifdef KOFFICE_RTREE_DEBUG
// paint tree
double zx = 0;
......@@ -331,4 +339,11 @@ KoSelection * KoShapeManager::selection() const {
return d->selection;
}
void KoShapeManager::addShapeConnection(KoShapeConnection *connection) {
// TODO remove this simple implementation, should use the proper start and end point.
QRectF br = connection->shape1()->boundingRect();
br.unite(connection->shape1()->boundingRect());
d->connectionTree.insert( br, connection );
}
#include "KoShapeManager.moc"
......@@ -33,6 +33,7 @@ class KoShape;
class KoSelection;
class KoViewConverter;
class KoCanvasBase;
class KoShapeConnection;
class QPainter;
class QPointF;
......@@ -134,6 +135,8 @@ public:
*/
void notifyShapeChanged( KoShape * shape );
void addShapeConnection(KoShapeConnection *connection);
private:
/**
* Update the tree when there are shapes in m_aggregate4update. This is done so not all
......
......@@ -6,8 +6,8 @@ include_directories( ${FLAKE_INCLUDES} ${QT_INCLUDES} ${KOFFICECORE_INCLUDES} )
SET ( defaulttools_SRCS
Plugin.cpp
#ConnectionTool.cpp
#ConnectionToolFactory.cpp
ConnectionTool.cpp
ConnectionToolFactory.cpp
ZoomTool.cpp
)
......
/* This file is part of the KDE project
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
*
* 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 "ConnectionTool.h"
#include <KoPointerEvent.h>
#include <KoCanvasBase.h>
#include <KoViewConverter.h>
#include <KoShapeManager.h>
#include <KoShape.h>
#include <KoShapeConnection.h>
#include <kdebug.h>
ConnectionTool::ConnectionTool(KoCanvasBase *canvas)
: KoTool(canvas),
m_startShape(0)
{
}
ConnectionTool::~ConnectionTool() {
}
void ConnectionTool::paint( QPainter &painter, KoViewConverter &converter ) {
QList<KoShape*> repaints = m_shapesPaintedWithConnections;
if(m_startShape)
repaints.append(m_startShape);
double zoomX, zoomY;
converter.zoom(&zoomX, &zoomY);
foreach(KoShape *shape, repaints) {
// TODO check if they are not clipped.
QMatrix matrix = shape->transformationMatrix(&converter);
matrix.scale(zoomX, zoomY);
foreach(QPointF point, shape->connectors()) {
point = matrix.map(point);
painter.fillRect(QRectF(QPointF(point.x() - 2, point.y() -2) , QSizeF(4, 4)), QBrush(Qt::red));
}
}
}
void ConnectionTool::mousePressEvent( KoPointerEvent *event ) {
QRectF region = m_canvas->viewConverter()->viewToDocument(QRectF(0, 0, 20, 20));
region.moveTo(event->point.x() - region.width() / 2, event->point.y() - region.height() / 2);
foreach(KoShape *shape, m_canvas->shapeManager()->shapesAt(region)) {
QMatrix matrix = shape->transformationMatrix(0);
foreach(QPointF point, shape->connectors()) {
QPointF p = matrix.map(point);
QPointF distance = m_canvas->viewConverter()->documentToView(p - event->point);
if(qAbs(distance.x()) < 10 && qAbs(distance.y()) < 10) { // distance is in pixels.
if(m_startShape == 0) {
m_startShape = shape;
m_startPoint = point;
}
else {
createConnection(m_startShape, m_startPoint, shape, point);
m_startShape = 0;
}
}
}
}
}
void ConnectionTool::mouseMoveEvent( KoPointerEvent *event ) {
QRectF region = m_canvas->viewConverter()->viewToDocument(QRectF(0, 0, 50, 50));
region.moveTo(event->point.x() - region.width() / 2, event->point.y() - region.height() / 2);
QList<KoShape*> oldList = m_shapesPaintedWithConnections;
m_shapesPaintedWithConnections.clear();
foreach(KoShape *shape, m_canvas->shapeManager()->shapesAt(region)) {
if(shape->connectors().isEmpty())
continue;
if(! oldList.contains(shape))
// TODO do a for loop to repaint only the actual points.
shape->repaint(); // because it will have connections painted on top.
m_shapesPaintedWithConnections.append(shape);
}
foreach(KoShape *shape, oldList) {
if(! m_shapesPaintedWithConnections.contains(shape))
// TODO do a for loop to repaint only the actual points.
shape->repaint(); // because it used to have connections painted, but no longer will.
}
}
void ConnectionTool::mouseReleaseEvent( KoPointerEvent *event ) {
}
void ConnectionTool::activate (bool temporary) {
Q_UNUSED(temporary);
useCursor(Qt::ArrowCursor, true);
m_startShape = 0;
}
void ConnectionTool::deactivate() {
m_startShape = 0;
}
void ConnectionTool::createConnection(KoShape *shape1, QPointF point1, KoShape *shape2, QPointF point2) {
kDebug() << "create Connection!\n";
KoShapeConnection *connection = new KoShapeConnection(shape1, shape2); // will add itself.
}
#include "ConnectionTool.moc"
/* This file is part of the KDE project
* Copyright (C) 2006-2007 Thomas Zander <zander@kde.org>
*
* 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.
*/
#ifndef CONNECTIONTOOL_H
#define CONNECTIONTOOL_H
#include <KoTool.h>
#include <QPointF>
class KoShape;
class ConnectionTool : public KoTool {
Q_OBJECT
public:
explicit ConnectionTool(KoCanvasBase *canvas);
~ConnectionTool();
/// reimplemented from superclass
void paint( QPainter &painter, KoViewConverter &converter );
/// reimplemented from superclass
void mousePressEvent( KoPointerEvent *event ) ;
/// reimplemented from superclass
void mouseMoveEvent( KoPointerEvent *event );
/// reimplemented from superclass
void mouseReleaseEvent( KoPointerEvent *event );
/// reimplemented from superclass
void activate (bool temporary=false);
/// reimplemented from superclass
void deactivate();
private:
void createConnection(KoShape *shape1, QPointF point1, KoShape *shape2, QPointF point2);
private:
KoShape *m_startShape;
QPointF m_startPoint;
QList<KoShape*> m_shapesPaintedWithConnections;
};
#endif
/* This file is part of the KDE project
* Copyright (C) 2006 Thomas Zander <zander@kde.org>
*
* 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 "ConnectionToolFactory.h"
#include "ConnectionTool.h"
#include <klocale.h>
#include <kdebug.h>
ConnectionToolFactory::ConnectionToolFactory(QObject *parent)
: KoToolFactory(parent, "ConnectionToolFactory_ID", i18n("Connection tool"))
{
kDebug() << "ConnectionToolFactory::ConnectionToolFactory\n";
setToolTip (i18n("Connection Creation tool"));
setToolType (mainToolType());
//setIcon ("connections");
setPriority (9);
}
ConnectionToolFactory::~ConnectionToolFactory() {
}
KoTool * ConnectionToolFactory::createTool(KoCanvasBase *canvas) {
return new ConnectionTool(canvas);
}
#include "ConnectionToolFactory.moc"
/* This file is part of the KDE project
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
*
* 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.
*/
#ifndef CONNECTIONTOOLFACTORY_H
#define CONNECTIONTOOLFACTORY_H
#include <KoToolFactory.h>
#include <QStringList>
class ConnectionToolFactory : public KoToolFactory {
Q_OBJECT
public:
explicit ConnectionToolFactory(QObject *parent);
~ConnectionToolFactory();
KoTool * createTool(KoCanvasBase *canvas);
};
#endif
......@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
#include "Plugin.h"
//#include "ConnectionToolFactory.h"
#include "ConnectionToolFactory.h"
#include "ZoomTool.h"
#include <KoShapeRegistry.h>
......@@ -25,12 +25,12 @@
#include <kgenericfactory.h>
K_EXPORT_COMPONENT_FACTORY(connectiontool, KGenericFactory<Plugin>( "Plugin" ) )
K_EXPORT_COMPONENT_FACTORY(defaulttools, KGenericFactory<Plugin>( "Plugin" ) )
Plugin::Plugin(QObject * parent, const QStringList &)
: QObject(parent)
{
//KoToolRegistry::instance()->add(new ConnectionToolFactory(parent));
KoToolRegistry::instance()->add(new ConnectionToolFactory(parent));
KoToolRegistry::instance()->add(new ZoomToolFactory(parent));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment