#include "blockview.h" #include BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent): QGraphicsObject(_parent), ell_item(this), text_item(this) { parent_ = 0; setData(1004, "pin"); setAcceptHoverEvents(true); text_item.setData(1002, true); ell_item.setData(1003, true); br[Disconnected] = QBrush(Qt::lightGray); br[Connected] = QBrush(Qt::darkGreen); br[Hover] = QBrush(Qt::blue); br[Drop] = QBrush(Qt::green); br[Accept] = QBrush(Qt::green); br[Reject] = QBrush(Qt::red); anim_pin_size.setTargetObject(this); anim_pin_size.setPropertyName("pinSize"); anim_pin_size.setEasingCurve(QEasingCurve::OutElastic); anim_pin_size.setDuration(700); anim_accept.setTargetObject(this); anim_accept.setPropertyName("pinSize"); anim_accept.setEasingCurve(QEasingCurve::InOutQuad); anim_accept.setDuration(150); connect(&anim_accept, SIGNAL(finished()), this, SLOT(animationAccept())); setState(Disconnected); setAlignment(a); setBusType(bus_type_); setText(text_); setZValue(2.); setDirection(BlockItemPin::InputOutput); _reparent(); } void BlockItemPin::animAccept() { if (!((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && anim_accept.state() != QAbstractAnimation::Running) return; anim_accept.setStartValue(pinSize()); anim_accept.setEndValue(10.); anim_accept.start(); } void BlockItemPin::setState(State s) { State os = state_; state_ = s; setBrush(br[int(state_)]); if (s == Accept && os != Accept) { animAccept(); } update(); } void BlockItemPin::enlargePin(bool enlarge) { double sz = enlarge ? 12. : 7; if (anim_accept.state() == QAbstractAnimation::Running && enlarge) { anim_accept.stop(); resizePin(sz); } if (!((BlockView *)scene()->views().back())->isBlockAnimationEnabled()) { resizePin(sz); return; } if (sz == anim_pin_size.endValue()) return; anim_pin_size.stop(); anim_pin_size.setStartValue(pinSize()); anim_pin_size.setEndValue(sz); anim_pin_size.start(); } void BlockItemPin::resizePin(double r) { ell_item.setRect(-r, -r, r+r, r+r); } double BlockItemPin::pinSize() const { return ell_item.rect().width() / 2.; } void BlockItemPin::animationAccept() { if (anim_accept.endValue().toDouble() == 7.) return; anim_accept.setStartValue(pinSize()); anim_accept.setEndValue(7.); anim_accept.start(); } void BlockItemPin::_init(bool affect_parent) { text_item.setFont(AlignedTextItem::sceneFont(QApplication::font())); QRectF tbr = text_item.boundingRect(); const double r = 7.; ell_item.setRect(-r, -r, r+r, r+r); ell_item.setSpanAngle(16*180); text_item.resetTransform(); text_item.setPos(0, -tbr.height() / 2.); text_item.setTransformOriginPoint(0, tbr.height() / 2.); switch (align) { case Qt::AlignBottom: ell_item.setStartAngle(16*0); text_item.setRotation(-90.); text_item.moveBy(0, -r * 1.5); break; case Qt::AlignRight: ell_item.setStartAngle(16*90); text_item.setRotation(0.); text_item.moveBy(-tbr.width() - r * 1.5, 0); break; case Qt::AlignTop: ell_item.setStartAngle(16*180); text_item.setRotation(-90.); text_item.moveBy(0, tbr.width() + r * 1.5); break; case Qt::AlignLeft: ell_item.setStartAngle(16*270); text_item.setRotation(0.); text_item.moveBy(r * 1.5, 0); break; default: break; } if (affect_parent && parent_) parent_->arrangePins(); } void BlockItemPin::_reparent() { if (parentItem() == 0) return; if (qgraphicsitem_cast(parentItem()) == 0) return; QPen p = qgraphicsitem_cast(parentItem())->g_main.pen(); ell_item.setPen(p); if (scene()) { text_item.setFont(AlignedTextItem::sceneFont(scene()->font())); QRectF tbr = text_item.boundingRect(); text_item.resetTransform(); text_item.setPos(0, -tbr.height() / 2.); text_item.setTransformOriginPoint(0, tbr.height() / 2.); } } QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) { if (change == QGraphicsItem::ItemParentChange) _reparent(); return QGraphicsItem::itemChange(change, value); } void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { bool m_pin_mc = false; if (scene()) if (!scene()->views().isEmpty()) QMetaObject::invokeMethod(scene()->views().back(), "getPinMC", Q_ARG(bool*, &m_pin_mc)); if ((state() != Disconnected) && !m_pin_mc) return; saveState(); setState(BlockItemPin::Hover); enlargePin(true); update(); } void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { restoreState(); enlargePin(false); update(); }