File indexing completed on 2024-06-16 11:34:23

0001 //
0002 // C++ Implementation: pinnode
0003 //
0004 // Description:
0005 //
0006 //
0007 //
0008 // Copyright: See COPYING file that comes with this distribution
0009 //
0010 //
0011 #include "pinnode.h"
0012 #include "component.h"
0013 #include "pin.h"
0014 
0015 #include <QPainter>
0016 #include <cmath>
0017 
0018 /// The maximum length of the voltage indiactor
0019 const int vLength = 8;
0020 
0021 /// The current at the middle of the current indicator
0022 const double iMidPoint = 0.03;
0023 
0024 /// The maximum thicnkess of the current indicator
0025 const int iLength = 6;
0026 
0027 inline double calcIProp(const double i)
0028 {
0029     return 1 - iMidPoint / (iMidPoint + std::abs(i));
0030 }
0031 
0032 inline int calcThickness(const double prop)
0033 {
0034     return int((iLength - 2) * prop + 2);
0035 }
0036 
0037 inline int calcLength(double v)
0038 {
0039     double prop = Component::voltageLength(v);
0040     if (v > 0)
0041         prop *= -1.0;
0042 
0043     return int(vLength * prop);
0044 }
0045 PinNode::PinNode(ICNDocument *icnDocument, int dir, const QPoint &pos, QString *id)
0046     : ECNode(icnDocument, Node::ec_pin, dir, pos, id)
0047 {
0048     QString name("PinNode");
0049     if (id) {
0050         name.append(QString("-%1").arg(*id));
0051     } else {
0052         name.append("-Unknown");
0053     }
0054     setObjectName(name.toLatin1().data());
0055 
0056     m_pinPoint = new KtlQCanvasRectangle(0, 0, 3, 3, canvas());
0057     m_pinPoint->setBrush(Qt::black);
0058     m_pinPoint->setPen(QPen(Qt::black));
0059 }
0060 
0061 PinNode::~PinNode()
0062 {
0063 }
0064 
0065 void PinNode::drawShape(QPainter &p)
0066 {
0067     initPainter(p);
0068 
0069     double v = pin() ? pin()->voltage() : 0.0;
0070     QColor voltageColor = Component::voltageColor(v);
0071 
0072     QPen pen = p.pen();
0073 
0074     if (isSelected())
0075         pen = m_selectedColor;
0076     else if (m_bShowVoltageColor)
0077         pen = voltageColor;
0078 
0079     if (m_pinPoint) {
0080         bool drawDivPoint;
0081         QPoint divPoint = findConnectorDivergePoint(&drawDivPoint);
0082         m_pinPoint->setVisible(drawDivPoint);
0083         m_pinPoint->move(divPoint.x() - 1, divPoint.y() - 1);
0084         m_pinPoint->setBrush(pen.color());
0085         m_pinPoint->setPen(pen.color());
0086     }
0087 
0088     // Now to draw on our current/voltage bar indicators
0089     int length = calcLength(v);
0090 
0091     if ((numPins() == 1) && m_bShowVoltageBars && length != 0) {
0092         // we can assume that v != 0 as length != 0
0093         double i = pin()->current();
0094         double iProp = calcIProp(i);
0095         int thickness = calcThickness(iProp);
0096 
0097         p.setPen(QPen(voltageColor, thickness));
0098 
0099         // The node line (drawn at the end of this function) will overdraw
0100         // some of the voltage bar, so we need to adapt the length
0101         if ((v > 0) && (((225 < m_dir) && (m_dir < 315)) || ((45 < m_dir) && (m_dir < 135))))
0102             length--;
0103 
0104         else if ((v < 0) && (((135 < m_dir) && (m_dir < 225)) || ((315 < m_dir) || (m_dir < 45))))
0105             length++;
0106 
0107         if ((m_dir > 270) || (m_dir <= 90))
0108             p.drawLine(3, -thickness/2, 3, length);
0109         else
0110             p.drawLine(3, thickness/2, 3, -length);
0111     }
0112 
0113     pen.setWidth((numPins() > 1) ? 2 : 1);
0114     p.setPen(pen);
0115 
0116     p.drawLine(0, 0, m_length, 0);
0117 
0118     deinitPainter(p);
0119 }
0120 
0121 void PinNode::initPoints()
0122 {
0123     int l = -m_length;
0124 
0125     // Bounding rectangle, facing right
0126     QPolygon pa(QRect(0, -8, l, 16));
0127 
0128     QTransform m;
0129     m.rotate(m_dir);
0130     pa = m.map(pa);
0131     setPoints(pa);
0132 }