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