git-svn-id: svn://db.shs.com.ru/libs@316 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2017-11-15 14:27:51 +00:00
parent efeb95c1c3
commit ed362a6b55
8 changed files with 473 additions and 215 deletions

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -1,94 +1,7 @@
#include "blockitem.h"
#include "blockview.h"
#include <QApplication>
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<BlockItem*>(parentItem()) == 0) return;
QPen p = qgraphicsitem_cast<BlockItem*>(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);
}

View File

@@ -1,20 +1,8 @@
#ifndef BLOCKITEM_H
#define BLOCKITEM_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsObject>
#include <QGraphicsEllipseItem>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent>
#include <QStack>
#include <QDebug>
#include <qmath.h>
#include "blockbase.h"
#include "alignedtextitem.h"
#include "chunkstream.h"
#include "blockitempin.h"
#include <QTime>
/// 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<BlockBusItem * > 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<State> sstate_;
QList<BlockBusItem * > 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<Qt::Alignment, QVector<BlockItemPin * > > pins_;
QList<QGraphicsItem * > 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);

View File

@@ -0,0 +1,146 @@
#include "blockview.h"
#include <QApplication>
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<BlockItem*>(parentItem()) == 0) return;
QPen p = qgraphicsitem_cast<BlockItem*>(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();
}

View File

@@ -0,0 +1,109 @@
#ifndef BLOCKITEMPIN_H
#define BLOCKITEMPIN_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsObject>
#include <QGraphicsEllipseItem>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent>
#include <QStack>
#include <QDebug>
#include <QPropertyAnimation>
#include <qmath.h>
#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<BlockBusItem * > 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<State> sstate_;
QList<BlockBusItem * > 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

View File

@@ -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<BlockItemPin*>(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<QGraphicsItem * > 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<BlockBusItem*>(i);
}
foreach (BlockItemPin * p, pins) {
p->clearStateStack();
p->setState(BlockItemPin::Disconnected);
p->buses_.clear();
}

View File

@@ -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<QGraphicsItem * > & items, QPointF dp);
QList<BlockBusItem * > internalBuses(const QList<BlockItem * > & 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;}