File indexing completed on 2024-05-19 04:36:38

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "LineTool.h"
0021 #include "ResizeHandle.h"
0022 #include "RotateHandle.h"
0023 #include "MoveHandle.h"
0024 #include "EdgePathItem.h"
0025 #include "AnchorManager.h"
0026 #include "DocumentPrivate.h"
0027 #include "ViewPrivate.h"
0028 #include "Renderer.h"
0029 
0030 #include <tikz/core/Style.h>
0031 #include <tikz/core/EdgePath.h>
0032 #include <tikz/core/Transaction.h>
0033 
0034 #include <QApplication>
0035 #include <QGraphicsScene>
0036 
0037 #include <QDebug>
0038 
0039 namespace tikz {
0040 namespace ui {
0041 
0042 LineTool::LineTool(tikz::ui::PathItem * path, QGraphicsScene * scene)
0043     : AbstractTool(path->document(), scene)
0044     , m_path(qobject_cast<tikz::ui::EdgePathItem *>(path))
0045     , m_anchorManager(new AnchorManager(scene, path->document(), this))
0046     , m_transaction(nullptr)
0047 {
0048     // show all path handles
0049     createPathHandles();
0050 
0051     connect(m_path->path(), SIGNAL(changed()), this, SLOT(updateHandlePositions()));
0052 }
0053 
0054 LineTool::~LineTool()
0055 {
0056     qDeleteAll(m_handles);
0057     m_handles.clear();
0058 }
0059 
0060 void LineTool::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
0061 {
0062 }
0063 
0064 void LineTool::mousePressEvent(QGraphicsSceneMouseEvent * event)
0065 {
0066 }
0067 
0068 void LineTool::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
0069 {
0070 }
0071 
0072 void LineTool::createPathHandles()
0073 {
0074     // on hide, just delte all handles
0075     qDeleteAll(m_handles);
0076     m_handles.clear();
0077 
0078     // create and show handles
0079     m_handles.append(new ResizeHandle(Handle::StartPos));
0080     m_handles.append(new ResizeHandle(Handle::EndPos));
0081 
0082     // make sure the handles are positioned correctly
0083     updateHandlePositions();
0084 
0085     // show and connect to get handle movements
0086     for (Handle * handle : qAsConst(m_handles)) {
0087         scene()->addItem(handle);
0088         handle->show();
0089         connect(handle, SIGNAL(positionChanged(tikz::ui::Handle *, const QPointF &, QGraphicsView *)),
0090                 this, SLOT(handleMoved(tikz::ui::Handle *, const QPointF &, QGraphicsView *)));
0091         connect(handle, SIGNAL(mousePressed(tikz::ui::Handle *, const QPointF &, QGraphicsView *)),
0092                 this, SLOT(handleMousePressed(tikz::ui::Handle *, const QPointF &, QGraphicsView *)));
0093         connect(handle, SIGNAL(mouseReleased(tikz::ui::Handle *, const QPointF &, QGraphicsView *)),
0094                 this, SLOT(handleMouseReleased(tikz::ui::Handle *, const QPointF &, QGraphicsView *)));
0095     }
0096 }
0097 
0098 void LineTool::updateHandlePositions()
0099 {
0100     for (Handle * handle : qAsConst(m_handles)) {
0101         handle->setPos(handlePos(handle->handlePos()));
0102         handle->setRotation(-m_path->style()->rotation());
0103     }
0104 }
0105 
0106 QPointF LineTool::handlePos(Handle::Position pos)
0107 {
0108     if (pos == Handle::StartPos) {
0109         return m_path->startPos();
0110     } else {
0111         return m_path->endPos();
0112     }
0113 }
0114 
0115 void LineTool::handleMoved(Handle * handle, const QPointF & scenePos, QGraphicsView * view)
0116 {
0117     auto tikzView = qobject_cast<Renderer *>(view);
0118 
0119     // later: preferred unit
0120     const tikz::Unit unit = tikz::Unit::Centimeter;
0121 
0122     // try to attach to anchor
0123     tikz::core::MetaPos metaPos = m_anchorManager->anchorAt(scenePos, view);
0124 
0125     if (! metaPos.node()) {
0126         tikz::Pos p = tikz::Pos(scenePos).convertTo(unit);
0127         p = tikzView->snapPos(p);
0128         metaPos.setPos(p);
0129     }
0130 
0131     //
0132     // move start / end
0133     //
0134     tikz::core::EdgePath * ep = m_path->edgePath();
0135     switch (handle->handlePos()) {
0136         case Handle::StartPos: {
0137             ep->setStartMetaPos(metaPos);
0138             break;
0139         }
0140         case Handle::EndPos: {
0141             ep->setEndMetaPos(metaPos);
0142             break;
0143         }
0144         default: Q_ASSERT(false);
0145     }
0146 }
0147 
0148 void LineTool::handleMousePressed(Handle * handle, const QPointF & scenePos, QGraphicsView * view)
0149 {
0150 //     qDebug() << "line tool: mouse handle pressed " << scenePos;
0151     m_transaction.reset(new tikz::core::Transaction(document(), "Move Line"));
0152     m_anchorManager->addAllNodes();
0153 }
0154 
0155 void LineTool::handleMouseReleased(Handle * handle, const QPointF & scenePos, QGraphicsView * view)
0156 {
0157 //     qDebug() << "line tool: mouse handle released" << scenePos;
0158 
0159     m_anchorManager->clear();
0160     m_transaction->finish();
0161 }
0162 
0163 }
0164 }
0165 
0166 // kate: indent-width 4; replace-tabs on;