Ejemplo n.º 1
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;
    }
}
Ejemplo 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;
            }
        }
Ejemplo n.º 3
0
QRectF KoToolBase::handleGrabRect(const QPointF &position) const
{
    Q_D(const KoToolBase);
    const KoViewConverter * converter = d->canvas->viewConverter();
    uint handleSize = 2*grabSensitivity();
    QRectF r = converter->viewToDocument(QRectF(0, 0, handleSize, handleSize));
    r.moveCenter(position);
    return r;
}
Ejemplo n.º 4
0
void ConnectionTool::mouseReleaseEvent(KoPointerEvent *event)
{
    if (m_currentStrategy) {
        if (m_editMode == CreateConnection) {
            // check if connection handles have a minimal distance
            KoConnectionShape * connectionShape = dynamic_cast<KoConnectionShape*>(m_currentShape);
            Q_ASSERT(connectionShape);
            // get both handle positions in document coordinates
            QPointF p1 = connectionShape->shapeToDocument(connectionShape->handlePosition(0));
            QPointF p2 = connectionShape->shapeToDocument(connectionShape->handlePosition(1));
            int grabDistance = grabSensitivity();
            // use grabbing sensitivity as minimal distance threshold
            if (squareDistance(p1, p2) < grabDistance*grabDistance) {
                // minimal distance was not reached, so we have to undo the started work:
                // - cleanup and delete the strategy
                // - remove connection shape from shape manager and delete it
                // - reset edit mode to last state
                delete m_currentStrategy;
                m_currentStrategy = 0;
                repaintDecorations();
                canvas()->shapeManager()->remove(m_currentShape);
                setEditMode(m_editMode, connectionShape->firstShape(), connectionShape->firstConnectionId());
                repaintDecorations();
                delete connectionShape;
                return;
            } else {
                // finalize adding the new connection shape with an undo command
                KUndo2Command * cmd = canvas()->shapeController()->addShape(m_currentShape);
                canvas()->addCommand(cmd);
                setEditMode(EditConnection, m_currentShape, KoConnectionShape::StartHandle);
            }
        }
        m_currentStrategy->finishInteraction(event->modifiers());
        // TODO: Add parent command to KoInteractionStrategy::createCommand
        // so that we can have a single command to undo for the user
        KUndo2Command *command = m_currentStrategy->createCommand();
        if (command)
            canvas()->addCommand(command);
        delete m_currentStrategy;
        m_currentStrategy = 0;
    }
    updateStatusText();
}