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