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

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2013 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 "RectShape.h"
0021 #include "NodeItem.h"
0022 
0023 #include <tikz/core/Style.h>
0024 #include <tikz/core/tikz.h>
0025 
0026 #include <cmath>
0027 
0028 #include <QDebug>
0029 
0030 namespace tikz {
0031 namespace ui {
0032 
0033 class RectShapePrivate
0034 {
0035     public:
0036 };
0037 
0038 RectShape::RectShape(NodeItem * node)
0039     : AbstractShape(node)
0040     , d(new RectShapePrivate())
0041 {
0042 }
0043 
0044 RectShape::~RectShape()
0045 {
0046     delete d;
0047 }
0048 
0049 tikz::Shape RectShape::type() const
0050 {
0051     return tikz::Shape::ShapeRectangle;
0052 }
0053 
0054 QPainterPath RectShape::shape() const
0055 {
0056     QPainterPath path;
0057     path.addRect(node()->shapeRect());
0058     return path;
0059 }
0060 
0061 QPainterPath RectShape::outline() const
0062 {
0063     const qreal lw = node()->style()->penWidth().toPoint() / 2;
0064     QRectF rect = node()->shapeRect();
0065     rect.adjust(-lw, -lw, lw, lw);
0066 
0067     QPainterPath path;
0068     path.addRect(rect);
0069     return path;
0070 }
0071 
0072 QStringList RectShape::supportedAnchors() const
0073 {
0074     // by default, just return NoAnchor
0075     const QStringList anchors = QStringList()
0076         << QString()
0077         << QStringLiteral("center")
0078         << QStringLiteral("north")
0079         << QStringLiteral("north east")
0080         << QStringLiteral("east")
0081         << QStringLiteral("south east")
0082         << QStringLiteral("south")
0083         << QStringLiteral("south west")
0084         << QStringLiteral("west")
0085         << QStringLiteral("north west");
0086     return anchors;
0087 }
0088 
0089 QPointF RectShape::anchorPos(const QString & anchor) const
0090 {
0091     if (anchor.isEmpty()) {
0092         return QPointF(0, 0);
0093     }
0094 
0095     const QRectF shapeRect = node()->shapeRect();
0096     const qreal rx = shapeRect.width() / 2.0 + node()->style()->outerSep().toPoint();
0097     const qreal ry = shapeRect.height() / 2.0 + node()->style()->outerSep().toPoint();
0098 
0099     if (anchor == QStringLiteral("center")) {
0100         return QPointF(0, 0);
0101     } else if (anchor == QStringLiteral("north")) {
0102         return QPointF(0, ry);
0103     } else if (anchor == QStringLiteral("north east")) {
0104         return QPointF(rx, ry);
0105     } else if (anchor == QStringLiteral("east")) {
0106         return QPointF(rx, 0);
0107     } else if (anchor == QStringLiteral("south east")) {
0108         return QPointF(rx, -ry);
0109     } else if (anchor == QStringLiteral("south")) {
0110         return QPointF(0, -ry);
0111     } else if (anchor == QStringLiteral("south west")) {
0112         return QPointF(-rx, -ry);
0113     } else if (anchor == QStringLiteral("west")) {
0114         return QPointF(-rx, 0);
0115     } else if (anchor == QStringLiteral("north west")) {
0116         return QPointF(-rx, ry);
0117     }
0118 
0119     tikz::warn("The shape 'rectangle' does not support anchor '" + anchor + "'.");
0120 
0121     return QPointF(0, 0);
0122 }
0123 
0124 QPointF RectShape::contactPoint(const QString & anchor, qreal rad) const
0125 {
0126     if (! anchor.isEmpty()) {
0127         return anchorPos(anchor);
0128     }
0129 
0130     const QRectF shapeRect = node()->shapeRect();
0131     const qreal rx = shapeRect.width() / 2.0 + node()->style()->outerSep().toPoint();
0132     const qreal ry = shapeRect.height() / 2.0 + node()->style()->outerSep().toPoint();
0133 
0134     qreal x = std::cos(rad);
0135     qreal y = std::sin(rad);
0136     if (qFuzzyCompare(y, 0.0)) {
0137         x *= rx;
0138     } else if (qFuzzyCompare(x, 0.0)) {
0139         y *= ry;
0140     } else {
0141         if (fabs(y) != ry) {
0142             // normalize to y
0143             x = (x < 0 ? -1 : 1) * fabs(ry * x / y);
0144             y = (y < 0 ? -1 : 1) * ry;
0145         }
0146         if (fabs(x) > rx) {
0147             // normalize to x
0148             y = (y < 0 ? -1 : 1) * fabs(rx * y / x);
0149             x = (x < 0 ? -1 : 1) * rx;
0150         }
0151     }
0152     return QPointF(x, y);
0153 }
0154 
0155 }
0156 }
0157 
0158 // kate: indent-width 4; replace-tabs on;