1 /*******************************************************************
2
3 Part of the Fritzing project - http://fritzing.org
4 Copyright (c) 2007-2014 Fachhochschule Potsdam - http://fh-potsdam.de
5
6 Fritzing is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Fritzing is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Fritzing. If not, see <http://www.gnu.org/licenses/>.
18
19 ********************************************************************
20
21 $Revision: 6904 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-02-26 16:26:03 +0100 (Di, 26. Feb 2013) $
24
25 ********************************************************************/
26
27 #include "nonconnectoritem.h"
28
29 #include <QBrush>
30 #include <QPen>
31 #include <QColor>
32 #include <limits>
33
34 #include "../sketch/infographicsview.h"
35 #include "../debugdialog.h"
36 #include "../utils/graphicsutils.h"
37 #include "../model/modelpart.h"
38
39 //static const double EffectiveAdjustment = 1.25;
40 static const double EffectiveAdjustmentFactor = 5.0 / 15.0;
41
42 /////////////////////////////////////////////////////////
43
NonConnectorItem(ItemBase * attachedTo)44 NonConnectorItem::NonConnectorItem(ItemBase * attachedTo) : QGraphicsRectItem(attachedTo)
45 {
46 m_effectively = EffectivelyUnknown;
47 m_radius = m_strokeWidth = 0;
48 m_layerHidden = m_isPath = m_inactive = m_hidden = false;
49 m_attachedTo = attachedTo;
50 setAcceptHoverEvents(false);
51 setAcceptedMouseButtons(Qt::NoButton);
52 setFlag(QGraphicsItem::ItemIsMovable, false);
53 setFlag(QGraphicsItem::ItemIsSelectable, false);
54 setFlag(QGraphicsItem::ItemIsFocusable, false);
55 }
56
~NonConnectorItem()57 NonConnectorItem::~NonConnectorItem() {
58 }
59
attachedTo()60 ItemBase * NonConnectorItem::attachedTo() {
61 return m_attachedTo;
62 }
63
doNotPaint()64 bool NonConnectorItem::doNotPaint() {
65 return (m_hidden || m_inactive || !m_paint || m_layerHidden);
66 }
67
68
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)69 void NonConnectorItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget ) {
70
71 if (doNotPaint()) return;
72
73 painter->setOpacity(m_opacity);
74
75 /*
76 DebugDialog::debug(QString("id:%1 %2 w:%3 %4 c:%5 ec:%6 er:%7 neg:%8 w:%9")
77 .arg(attachedToID())
78 .arg(attachedToTitle())
79 .arg(pen().width())
80 .arg(pen().color().name())
81 .arg(m_circular)
82 .arg(m_effectivelyCircular)
83 .arg(m_effectivelyRectangular)
84 .arg(m_negativePenWidth)
85 .arg(rect().width())
86 );
87 */
88
89 if (m_circular) {
90 painter->setBrush(brush());
91 if (m_negativePenWidth < 0) {
92 // for wires
93 painter->setPen(Qt::NoPen);
94 if (!m_negativeOffsetRect) {
95 painter->drawEllipse(rect().center(), m_negativePenWidth, m_negativePenWidth);
96 }
97 else {
98 int pw = m_negativePenWidth + 1;
99 painter->drawEllipse(rect().adjusted(-pw, -pw, pw, pw));
100 }
101 }
102 else
103 {
104 // for parts
105 QRectF r = rect();
106 if (r.width() > 0 && r.height() > 0) {
107 double delta = .66 * m_strokeWidth;
108 painter->setPen(pen());
109 painter->drawEllipse(r.adjusted(delta, delta, -delta, -delta));
110 }
111 }
112 }
113 else if (!m_shape.isEmpty()) {
114 painter->setBrush(brush());
115 painter->setPen(pen());
116 painter->drawPath(m_shape);
117 }
118 else if (m_effectively == EffectivelyCircular) {
119 QRectF r = rect();
120 if (r.width() > 0 && r.height() > 0) {
121 painter->setBrush(brush());
122 painter->setPen(pen());
123 double delta = r.width() * EffectiveAdjustmentFactor;
124 painter->drawEllipse(r.adjusted(delta, delta, -delta, -delta));
125 }
126 }
127 else if (m_effectively == EffectivelyRectangular) {
128 QRectF r = rect();
129 if (r.width() > 0 && r.height() > 0) {
130 painter->setBrush(brush());
131 painter->setPen(pen());
132 double delta = qMin(r.width(), r.height()) * EffectiveAdjustmentFactor;
133 painter->drawRect(r.adjusted(delta, delta, -delta, -delta));
134 }
135 }
136 else {
137 QGraphicsRectItem::paint(painter, option, widget);
138 }
139
140 }
141
setHidden(bool hide)142 void NonConnectorItem::setHidden(bool hide) {
143 m_hidden = hide;
144 this->update();
145 }
146
hidden()147 bool NonConnectorItem::hidden() {
148 return m_hidden;
149 }
150
setLayerHidden(bool hide)151 void NonConnectorItem::setLayerHidden(bool hide) {
152 m_layerHidden = hide;
153 this->update();
154 }
155
layerHidden()156 bool NonConnectorItem::layerHidden() {
157 return m_layerHidden;
158 }
159
setInactive(bool inactivate)160 void NonConnectorItem::setInactive(bool inactivate) {
161 m_inactive = inactivate;
162 this->update();
163 }
164
inactive()165 bool NonConnectorItem::inactive() {
166 return m_inactive;
167 }
168
attachedToID()169 long NonConnectorItem::attachedToID() {
170 if (attachedTo() == NULL) return -1;
171 return attachedTo()->id();
172 }
173
attachedToTitle()174 const QString & NonConnectorItem::attachedToTitle() {
175 if (attachedTo() == NULL) return ___emptyString___;
176 return attachedTo()->title();
177 }
178
attachedToInstanceTitle()179 const QString & NonConnectorItem::attachedToInstanceTitle() {
180 if (attachedTo() == NULL) return ___emptyString___;
181 return attachedTo()->instanceTitle();
182 }
183
setCircular(bool circular)184 void NonConnectorItem::setCircular(bool circular) {
185 m_circular = circular;
186 }
187
setRadius(double radius,double strokeWidth)188 void NonConnectorItem::setRadius(double radius, double strokeWidth) {
189 m_radius = radius;
190 m_strokeWidth = strokeWidth;
191 m_circular = (m_radius > 0);
192 }
193
setIsPath(bool path)194 void NonConnectorItem::setIsPath(bool path) {
195 m_isPath = path;
196 }
197
isPath()198 bool NonConnectorItem::isPath() {
199 return m_isPath;
200 }
201
radius()202 double NonConnectorItem::radius() {
203 return m_radius;
204 }
205
strokeWidth()206 double NonConnectorItem::strokeWidth() {
207 return m_strokeWidth;
208 }
209
shape() const210 QPainterPath NonConnectorItem::shape() const
211 {
212 if (m_circular || m_effectively == EffectivelyCircular) {
213 QPainterPath path;
214 path.addEllipse(rect());
215 return GraphicsUtils::shapeFromPath(path, pen(), pen().widthF(), true);
216 }
217 else if (!m_shape.isEmpty()) {
218 return m_shape;
219 }
220
221 return QGraphicsRectItem::shape();
222 }
223
setShape(QPainterPath & pp)224 void NonConnectorItem::setShape(QPainterPath & pp) {
225 // so far only used by GroundPlane
226 m_shape = GraphicsUtils::shapeFromPath(pp, pen(), pen().widthF(), true);
227 }
228
attachedToItemType()229 int NonConnectorItem::attachedToItemType() {
230 if (m_attachedTo == NULL) return ModelPart::Unknown;
231
232 return m_attachedTo->itemType();
233 }
234