Warning, file /graphics/tikzkit/src/ui/paths/EllipsePathItem.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2013-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 "EllipsePathItem.h"
0021 
0022 #include "NodeItem.h"
0023 #include "DocumentPrivate.h"
0024 #include "ResizeHandle.h"
0025 #include "MoveHandle.h"
0026 #include "RotateHandle.h"
0027 #include "Painter.h"
0028 
0029 #include <tikz/core/EllipsePath.h>
0030 #include <tikz/core/Style.h>
0031 
0032 #include <QApplication>
0033 #include <QPainter>
0034 #include <QGraphicsScene>
0035 #include <QGraphicsView>
0036 #include <QDebug>
0037 #include <QGraphicsSceneMouseEvent>
0038 #include <QPainterPathStroker>
0039 
0040 namespace tikz {
0041 namespace ui {
0042 
0043 EllipsePathItem::EllipsePathItem(tikz::core::Path * path)
0044     : tikz::ui::PathItem(path)
0045 {
0046     // catch if the tikz::core::Node::pos() changes behind our back:
0047     // we need to track the NodeItem the ellipse is attached to
0048     connect(path, SIGNAL(nodeChanged(tikz::core::Node*)),
0049             this, SLOT(updateNode(tikz::core::Node*)));
0050 
0051     connect(path, SIGNAL(changed()), this, SLOT(slotUpdate()));
0052 }
0053 
0054 EllipsePathItem::~EllipsePathItem()
0055 {
0056 }
0057 
0058 DocumentPrivate * EllipsePathItem::document() const
0059 {
0060     Q_ASSERT(qobject_cast<DocumentPrivate*>(path()->document()) != nullptr);
0061     return qobject_cast<DocumentPrivate*>(path()->document());
0062 }
0063 
0064 void EllipsePathItem::setNode(NodeItem* node)
0065 {
0066     if (m_node != node) {
0067         ellipsePath()->setNode(node ? node->node() : nullptr);
0068     }
0069 }
0070 
0071 NodeItem* EllipsePathItem::node() const
0072 {
0073     return m_node;
0074 }
0075 
0076 QPointF EllipsePathItem::pos() const
0077 {
0078     if (ellipsePath()->node()) {
0079         NodeItem * nodeItem = document()->nodeItemFromId(ellipsePath()->node()->uid());
0080         Q_ASSERT(nodeItem != nullptr);
0081 
0082         return nodeItem->anchor(anchor());
0083     } else {
0084         return ellipsePath()->pos();
0085     }
0086 }
0087 
0088 QString EllipsePathItem::anchor() const
0089 {
0090     return ellipsePath()->anchor();
0091 }
0092 
0093 void EllipsePathItem::setAnchor(const QString & anchor)
0094 {
0095     ellipsePath()->setAnchor(anchor);
0096 }
0097 
0098 void EllipsePathItem::slotUpdate()
0099 {
0100     prepareGeometryChange();
0101 
0102     m_dirty = true;
0103     setTransformOriginPoint(pos());
0104     setRotation(style()->rotation());
0105 }
0106 
0107 void EllipsePathItem::paint(QPainter *painter,
0108                             const QStyleOptionGraphicsItem *option,
0109                             QWidget *widget)
0110 {
0111     Q_UNUSED(option);
0112     Q_UNUSED(widget);
0113 
0114     updateCache();
0115 
0116     painter->setRenderHints(QPainter::Antialiasing);
0117 
0118     if (isHovered() /*&& !dragging*/) {
0119         painter->fillPath(m_hoverPath, QColor(148, 202, 239)); // FIXME: make color configurable
0120     }
0121 
0122     // draw line
0123     Painter p(painter, style());
0124     p.drawPath(m_ellipse);
0125 }
0126 
0127 QRectF EllipsePathItem::boundingRect() const
0128 {
0129     // make sure the cache is up-to-date
0130     const_cast<EllipsePathItem*>(this)->updateCache();
0131 
0132     return m_boundingRect; //.adjusted(-0.05, -0.05, 0.05, 0.05);
0133 }
0134 
0135 QPainterPath EllipsePathItem::shape() const
0136 {
0137     const_cast<EllipsePathItem*>(this)->updateCache();
0138 
0139     return m_shapePath;
0140 }
0141 
0142 bool EllipsePathItem::contains(const QPointF & point) const
0143 {
0144     // make sure the cache is up-to-date
0145     const_cast<EllipsePathItem*>(this)->updateCache();
0146 
0147     // contains depends on the type of fill color/brush
0148     if (style()->fillColor() == Qt::transparent) {
0149         return m_hoverPath.contains(point);
0150     } else {
0151         return m_ellipse.contains(point)
0152             || m_hoverPath.contains(point);
0153     }
0154 }
0155 
0156 void EllipsePathItem::updateNode(tikz::core::Node * node)
0157 {
0158     NodeItem * newNode = nullptr;
0159 
0160     if (node) {
0161         newNode = document()->nodeItemFromId(node->uid());
0162     }
0163 
0164     if (m_node != newNode) {
0165         prepareGeometryChange();
0166         m_dirty = true;
0167         m_node = newNode;
0168     }
0169 }
0170 
0171 void EllipsePathItem::updateCache()
0172 {
0173     if (!m_dirty) return;
0174     m_dirty = false;
0175 
0176     // reset old paths
0177     m_ellipse = QPainterPath();
0178     m_hoverPath = QPainterPath();
0179     m_boundingRect = QRectF();
0180 
0181     // draw ellipse path
0182     m_ellipse.addEllipse(pos(),
0183                          style()->radiusX().toPoint(),
0184                          style()->radiusY().toPoint());
0185 
0186     // cache hover path
0187     QPainterPathStroker pps;
0188     pps.setWidth(style()->penWidth().toPoint() + 1.0_mm .toPoint());
0189     m_hoverPath = pps.createStroke(m_ellipse);
0190 
0191     // cache shape path
0192     pps.setWidth(style()->penWidth().toPoint() + 2.0_mm .toPoint());
0193     m_shapePath = pps.createStroke(m_ellipse);
0194 
0195     // cache bounding rect
0196     m_boundingRect = m_shapePath.boundingRect();
0197 }
0198 
0199 tikz::core::EllipsePath * EllipsePathItem::ellipsePath() const
0200 {
0201     tikz::core::EllipsePath * p = qobject_cast<tikz::core::EllipsePath*>(path());
0202     Q_ASSERT(p != nullptr);
0203 
0204     return p;
0205 }
0206 
0207 }
0208 }
0209 // kate: indent-width 4; replace-tabs on;