From ed362a6b556a056a350e2fd97a6aa6894f4be83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=8B=D1=87=D0=BA=D0=BE=D0=B2=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Wed, 15 Nov 2017 14:27:51 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@316 a8b55f48-bf90-11e4-a774-851b48703e85 --- qad/blockview/blockbusitem.cpp | 72 ++++++++++++++-- qad/blockview/blockbusitem.h | 32 ++++++-- qad/blockview/blockitem.cpp | 146 +++++++++++++-------------------- qad/blockview/blockitem.h | 108 +++--------------------- qad/blockview/blockitempin.cpp | 146 +++++++++++++++++++++++++++++++++ qad/blockview/blockitempin.h | 109 ++++++++++++++++++++++++ qad/blockview/blockview.cpp | 50 +++++++---- qad/blockview/blockview.h | 25 +++++- 8 files changed, 473 insertions(+), 215 deletions(-) create mode 100644 qad/blockview/blockitempin.cpp create mode 100644 qad/blockview/blockitempin.h diff --git a/qad/blockview/blockbusitem.cpp b/qad/blockview/blockbusitem.cpp index 29f149e..9c75ec1 100644 --- a/qad/blockview/blockbusitem.cpp +++ b/qad/blockview/blockbusitem.cpp @@ -1,4 +1,4 @@ -#include "blockbusitem.h" +#include "blockview.h" BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() { @@ -44,7 +44,14 @@ void BlockBusItem::_init() { max_ep = 0; selPoint = selSegment = state_ = -1; pen_width = 2.; + point_size = 3.; moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false; + anim_point_size.setTargetObject(this); + anim_point_size.setPropertyName("pointSize"); + anim_point_size.setStartValue(0); + anim_point_size.setEasingCurve(QEasingCurve::OutQuad); + anim_point_size.setEndValue(point_size); + anim_point_size.setDuration(200); } @@ -169,6 +176,11 @@ void BlockBusItem::appendPoint(const QPointF & p) { } +void BlockBusItem::appendPoint(qreal x, qreal y) { + appendPoint(QPointF(x, y)); +} + + void BlockBusItem::clear() { pol.clear(); segments.clear(); @@ -176,6 +188,31 @@ void BlockBusItem::clear() { } +void BlockBusItem::movePolyline(const QPointF & dp) { + pol.translate(dp); + prepareGeometryChange(); +} + + +void BlockBusItem::movePoint(int index, const QPointF & dp) { + pol[index] += dp; + prepareGeometryChange(); +} + + +void BlockBusItem::setWidth(const double & w) { + pen_width = w; + update(); +} + + +void BlockBusItem::setColor(const QColor & c) { + pu.setColor(c); + bu.setColor(c); + update(); +} + + void BlockBusItem::markAsInput() { mark_in = true; mark_out = false; @@ -457,7 +494,15 @@ void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) { if (temp_) return; QPointF sp = e->scenePos(); + int pp = selPoint; testPoint(sp, &selPoint, &selSegment); + if (selPoint >= 0 && pp < 0) { + if (((BlockView *)scene()->views().back())->isBlockAnimationEnabled()) { + setPointSize(0); + anim_point_size.start(); + } else setPointSize(anim_point_size.endValue().toDouble()); + } + if (selPoint >= 0 || selSegment >= 0) { setToolTip(tt); update(); @@ -488,6 +533,7 @@ void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { selPoint = selSegment = -1; setPen(pu); setBrush(bu); setToolTip(QString()); + anim_point_size.stop(); update(); QGraphicsObject::hoverLeaveEvent(e); } @@ -505,6 +551,8 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { return; } int btncnt = 0; + if (endpoints().contains(selPoint) && e->button() == Qt::LeftButton) + QMetaObject::invokeMethod(scene()->views().back(), "startBusPointMove", Q_ARG(int, busType())); if (e->buttons().testFlag(Qt::LeftButton)) btncnt++; if (e->buttons().testFlag(Qt::RightButton)) btncnt++; if (e->buttons().testFlag(Qt::MidButton)) btncnt++; @@ -515,8 +563,9 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { moved = false; QPointF lp = qp - press_pos; //qDebug() << lp; - if (selPoint >= 0 && selPoint <= pol.size() - 1) + if (selPoint >= 0 && selPoint <= pol.size() - 1) { pol[selPoint] += lp; + } if (selSegment >= 0 && selSegment <= segments.size() - 1) { pol[segments[selSegment].first] += lp; pol[segments[selSegment].second] += lp; @@ -624,11 +673,16 @@ void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) { } if (moved) { simplify(false); - reconnect(); - emitAction(lm_point ? BlockItemBase::BusPointMove : BlockItemBase::BusSegmentMove); + if (lm_point) { + QMetaObject::invokeMethod(scene()->views().back(), "endBusPointMove", Qt::QueuedConnection); + emitAction(BlockItemBase::BusPointMove); + } else { + reconnect(); + emitAction( BlockItemBase::BusSegmentMove); + } } moved = new_segment = false; - QGraphicsObject::mouseReleaseEvent(e); + QGraphicsObject::mouseReleaseEvent(e); } @@ -716,7 +770,7 @@ void BlockBusItem::paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidg p->setPen(ph); p->setBrush(bh); p->translate(pol[selPoint]); - p->drawEllipse(QPointF(0, 0), 3, 3); + p->drawEllipse(QPointF(0, 0), point_size, point_size); p->restore(); } if (selSegment >= 0) { @@ -728,6 +782,12 @@ void BlockBusItem::paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidg } +void BlockBusItem::setPointSize(double s) { + point_size = s; + update(); +} + + QRectF BlockBusItem::boundingRect() const { QPolygonF p(pol); if (new_segment) p << new_end; diff --git a/qad/blockview/blockbusitem.h b/qad/blockview/blockbusitem.h index f866547..95ad312 100644 --- a/qad/blockview/blockbusitem.h +++ b/qad/blockview/blockbusitem.h @@ -4,10 +4,24 @@ #include "blockitem.h" +/// data: +/// 1002 - flag for move parent (true) +/// 1003 - flag for visualize selection (true) +/// 1004 - BlockItemPin ("pin") +/// 1005 - BlockBusItem ("connection") +/// 1006 - BlockItem ("item") +/// 1007 - BlockItem selection ("item_selection") +/// 1008 - item is NOT decor, ignore for function decors() (true) +/// 1009 - item is scene decor ("decor") +/// 1010 - BlockItem decor (src text for QGraphicsSimpleTextItem) +/// 1011 - item is BlockItem decor ("decor") +/// 1100 - flag for correct move (true) + + class BlockBusItem: public QGraphicsObject, public PropertyStorage { Q_OBJECT Q_INTERFACES(QGraphicsItem) - //Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false) friend class BlockView; public: BlockBusItem(bool temp = false); @@ -22,7 +36,7 @@ public: int busType() const {return bus_type;} QString busName() const {return bus_name;} void appendPoint(const QPointF & p); - void appendPoint(qreal x, qreal y) {appendPoint(QPointF(x, y));} + void appendPoint(qreal x, qreal y); void testPoint(QPointF pos, int * sel_point, int * sel_segment); void clear(); /*void setStart(const QPointF & p) {pol[0] = p; scene()->update();} @@ -36,11 +50,11 @@ public: void setBrush(const QBrush & b) {b_ = b; update();} QBrush brush() const {return b_;} //void disconnectBrick() {BrickBase::disconnect(brickFrom, portFrom, brickTo, portTo);} - void movePolyline(const QPointF & dp) {pol.translate(dp); prepareGeometryChange();} - void movePoint(int index, const QPointF & dp) {pol[index] += dp; prepareGeometryChange();} + void movePolyline(const QPointF & dp); + void movePoint(int index, const QPointF & dp); double width() const {return pen_width;} - void setWidth(const double & w) {pen_width = w; update();} - void setColor(const QColor & c) {pu.setColor(c); bu.setColor(c); update();} + void setWidth(const double & w); + void setColor(const QColor & c); int addPoint(const QPointF & point, bool update = true); int segmentPointPair(int point, int * seg = 0) const; void removePoint(int index); @@ -104,6 +118,12 @@ protected: int selPoint, selSegment, max_ep, bus_type, state_; bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point; +private: + double pointSize() const {return point_size;} + void setPointSize(double s); + + double point_size; + QPropertyAnimation anim_point_size; }; diff --git a/qad/blockview/blockitem.cpp b/qad/blockview/blockitem.cpp index 976f971..a593e90 100644 --- a/qad/blockview/blockitem.cpp +++ b/qad/blockview/blockitem.cpp @@ -1,94 +1,7 @@ -#include "blockitem.h" +#include "blockview.h" #include - -BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsItem * _parent): QGraphicsItem(_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); - setState(Disconnected); - setAlignment(a); - setBusType(bus_type_); - setText(text_); - setZValue(2.); - setDirection(BlockItemPin::InputOutput); - _reparent(); -} - - -void BlockItemPin::resizePin(double r) { - ell_item.setRect(-r, -r, r+r, r+r); -} - - -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()[0], "getPinMC", Q_ARG(bool*, &m_pin_mc)); - if ((state() != Disconnected) && !m_pin_mc) return; - saveState(); - setState(BlockItemPin::Hover); - update(); -} - - -void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { - restoreState(); - update(); -} - #define BLOCKITEM_DEFAULT_PIN_MARGIN 20 BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), @@ -110,6 +23,15 @@ g_main(this), g_selection(this) { g_selection.setPen(p); g_selection.setBrush(QColor(128, 128, 255, 32)); pins_margin = BLOCKITEM_DEFAULT_PIN_MARGIN; + anim_thick.setTargetObject(this); + anim_thick.setPropertyName("_thickness"); + anim_thick.setEasingCurve(QEasingCurve::OutQuad); + anim_thick.setDuration(300); + anim_sel.setTargetObject(this); + anim_sel.setPropertyName("_selRect"); + anim_sel.setEasingCurve(QEasingCurve::OutCubic); + anim_sel.setDuration(400); + t_sel.start(); //g_main.setBrush(QColor(128, 128, 128, 64)); /* BlockItemPin * pin = new BlockItemPin(Qt::AlignRight, 0, this); @@ -447,11 +369,25 @@ void BlockItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { void BlockItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { + bool anim = ((BlockView *)scene()->views().back())->isBlockAnimationEnabled(); + if (anim) { + anim_thick.stop(); + anim_thick.setStartValue(thickness()); + anim_thick.setEndValue(2); + anim_thick.start(); + } else setThickness(2); emit blockHoverEnter(this); } void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { + bool anim = ((BlockView *)scene()->views().back())->isBlockAnimationEnabled(); + if (anim) { + anim_thick.stop(); + anim_thick.setStartValue(thickness()); + anim_thick.setEndValue(1); + anim_thick.start(); + } else setThickness(1); emit blockHoverLeave(this); } @@ -484,7 +420,39 @@ void BlockItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * optio QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) { - if (change == QGraphicsItem::ItemSelectedChange) + if (change == QGraphicsItem::ItemSelectedChange) { +// qDebug() << "select" << value.toBool(); + if (value.toBool() && !isSelected() && ((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && t_sel.elapsed() > 50) { + g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 16)); + anim_sel.setStartValue(selectionRect()); + anim_sel.setEndValue(enlargedRect(g_main.rect(), 0, 0, 8)); + anim_sel.start(); + } + t_sel.restart(); g_selection.setVisible(value.toBool()); + } return QGraphicsItem::itemChange(change, value); } + + +double BlockItem::thickness() const { + return g_main.pen().widthF(); +} + + +void BlockItem::setThickness(double w) { + QPen p = g_main.pen(); + p.setWidthF(w); + g_main.setPen(p); +} + + +QRectF BlockItem::selectionRect() const { + return g_selection.rect(); +} + + +void BlockItem::setSelectionRect(const QRectF & r) { + g_selection.setRect(r); +} + diff --git a/qad/blockview/blockitem.h b/qad/blockview/blockitem.h index ee20c30..3145509 100644 --- a/qad/blockview/blockitem.h +++ b/qad/blockview/blockitem.h @@ -1,20 +1,8 @@ #ifndef BLOCKITEM_H #define BLOCKITEM_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "blockbase.h" -#include "alignedtextitem.h" -#include "chunkstream.h" - +#include "blockitempin.h" +#include /// data: /// 1002 - flag for move parent (true) @@ -29,93 +17,14 @@ /// 1011 - item is BlockItem decor ("decor") /// 1100 - flag for correct move (true) - -class BlockItem; -class BlockBusItem; - - -class BlockItemPin: public QGraphicsItem, public PropertyStorage -{ - friend class BlockView; - friend class BlockItem; -public: - BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsItem * parent_ = 0); - - enum State { - Disconnected, - Connected, - Hover, - Drop, - Accept, - Reject - }; - - enum Direction { - None = 0x0, - Input = 0x1, - Output = 0x2, - InputOutput = 0x3 - }; - - void setPen(const QPen & p) {ell_item.setPen(p);} - QPen pen() const {return ell_item.pen();} - void setBrush(const QBrush & b) {ell_item.setBrush(b);} - QBrush brush() const {return ell_item.brush();} - - int busType() const {return bus_type;} - Qt::Alignment alignment() const {return align;} - Direction direction() const {return dir;} - QString text() const {return text_item.text();} - State state() const {return state_;} - - void setBusType(int type_) {bus_type = type_;} - void setAlignment(Qt::Alignment a) {align = a; _init(true);} - void setDirection(Direction d) {dir = d; _init(true);} - void setText(const QString & t) {text_item.setText(t); _init(true);} - void setState(State s) {state_ = s; setBrush(br[int(state_)]); update();} - - void saveState() {sstate_.push(state_);} - bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;} - void clearStateStack() {sstate_.clear();} - - void resizePin(double r = 7.); - - BlockItem * parent() const {return parent_;} - QList connectedBuses() const {return buses_;} - - enum {Type = UserType + 3}; - -protected: - void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {} - QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());} - int type() const {return Type;} - QVariant itemChange(GraphicsItemChange change, const QVariant & value); - void hoverEnterEvent(QGraphicsSceneHoverEvent * e); - void hoverLeaveEvent(QGraphicsSceneHoverEvent * e); - void _init(bool affect_parent = false); - void _reparent(); - int bus_type; - State state_; - QGraphicsEllipseItem ell_item; - QGraphicsSimpleTextItem text_item; - QStack sstate_; - QList buses_; - BlockItem * parent_; - Qt::Alignment align; - Direction dir; - QBrush br[6]; - -}; - - - - class BlockItem: public QGraphicsObject, public PropertyStorage { friend class BlockView; friend class BlockItemPin; friend class DrawTools; Q_OBJECT + Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false) + Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false) public: BlockItem(QGraphicsItem * parent = 0); ~BlockItem(); @@ -176,6 +85,15 @@ protected: QMap > pins_; QList decors_; +private: + double thickness() const; + void setThickness(double w); + QRectF selectionRect() const; + void setSelectionRect(const QRectF & r); + + QPropertyAnimation anim_thick, anim_sel; + QTime t_sel; + signals: void blockHoverEnter(BlockItem * b); void blockHoverLeave(BlockItem * b); diff --git a/qad/blockview/blockitempin.cpp b/qad/blockview/blockitempin.cpp new file mode 100644 index 0000000..7b1ef90 --- /dev/null +++ b/qad/blockview/blockitempin.cpp @@ -0,0 +1,146 @@ +#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(200); + 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::setState(State s) { + State os = state_; + state_ = s; + setBrush(br[int(state_)]); + if (s == Accept && os != Accept && anim_accept.state() != QAbstractAnimation::Running && ((BlockView *)scene()->views().back())->isBlockAnimationEnabled()) { + anim_accept.setStartValue(pinSize()); + anim_accept.setEndValue(10.); + anim_accept.start(); + } + 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(); +} + diff --git a/qad/blockview/blockitempin.h b/qad/blockview/blockitempin.h new file mode 100644 index 0000000..cbea79f --- /dev/null +++ b/qad/blockview/blockitempin.h @@ -0,0 +1,109 @@ +#ifndef BLOCKITEMPIN_H +#define BLOCKITEMPIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "blockbase.h" +#include "alignedtextitem.h" +#include "chunkstream.h" + + +class BlockItem; +class BlockBusItem; + + +class BlockItemPin: public QGraphicsObject, public PropertyStorage +{ + friend class BlockView; + friend class BlockItem; + Q_OBJECT + Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false) +public: + BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0); + + enum State { + Disconnected, + Connected, + Hover, + Drop, + Accept, + Reject + }; + + enum Direction { + None = 0x0, + Input = 0x1, + Output = 0x2, + InputOutput = 0x3 + }; + + void setPen(const QPen & p) {ell_item.setPen(p);} + QPen pen() const {return ell_item.pen();} + void setBrush(const QBrush & b) {ell_item.setBrush(b);} + QBrush brush() const {return ell_item.brush();} + + int busType() const {return bus_type;} + Qt::Alignment alignment() const {return align;} + Direction direction() const {return dir;} + QString text() const {return text_item.text();} + State state() const {return state_;} + + void setBusType(int type_) {bus_type = type_;} + void setAlignment(Qt::Alignment a) {align = a; _init(true);} + void setDirection(Direction d) {dir = d; _init(true);} + void setText(const QString & t) {text_item.setText(t); _init(true);} + void setState(State s); + + void saveState() {sstate_.push(state_);} + bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;} + void clearStateStack() {sstate_.clear();} + + void enlargePin(bool enlarge); + + BlockItem * parent() const {return parent_;} + QList connectedBuses() const {return buses_;} + + enum {Type = UserType + 3}; + +protected: + void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {} + QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());} + int type() const {return Type;} + QVariant itemChange(GraphicsItemChange change, const QVariant & value); + void hoverEnterEvent(QGraphicsSceneHoverEvent * e); + void hoverLeaveEvent(QGraphicsSceneHoverEvent * e); + void _init(bool affect_parent = false); + void _reparent(); + int bus_type; + State state_; + QGraphicsEllipseItem ell_item; + QGraphicsSimpleTextItem text_item; + QStack sstate_; + QList buses_; + BlockItem * parent_; + Qt::Alignment align; + Direction dir; + QBrush br[6]; + +private slots: + void animationAccept(); + +private: + void resizePin(double r); + double pinSize() const; + + QPropertyAnimation anim_pin_size; + QPropertyAnimation anim_accept; + +}; + + +#endif // BLOCKITEMPIN_H diff --git a/qad/blockview/blockview.cpp b/qad/blockview/blockview.cpp index 75bca40..4499e0f 100644 --- a/qad/blockview/blockview.cpp +++ b/qad/blockview/blockview.cpp @@ -28,7 +28,7 @@ BlockView::~BlockView() { void BlockView::_init() { grid_visible = grid_snap = pm_connect = navigation = m_connect = m_trace_with_buses = minimap = true; - mm_drag = moved = new_branch = new_bus = mm_cancel = iconnect = mm_copy = m_pin_mc = mm_thumb = false; + mm_drag = moved = new_branch = new_bus = mm_cancel = iconnect = mm_copy = m_pin_mc = mm_thumb = move_bus_point = false; match_bus = bus_from = 0; mm_ci = 0; hpin = 0; @@ -41,7 +41,7 @@ void BlockView::_init() { smode = BlockView::MultiSelection; cur_scl = thumb_scl = 1.; _talpha = 0.; - ae_enabled = is_nav_anim = true; + ae_enabled = is_nav_anim = is_block_anim = true; nav_prev_aa = nav_prev_grid = true; thumb_size = QSizeF(200, 200); if (scene() == 0) { @@ -339,12 +339,11 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { break; } if (hpin) { - if (hpin->state() == BlockItemPin::Accept) - hoverAcceptedPin(hpin); - else - hpin = 0; - } else - unhoverPins(); + if (hpin->state() == BlockItemPin::Accept) { + unhoverPins(hpin); + hoverAcceptedPin(hpin, true); + } else hpin = 0; + } else unhoverPins(); if (new_branch) { matchBus(); break; @@ -1283,10 +1282,10 @@ void BlockView::markPins(int bus_type) { BlockItemPin * p = qgraphicsitem_cast(i); p->saveState(); if (m_pin_mc) { - if (p->busType() == tmp_bus.busType()) + if (p->busType() == bus_type) p->setState(BlockItemPin::Accept); } else { - if (p->busType() == tmp_bus.busType() && p->state() == BlockItemPin::Disconnected) + if (p->busType() == bus_type && p->state() == BlockItemPin::Disconnected) p->setState(BlockItemPin::Accept); } } @@ -1307,17 +1306,20 @@ void BlockView::unmarkPins(bool to_normal) { } -void BlockView::hoverAcceptedPin(BlockItemPin * pin) { +void BlockView::hoverAcceptedPin(BlockItemPin * pin, bool hover) { if (!pin) return; - pin->resizePin(12.); + pin->enlargePin(hover); } -void BlockView::unhoverPins() { +void BlockView::unhoverPins(BlockItemPin* excl_pin) { QList gi = scene_->items(); - foreach (QGraphicsItem * i, gi) - if (i->data(1004) == "pin") - ((BlockItemPin*)i)->resizePin(); + foreach (QGraphicsItem * i, gi) { + if (excl_pin == ((BlockItemPin*)i)) continue; + if (i->data(1004) == "pin") { + ((BlockItemPin*)i)->enlargePin(false); + } + } } @@ -1473,6 +1475,21 @@ void BlockView::newBranch(BlockBusItem * item) { } +void BlockView::startBusPointMove(int bus_type) { + move_bus_point = true; + newBusStarted(bus_type); + markPins(bus_type); +} + + +void BlockView::endBusPointMove() { + move_bus_point = false; + unmarkPins(); + reconnectAll(); +} + + + void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) { trace(item->press_pos, to, &tmp_bus); tmp_bus.show(); @@ -1601,6 +1618,7 @@ void BlockView::reconnectAll() { buses << qgraphicsitem_cast(i); } foreach (BlockItemPin * p, pins) { + p->clearStateStack(); p->setState(BlockItemPin::Disconnected); p->buses_.clear(); } diff --git a/qad/blockview/blockview.h b/qad/blockview/blockview.h index 34faba3..447e0c1 100644 --- a/qad/blockview/blockview.h +++ b/qad/blockview/blockview.h @@ -12,6 +12,20 @@ #include "blockviewwavetrace.h" #include "blockbusitem.h" +/// data: +/// 1002 - flag for move parent (true) +/// 1003 - flag for visualize selection (true) +/// 1004 - BlockItemPin ("pin") +/// 1005 - BlockBusItem ("connection") +/// 1006 - BlockItem ("item") +/// 1007 - BlockItem selection ("item_selection") +/// 1008 - item is NOT decor, ignore for function decors() (true) +/// 1009 - item is scene decor ("decor") +/// 1010 - BlockItem decor (src text for QGraphicsSimpleTextItem) +/// 1011 - item is BlockItem decor ("decor") +/// 1100 - flag for correct move (true) + + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -31,6 +45,7 @@ class BlockView: public QGraphicsView Q_PROPERTY(bool connectByMouse READ isConnectByMouseEnabled WRITE setConnectByMouseEnabled) Q_PROPERTY(bool navigationEnabled READ isNavigationEnabled WRITE setNavigationEnabled) Q_PROPERTY(bool navigateAnimationEnabled READ isNavigateAnimationEnabled WRITE setNavigateAnimationEnabled) + Q_PROPERTY(bool blockAnimationEnabled READ isBlockAnimationEnabled WRITE setBlockAnimationEnabled) Q_PROPERTY(bool traceConsiderBuses READ isTraceConsiderBuses WRITE setTraceConsiderBuses) Q_PROPERTY(bool pinMulticonnect READ isPinMulticonnectEnabled WRITE setPinMulticonnectEnabled) Q_PROPERTY(bool miniMap READ isMiniMapEnabled WRITE setMiniMapEnabled) @@ -55,6 +70,7 @@ public: bool isPostMoveConnectEnabled() const {return pm_connect;} bool isNavigationEnabled() const {return navigation;} bool isNavigateAnimationEnabled() const {return is_nav_anim;} + bool isBlockAnimationEnabled() const {return is_block_anim;} bool isConnectByMouseEnabled() const {return m_connect;} bool isTraceConsiderBuses() const {return m_trace_with_buses;} bool isPinMulticonnectEnabled() const {return m_pin_mc;} @@ -115,8 +131,8 @@ protected: bool connectTmpToBus(BlockBusItem* bus); void markPins(int bus_type); void unmarkPins(bool to_normal = false); - void hoverAcceptedPin(BlockItemPin * pin); - void unhoverPins(); + void hoverAcceptedPin(BlockItemPin * pin, bool hover); + void unhoverPins(BlockItemPin * excl_pin = 0); void simplifyBuses(); void moveBuses(const QList & items, QPointF dp); QList internalBuses(const QList & items); @@ -155,7 +171,7 @@ protected: Qt::KeyboardModifiers mm_mods; QPropertyAnimation thumb_anim, nav_anim; int timer_thumb, thumb_hide_delay, thick; - bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim; + bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim, move_bus_point; bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap; bool nav_prev_aa, nav_prev_grid; double grid_step, grid_points, cur_scl, _talpha, thumb_scl; @@ -174,6 +190,8 @@ protected slots: void _setThumb(double v); void _setNav(QRectF v); void _navFinished(); + void startBusPointMove(int bus_type); + void endBusPointMove(); public slots: void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();} @@ -184,6 +202,7 @@ public slots: void setPostMoveConnectEnabled(bool on) {pm_connect = on;} void setNavigationEnabled(bool on) {navigation = on;} void setNavigateAnimationEnabled(bool on) {is_nav_anim = on;} + void setBlockAnimationEnabled(bool on) {is_block_anim = on;} void setConnectByMouseEnabled(bool on) {m_connect = on;} void setTraceConsiderBuses(bool on) {m_trace_with_buses = on;} void setPinMulticonnectEnabled(bool on) {m_pin_mc = on;}