Esempio n. 1
0
void ConnectionTool::repaintDecorations()
{
    const qreal radius = handleRadius();
    QRectF repaintRect;

    if (m_currentShape) {
        repaintRect = m_currentShape->boundingRect();
        canvas()->updateCanvas(repaintRect.adjusted(-radius, -radius, radius, radius));
        KoConnectionShape * connectionShape = dynamic_cast<KoConnectionShape*>(m_currentShape);
        if (!m_resetPaint && m_currentShape->isVisible(true) && !connectionShape) {
            // only paint connection points of textShapes not inside a tos container and other shapes
            if ( !(m_currentShape->shapeId() == TextShape_SHAPEID &&
                    dynamic_cast<KoTosContainer*>(m_currentShape->parent())) ) {
                KoConnectionPoints connectionPoints = m_currentShape->connectionPoints();
                KoConnectionPoints::const_iterator cp = connectionPoints.constBegin();
                KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd();
                for(; cp != lastCp; ++cp) {
                    repaintRect = handleGrabRect(m_currentShape->shapeToDocument(cp.value().position));
                    canvas()->updateCanvas(repaintRect.adjusted(-radius, -radius, radius, radius));
                }
            }
        }
        if (m_editMode == EditConnection) {
            if (connectionShape) {
                QPointF handlePos = connectionShape->handlePosition(m_activeHandle);
                handlePos = connectionShape->shapeToDocument(handlePos);
                repaintRect = handlePaintRect(handlePos);
                canvas()->updateCanvas(repaintRect.adjusted(-radius, -radius, radius, radius));
            }
        }
    }
    if (m_resetPaint) {
        QList<KoShape*> shapes = canvas()->shapeManager()->shapes();
        for (QList<KoShape*>::const_iterator end = shapes.constBegin(); end !=  shapes.constEnd(); ++end) {
            KoShape* shape = *end;
            if (!dynamic_cast<KoConnectionShape*>(shape)) {
                // only paint connection points of textShapes not inside a tos container and other shapes
                if (shape->shapeId() == TextShape_SHAPEID && dynamic_cast<KoTosContainer*>(shape->parent()))
                    continue;

                KoConnectionPoints connectionPoints = shape->connectionPoints();
                KoConnectionPoints::const_iterator cp = connectionPoints.constBegin();
                KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd();
                for(; cp != lastCp; ++cp) {
                    repaintRect = handleGrabRect(shape->shapeToDocument(cp.value().position));
                    canvas()->updateCanvas(repaintRect.adjusted(-radius, -radius, radius, radius));
                }
            }
        }
    }
    m_resetPaint = false;
}
Esempio n. 2
0
KoConnectionShape * ConnectionTool::nearestConnectionShape(const QList<KoShape*> &shapes, const QPointF &mousePos) const
{
    int grabDistance = grabSensitivity();

    KoConnectionShape * nearestConnectionShape = 0;
    qreal minSquaredDistance = HUGE_VAL;
    const qreal maxSquaredDistance = grabDistance*grabDistance;

    foreach(KoShape *shape, shapes) {
        KoConnectionShape * connectionShape = dynamic_cast<KoConnectionShape*>(shape);
        if (!connectionShape || !connectionShape->isParametricShape())
            continue;

        // convert document point to shape coordinates
        QPointF p = connectionShape->documentToShape(mousePos);
        // our region of interest, i.e. a region around our mouse position
        QRectF roi = handleGrabRect(p);

        // check all segments of this shape which intersect the region of interest
        QList<KoPathSegment> segments = connectionShape->segmentsAt(roi);
        foreach (const KoPathSegment &s, segments) {
            qreal nearestPointParam = s.nearestPoint(p);
            QPointF nearestPoint = s.pointAt(nearestPointParam);
            QPointF diff = p - nearestPoint;
            qreal squaredDistance = diff.x()*diff.x() + diff.y()*diff.y();
            // are we within the allowed distance ?
            if (squaredDistance > maxSquaredDistance)
                continue;
            // are we closer to the last closest point ?
            if (squaredDistance < minSquaredDistance) {
                nearestConnectionShape = connectionShape;
                minSquaredDistance = squaredDistance;
            }
        }
Esempio n. 3
0
int ConnectionTool::handleAtPoint(KoShape *shape, const QPointF &mousePoint) const
{
    if (!shape)
        return -1;

    const QPointF shapePoint = shape->documentToShape(mousePoint);

    KoConnectionShape * connectionShape = dynamic_cast<KoConnectionShape*>(shape);
    if (connectionShape) {
        // check connection shape handles
        return connectionShape->handleIdAt(handleGrabRect(shapePoint));
    } else {
        // check connection points
        int grabDistance = grabSensitivity();
        qreal minDistance = HUGE_VAL;
        int handleId = -1;
        KoConnectionPoints connectionPoints = shape->connectionPoints();
        KoConnectionPoints::const_iterator cp = connectionPoints.constBegin();
        KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd();
        for(; cp != lastCp; ++cp) {
            qreal d = squareDistance(shapePoint, cp.value().position);
            if (d <= grabDistance && d < minDistance) {
                handleId = cp.key();
                minDistance = d;
            }
        }
        return handleId;
    }
}
Esempio n. 4
0
KoShape * ConnectionTool::findNonConnectionShapeAtPosition(const QPointF &position) const
{
    QList<KoShape*> shapes = canvas()->shapeManager()->shapesAt(handleGrabRect(position));
    if (!shapes.isEmpty()) {
        qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
        for (QList<KoShape*>::const_iterator end = shapes.constEnd()-1; end >= shapes.constBegin(); --end) {
            KoShape* shape = *end;
            if (!dynamic_cast<KoConnectionShape*>(shape) && shape->shapeId() != TextShape_SHAPEID) {
                return shape;
            }
        }
    }

    return 0;
}
Esempio n. 5
0
void KoCreatePathTool::mouseMoveEvent(KoPointerEvent *event)
{
    Q_D(KoCreatePathTool);

    KoPathPoint *endPoint = d->endPointAtPosition(event->point);
    if (d->hoveredPoint != endPoint) {
        if (d->hoveredPoint) {
            QPointF nodePos = d->hoveredPoint->parent()->shapeToDocument(d->hoveredPoint->point());
            canvas()->updateCanvas(handlePaintRect(nodePos));
        }
        d->hoveredPoint = endPoint;
        if (d->hoveredPoint) {
            QPointF nodePos = d->hoveredPoint->parent()->shapeToDocument(d->hoveredPoint->point());
            canvas()->updateCanvas(handlePaintRect(nodePos));
        }
    }

    if (!pathStarted()) {
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
        canvas()->snapGuide()->snap(event->point, event->modifiers());
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

        d->mouseOverFirstPoint = false;
        return;
    }

    d->mouseOverFirstPoint = handleGrabRect(d->firstPoint->point()).contains(event->point);

    canvas()->updateCanvas(d->shape->boundingRect());
    canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
    QPointF snappedPosition = canvas()->snapGuide()->snap(event->point, event->modifiers());

    d->repaintActivePoint();
    if (event->buttons() & Qt::LeftButton) {
        d->pointIsDragged = true;
        QPointF offset = snappedPosition - d->activePoint->point();
        d->activePoint->setControlPoint2(d->activePoint->point() + offset);
        // pressing <alt> stops controls points moving symmetrically
        if ((event->modifiers() & Qt::AltModifier) == 0)
            d->activePoint->setControlPoint1(d->activePoint->point() - offset);
        d->repaintActivePoint();
    } else {
        d->activePoint->setPoint(snappedPosition);
    }

    canvas()->updateCanvas(d->shape->boundingRect());
    canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
}
Esempio n. 6
0
KoShape * ConnectionTool::findShapeAtPosition(const QPointF &position) const
{
    QList<KoShape*> shapes = canvas()->shapeManager()->shapesAt(handleGrabRect(position));
    if (!shapes.isEmpty()) {
        qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
        // we want to priorize connection shape handles, even if the connection shape
        // is not at the top of the shape stack at the mouse position
        KoConnectionShape *connectionShape = nearestConnectionShape(shapes, position);
        // use best connection shape or first shape from stack (last in the list) if not found
        if (connectionShape) {
            return connectionShape;
        } else {
            for (QList<KoShape*>::const_iterator end = shapes.constEnd()-1; end >= shapes.constBegin(); --end) {
                KoShape* shape = *end;
                if (!dynamic_cast<KoConnectionShape*>(shape) && shape->shapeId() != TextShape_SHAPEID) {
                    return shape;
                }
            }
        }
    }

    return 0;
}
Esempio n. 7
0
void KoCreatePathTool::mousePressEvent(KoPointerEvent *event)
{
    Q_D(KoCreatePathTool);

    //Right click removes last point
    if (event->button() == Qt::RightButton) {
      removeLastPoint();
      return;
    }

    const bool isOverFirstPoint = d->shape &&
        handleGrabRect(d->firstPoint->point()).contains(event->point);
    bool haveCloseModifier = (listeningToModifiers() && (event->modifiers() & Qt::ShiftModifier));

    if ((event->button() == Qt::LeftButton) && haveCloseModifier && !isOverFirstPoint) {
        endPathWithoutLastPoint();
        return;
    }

    d->finishAfterThisPoint = false;

    if (pathStarted()) {
        if (isOverFirstPoint) {
            d->activePoint->setPoint(d->firstPoint->point());
            canvas()->updateCanvas(d->shape->boundingRect());
            canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

            if (haveCloseModifier) {
                d->shape->closeMerge();
                // we are closing the path, so reset the existing start path point
                d->existingStartPoint = 0;
                // finish path
                endPath();
            } else {
                // the path shape will get closed when the user releases
                // the mouse button
                d->finishAfterThisPoint = true;
            }
        } else {
            canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

            QPointF point = canvas()->snapGuide()->snap(event->point, event->modifiers());

            // check whether we hit an start/end node of an existing path
            d->existingEndPoint = d->endPointAtPosition(point);
            if (d->existingEndPoint.isValid() && d->existingEndPoint != d->existingStartPoint) {
                point = d->existingEndPoint.path->shapeToDocument(d->existingEndPoint.point->point());
                d->activePoint->setPoint(point);
                // finish path
                endPath();
            } else {
                d->activePoint->setPoint(point);
                canvas()->updateCanvas(d->shape->boundingRect());
                canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
            }
        }
    } else {
        KoPathShape *pathShape = new KoPathShape();
        d->shape=pathShape;
        pathShape->setShapeId(KoPathShapeId);

        KoShapeStroke *stroke = new KoShapeStroke(canvas()->resourceManager()->activeStroke());
        stroke->setColor(canvas()->resourceManager()->foregroundColor().toQColor());

        pathShape->setStroke(stroke);
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
        QPointF point = canvas()->snapGuide()->snap(event->point, event->modifiers());

        // check whether we hit an start/end node of an existing path
        d->existingStartPoint = d->endPointAtPosition(point);
        if (d->existingStartPoint.isValid()) {
            point = d->existingStartPoint.path->shapeToDocument(d->existingStartPoint.point->point());
        }
        d->activePoint = pathShape->moveTo(point);
        d->firstPoint = d->activePoint;
        canvas()->updateCanvas(handlePaintRect(point));
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

        canvas()->snapGuide()->setEditedShape(pathShape);

        d->angleSnapStrategy = new AngleSnapStrategy(d->angleSnappingDelta, d->angleSnapStatus);
        canvas()->snapGuide()->addCustomSnapStrategy(d->angleSnapStrategy);
    }

    if (d->angleSnapStrategy)
        d->angleSnapStrategy->setStartPoint(d->activePoint->point());
}