1
git-svn-id: svn://db.shs.com.ru/libs@1 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
419
qad_blockview/blockitem.cpp
Normal file
419
qad_blockview/blockitem.cpp
Normal file
@@ -0,0 +1,419 @@
|
||||
#include "blockitem.h"
|
||||
|
||||
|
||||
|
||||
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::_init(bool affect_parent) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
//if (state() == Hover)
|
||||
restoreState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(),
|
||||
g_main(this), g_selection(this) {
|
||||
setData(1006, "item");
|
||||
setZValue(1.);
|
||||
setAcceptHoverEvents(true);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
|
||||
g_main.setData(1002, true);
|
||||
g_selection.setData(1007, "item_selection");
|
||||
g_selection.setAcceptedMouseButtons(0);
|
||||
g_selection.setZValue(10.);
|
||||
g_selection.hide();
|
||||
g_selection.setData(1003, true);
|
||||
col = Qt::lightGray;
|
||||
_resize(QSizeF(100., 60.));
|
||||
QPen p(QColor(128, 128, 255), 1., Qt::DotLine);
|
||||
p.setCosmetic(true);
|
||||
g_selection.setPen(p);
|
||||
g_selection.setBrush(QColor(128, 128, 255, 32));
|
||||
//g_main.setBrush(QColor(128, 128, 128, 64));
|
||||
/*
|
||||
BlockItemPin * pin = new BlockItemPin(Qt::AlignRight, 0, this);
|
||||
pin->setText("text");
|
||||
pin->setBusType(0);
|
||||
addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignTop, this);
|
||||
pin->setBusType(0); addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignLeft, this);
|
||||
pin->setBusType(1); addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignRight, this);
|
||||
pin->setBusType(1); addPin(pin);*/
|
||||
}
|
||||
|
||||
|
||||
BlockItem::~BlockItem() {
|
||||
clearDecors();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::_resize(QSizeF s) {
|
||||
g_main.setRect(QRectF(QPointF(), s));
|
||||
g_main.setPos(-g_main.rect().center());
|
||||
g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 8));
|
||||
g_selection.setPos(g_main.pos());
|
||||
QRadialGradient g(g_main.rect().width() / 2., 0, qMax<qreal>(g_main.rect().width() / 2., g_main.rect().height()));
|
||||
g.setSpread(QGradient::PadSpread);
|
||||
g.setCoordinateMode(QGradient::LogicalMode);
|
||||
g.setColorAt(0., col.darker(120.));
|
||||
g.setColorAt(1., col.lighter(120.));
|
||||
g_main.setBrush(QBrush(g));
|
||||
prepareGeometryChange();
|
||||
arrangePins();
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::addPin(BlockItemPin * pin, bool update_) {
|
||||
pin->setParentItem(this);
|
||||
pins_[pin->alignment()] << pin;
|
||||
pin->parent_ = this;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_) {
|
||||
BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this);
|
||||
pin->parent_ = this;
|
||||
pins_[pin->alignment()] << pin;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removePin(BlockItemPin * pin) {
|
||||
if (!pin) return;
|
||||
QMutableMapIterator<Qt::Alignment, QList<BlockItemPin * > > it(pins_);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
it.value().removeAll(pin);
|
||||
}
|
||||
delete pin;
|
||||
arrangePins();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::addDecor(QGraphicsItem * item) {
|
||||
if (decors_.contains(item)) return;
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem*>(item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->setData(1010, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem*>(item))
|
||||
qgraphicsitem_cast<AlignedTextItem*>(item)->setData(1010, qgraphicsitem_cast<AlignedTextItem*>(item)->text());
|
||||
item->setData(1002, true);
|
||||
item->setData(1011, "decor");
|
||||
decors_ << item;
|
||||
item->setParentItem(this);
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removeDecor(QGraphicsItem * item) {
|
||||
if (scene() && item)
|
||||
scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
|
||||
decors_.removeAll(item);
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::takePins() {
|
||||
QVector<BlockItemPin * > ret = pins();
|
||||
pins_.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::clearPins() {
|
||||
QList<QList<BlockItemPin * > > mp = pins_.values();
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
qDeleteAll(mp[i]);
|
||||
pins_.clear();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::clearDecors() {
|
||||
bool pbs = false;
|
||||
if (scene()) pbs = scene()->blockSignals(true);
|
||||
if (scene())
|
||||
foreach (QGraphicsItem * i, decors_)
|
||||
scene()->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
qDeleteAll(decors_);
|
||||
decors_.clear();
|
||||
if (scene()) {
|
||||
scene()->blockSignals(pbs);
|
||||
QMetaObject::invokeMethod(scene(), "selectionChanged");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::pins() const {
|
||||
QList<QList<BlockItemPin * > > mp = pins_.values();
|
||||
QVector<BlockItemPin * > ret;
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
ret << mp[i].toVector();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockItem::saveModel() {
|
||||
/*QDataStream s(&ret, QIODevice::ReadWrite);
|
||||
QVector<BlockItemPin * > ps = pins();
|
||||
s << pos() << rotation() << size() << color() << ps.size();
|
||||
foreach (BlockItemPin * p, ps)
|
||||
s << int(p->alignment()) << p->busType() << p->text() << p->devices();
|
||||
s << decors_.size();
|
||||
foreach (QGraphicsItem * i, decors_)
|
||||
s << i;*/
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, size()) << cs.chunk(4, color()) << cs.chunk(5, pins()) << cs.chunk(6, decors_);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::loadModel(const QByteArray & data) {
|
||||
//qDebug() << "load from" << data.size() << "bytes";
|
||||
clearPins();
|
||||
clearDecors();
|
||||
if (data.isEmpty()) return;
|
||||
/*QDataStream s(data);
|
||||
{QPointF _v; s >> _v;}
|
||||
{qreal _v; s >> _v;}
|
||||
{QSizeF _v; s >> _v; setSize(_v);}
|
||||
{QColor _v; s >> _v; setColor(_v);}
|
||||
int _s; s >> _s;
|
||||
for (int i = 0; i < _s; ++i) {
|
||||
BlockItemPin * pin = new BlockItemPin();
|
||||
{int _v; s >> _v; pin->setAlignment((Qt::Alignment)_v);}
|
||||
{int _v; s >> _v; pin->setBusType(_v);}
|
||||
{QString _v; s >> _v; pin->setText(_v);}
|
||||
{QMap<QString, BlockItemPin::Device> _v; s >> _v; pin->setDevices(_v);}
|
||||
addPin(pin);
|
||||
}
|
||||
s >> _s;
|
||||
for (int i = 0; i < _s; ++i) {
|
||||
if (s.atEnd()) break;
|
||||
QGraphicsItem * ni = 0;
|
||||
s >> ni;
|
||||
if (ni) {
|
||||
addDecor(ni);
|
||||
}
|
||||
}*/
|
||||
ChunkStream cs(data);
|
||||
QVector<BlockItemPin * > tp;
|
||||
QList<QGraphicsItem * > dl;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: /*setPos(cs.getData<QPointF>());*/ break;
|
||||
case 2: /*setRotation(cs.getData<qreal>());*/ break;
|
||||
case 3: setSize(cs.getData<QSizeF>()); break;
|
||||
case 4: setColor(cs.getData<QColor>()); break;
|
||||
case 5:
|
||||
tp = cs.getData<QVector<BlockItemPin * > >();
|
||||
foreach (BlockItemPin * p, tp) addPin(p);
|
||||
break;
|
||||
case 6:
|
||||
dl = cs.getData<QList<QGraphicsItem * > >();
|
||||
foreach (QGraphicsItem * d, dl) addDecor(d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockItem::save() {
|
||||
ChunkStream cs;
|
||||
QMap<QString, QList<BlockItem::Property> > pp;
|
||||
foreach (BlockItemPin * p, pins()) {
|
||||
pp[p->text()] = p->properties();
|
||||
}
|
||||
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::load(const QByteArray & data) {
|
||||
if (data.isEmpty()) return;
|
||||
ChunkStream cs(data);
|
||||
QMap<QString, QMap<QString, QString> > _v;
|
||||
QMap<QString, QList<BlockItem::Property> > _p;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: setPos(cs.getData<QPointF>()); break;
|
||||
case 2: setRotation(cs.getData<qreal>()); break;
|
||||
case 3: props = cs.getData<QList<BlockItem::Property> >(); break;
|
||||
case 5:
|
||||
_p = cs.getData<QMap<QString, QList<BlockItem::Property> > >();
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (_p.contains(p->text()))
|
||||
p->properties() = _p[p->text()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlockItem * BlockItem::copy() const {
|
||||
BlockItem * ret = new BlockItem();
|
||||
ret->setPos(pos());
|
||||
ret->setSize(size());
|
||||
ret->setColor(color());
|
||||
ret->setSelected(false);
|
||||
ret->props = props;
|
||||
QVector<BlockItemPin * > mp = pins();
|
||||
foreach (BlockItemPin * p, mp) {
|
||||
BlockItemPin * np = new BlockItemPin();
|
||||
np->setBusType(p->busType());
|
||||
np->setAlignment(p->alignment());
|
||||
np->setText(p->text());
|
||||
np->properties() = p->properties();
|
||||
ret->addPin(np);
|
||||
}
|
||||
QByteArray ba;
|
||||
foreach (QGraphicsItem * i, decors_) {
|
||||
ba.clear();
|
||||
QGraphicsItem * ni = 0;
|
||||
QDataStream s(&ba, QIODevice::ReadWrite); s << i;
|
||||
QDataStream s2(ba); s2 >> ni;
|
||||
if (ni)
|
||||
ret->addDecor(ni);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockItem::connectedBuses() const {
|
||||
QList<BlockBusItem * > ret;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
ret << p->connectedBuses();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinByText(const QString & t) const {
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->text() == t)
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const {
|
||||
if (bus == 0) return 0;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->connectedBuses().contains(bus))
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockItem::boundingRect() const {
|
||||
return g_main.mapRectToParent(g_main.boundingRect());
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) {
|
||||
//QGraphicsItem::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
#define _POS (i - ((cp.size() - 1) / 2)) * 20
|
||||
|
||||
void BlockItem::arrangePins() {
|
||||
//double w = g_main.rect().width(), h = g_main.rect().height();
|
||||
QVector<BlockItemPin * > pl = pins();
|
||||
pins_.clear();
|
||||
foreach (BlockItemPin * p, pl)
|
||||
pins_[p->alignment()] << p;
|
||||
QList<BlockItemPin * > cp = pins_.value(Qt::AlignBottom);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS, bottom());
|
||||
cp = pins_.value(Qt::AlignTop);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS, top());
|
||||
cp = pins_.value(Qt::AlignLeft);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(left(), _POS);
|
||||
cp = pins_.value(Qt::AlignRight);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(right(), _POS);
|
||||
}
|
||||
|
||||
#undef _POS
|
||||
|
||||
|
||||
void BlockItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
|
||||
//if ()
|
||||
}
|
||||
|
||||
|
||||
QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
|
||||
if (change == QGraphicsItem::ItemSelectedChange)
|
||||
g_selection.setVisible(value.toBool());
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
Reference in New Issue
Block a user