File indexing completed on 2024-05-12 05:40:26

0001 /***************************************************************************
0002  *  Copyright (C) 2019 by Renaud Guezennec                                 *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software is free software; you can redistribute it and/or modify *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program 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 General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "mindmap/qmlItems/linkitem.h"
0021 
0022 #include "mindmap/geometry/linknode.h"
0023 
0024 namespace mindmap
0025 {
0026 LinkItem::LinkItem()
0027 {
0028     setFlag(QQuickItem::ItemHasContents, true);
0029     //setFlag(QQuickItem::Ite)
0030     setAntialiasing(true);
0031     setAcceptedMouseButtons(Qt::LeftButton);
0032     setWidth(280);
0033     setHeight(280);
0034 }
0035 
0036 PointList LinkItem::points() const
0037 {
0038     return m_points;
0039 }
0040 
0041 void LinkItem::setPoints(const PointList& list)
0042 {
0043     if(list == m_points)
0044         return;
0045     m_points= list;
0046     emit pointsChanged();
0047 }
0048 
0049 QColor LinkItem::color() const
0050 {
0051     return m_color;
0052 }
0053 
0054 void LinkItem::setColor(QColor color)
0055 {
0056     if(m_color == color)
0057         return;
0058     m_color= color;
0059     emit colorChanged();
0060     m_colorChanged= true;
0061     update();
0062 }
0063 
0064 void LinkItem::mousePressEvent(QMouseEvent* event)
0065 {
0066     if(event->button() & Qt::LeftButton)
0067     {
0068         emit selected(true);
0069         event->accept();
0070     }
0071 }
0072 
0073 QSGNode* LinkItem::updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeData*)
0074 {
0075 
0076     LinkNode* link= static_cast<LinkNode*>(node);
0077     if(!link)
0078     {
0079         link= new LinkNode();
0080         link->setColor(m_color);
0081     }
0082     if(m_colorChanged)
0083     {
0084         link->setColor(m_color);
0085         m_colorChanged= false;
0086     }
0087 
0088     if(m_controller)
0089         link->update(QRectF{0, 0, width(), height()}, m_controller->orientation(), m_controller->startBox(),
0090                      m_controller->endBox());
0091     return link;
0092 }
0093 
0094 qreal LinkItem::horizontalOffset() const
0095 {
0096     return m_horizontalOffset;
0097 }
0098 
0099 qreal LinkItem::verticalOffset() const
0100 {
0101     return m_verticalOffset;
0102 }
0103 void LinkItem::setHorizontalOffset(qreal r)
0104 {
0105     if(qFuzzyCompare(r, m_horizontalOffset))
0106         return;
0107     m_horizontalOffset= r;
0108     emit horizontalOffsetChanged();
0109 }
0110 void LinkItem::setVerticalOffset(qreal r)
0111 {
0112     if(qFuzzyCompare(r, m_verticalOffset))
0113         return;
0114     m_verticalOffset= r;
0115     emit verticalOffsetChanged();
0116 }
0117 
0118 LinkController* LinkItem::controller() const
0119 {
0120     return m_controller;
0121 }
0122 
0123 void LinkItem::setController(LinkController* newController)
0124 {
0125     if(m_controller == newController)
0126         return;
0127     m_controller= newController;
0128     emit controllerChanged();
0129 
0130     auto updateOffset= [this]() {
0131         auto endBox= m_controller->endBox();
0132         auto startBox= m_controller->startBox();
0133 
0134         QRectF rect{0, 0, width(), height()};
0135         QPointF p1, p2;
0136         QRectF rect1= startBox;
0137         rect1.moveTo(-startBox.width() / 2, -startBox.height() / 2);
0138         QRectF rect2= endBox;
0139         rect2.moveTo(-endBox.width() / 2, -endBox.height() / 2);
0140 
0141         switch(m_controller->orientation())
0142         {
0143         case LinkController::RightBottom:
0144         {
0145             p1= rect.topLeft();
0146             p2= rect.bottomRight();
0147             rect2= rect2.translated(p2.x(), p2.y());
0148         }
0149         break;
0150         case LinkController::LeftBottom:
0151         {
0152             p1= rect.topRight();
0153             p2= rect.bottomLeft();
0154             rect2= rect2.translated(p2.x(), p2.y());
0155             rect1= rect1.translated(p1.x(), p1.y());
0156         }
0157         break;
0158         case LinkController::RightTop:
0159         {
0160             p1= rect.bottomLeft();
0161             p2= rect.topRight();
0162             rect2= rect2.translated(p2.x(), p2.y());
0163             rect1= rect1.translated(p1.x(), p1.y());
0164         }
0165         break;
0166         case LinkController::LeftTop:
0167         {
0168             p1= rect.bottomRight();
0169             p2= rect.topLeft();
0170             rect1= rect1.translated(p1.x(), p1.y());
0171         }
0172         break;
0173         }
0174 
0175         QLineF line(p1, p2);
0176 
0177         QLineF rect1Bottom(rect1.bottomLeft(), rect1.bottomRight());
0178         QLineF rect1Top(rect1.topLeft(), rect1.topRight());
0179         QLineF rect1Left(rect1.topLeft(), rect1.bottomLeft());
0180         QLineF rect1Right(rect1.topRight(), rect1.bottomRight());
0181 
0182         QVector<QLineF> lines({rect1Bottom, rect1Top, rect1Left, rect1Right});
0183 
0184         QPointF intersection1;
0185         for(auto const& rectSide : qAsConst(lines))
0186         {
0187             QPointF point;
0188             if(line.intersects(rectSide, &point) == QLineF::BoundedIntersection)
0189                 intersection1= point;
0190         }
0191 
0192         QLineF rect2Bottom(rect2.bottomLeft(), rect2.bottomRight());
0193         QLineF rect2Top(rect2.topLeft(), rect2.topRight());
0194         QLineF rect2Left(rect2.topLeft(), rect2.bottomLeft());
0195         QLineF rect2Right(rect2.topRight(), rect2.bottomRight());
0196 
0197         QVector<QLineF> lines2({rect2Bottom, rect2Top, rect2Left, rect2Right});
0198 
0199         QPointF intersection2;
0200         for(auto const& rectSide : qAsConst(lines2))
0201         {
0202             QPointF point;
0203             if(line.intersects(rectSide, &point) == QLineF::BoundedIntersection)
0204                 intersection2= point;
0205         }
0206 
0207         line= QLineF(intersection1, intersection2);
0208 
0209         setHorizontalOffset(line.center().x());
0210         setVerticalOffset(line.center().y());
0211     };
0212     connect(m_controller, &LinkController::startBoxChanged, this, updateOffset);
0213     connect(m_controller, &LinkController::endBoxChanged, this, updateOffset);
0214     connect(m_controller, &LinkController::startChanged, this, updateOffset);
0215     connect(m_controller, &LinkController::endChanged, this, updateOffset);
0216 }
0217 
0218 } // namespace mindmap