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

This commit is contained in:
2018-06-13 13:01:25 +00:00
parent 34e6af4c39
commit 372abdf222
5 changed files with 163 additions and 26 deletions

View File

@@ -125,6 +125,13 @@ void BlockItemPin::_reparent() {
}
QGraphicsView * BlockItemPin::_view() const {
if (!scene()) return 0;
if (scene()->views().isEmpty()) return 0;
return scene()->views().back();
}
QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
if (change == QGraphicsItem::ItemParentChange)
_reparent();
@@ -133,9 +140,12 @@ QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, cons
void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
QGraphicsView * v = _view();
bool m_pin_mc = false;
if (scene()) if (!scene()->views().isEmpty())
QMetaObject::invokeMethod(scene()->views().back(), "getPinMC", Q_ARG(bool*, &m_pin_mc));
if (v) {
QMetaObject::invokeMethod(v, "getPinMC", Q_ARG(bool*, &m_pin_mc));
QMetaObject::invokeMethod(v, "pinHoverInOut", Qt::QueuedConnection, Q_ARG(BlockItemPin*, this));
}
if ((state() != Disconnected) && !m_pin_mc) return;
saveState();
setState(BlockItemPin::Hover);
@@ -145,8 +155,9 @@ void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
QGraphicsView * v = _view();
restoreState();
enlargePin(false);
update();
if (v) QMetaObject::invokeMethod(v, "pinHoverInOut", Q_ARG(BlockItemPin*, 0));
}

View File

@@ -85,6 +85,7 @@ protected:
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
void _init(bool affect_parent = false);
void _reparent();
QGraphicsView * _view() const;
int bus_type;
State state_;
QGraphicsEllipseItem ell_item;

View File

@@ -237,19 +237,16 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
new_bus = false;
unmarkPins(true);
reconnectAll();
tmp_bus.hide();
tmp_bus.clear();
hideTmpBuses();
}
if (new_branch && mm_cancel) {
new_branch = false;
tmp_bus.hide();
tmp_bus.clear();
hideTmpBuses();
}
if (moved && mm_cancel) {
moved = false;
restoreSelState();
tmp_bus.hide();
tmp_bus.clear();
hideTmpBuses();
}
if (mm_cancel) return true;
mm_mods = me->modifiers();
@@ -300,11 +297,19 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->state() == BlockItemPin::Hover) {
trace_from = mm_ci->scenePos();
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->clearStateStack();
hideTmpBuses();
tmp_bus.setBusType(qgraphicsitem_cast<BlockItemPin*>(mm_ci)->busType());
tmp_bus.setEndpointsNumber(3);
tmp_bus.clear();
tmp_bus.show();
new_bus = true;
qDeleteAll(tmp_buses);
tmp_buses.clear();
foreach (BlockItemPin * p, last_multiconnect_pl) {
tmp_buses << new BlockBusItem(true);
tmp_buses.back()->setBusType(p->busType());
addItem(tmp_buses.back());
}
//qDebug() << "new" << ;
newBusStarted(tmp_bus.busType());
markPins(tmp_bus.busType());
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignLeft ||
@@ -353,6 +358,12 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
break;
}
trace(trace_from, me->scenePos(), &tmp_bus);
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
QPointF dp = last_multiconnect_pl[i]->scenePos() - trace_from;
//qDebug() << "trace" << i << dp;
trace(trace_from + dp, me->scenePos() + dp, tmp_buses[i], false);
tmp_buses[i]->show();
}
matchBus();
}
}
@@ -507,7 +518,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
}
}
if (new_branch) {
tmp_bus.hide();
hideTmpBuses(false);
}
if (moved && pm_connect) {
QList<QGraphicsItem*> ci;
@@ -525,6 +536,12 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
BlockBusItem * nb = new BlockBusItem(tmp_bus);
loadBus(nb);
addItem(nb);
//qDebug() << "also" << tmp_buses;
foreach (BlockBusItem * b, tmp_buses) {
nb = new BlockBusItem(*b);
loadBus(nb);
addItem(nb);
}
} else {
if (connectTmpToBus(match_bus)) {
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << match_bus);
@@ -532,8 +549,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
}
}
unmarkPins();
tmp_bus.hide();
tmp_bus.clear();
hideTmpBuses();
reconnectAll();
}
clearBusStates();
@@ -644,6 +660,13 @@ void BlockView::mouseMoveEvent(QMouseEvent * event) {
void BlockView::keyPressEvent(QKeyEvent * e) {
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
if (pin) {
//qDebug() << "pin" << pin->state();
if (pin->state() == BlockItemPin::Hover) {
highlightNearPins(pin, e->modifiers());
}
}
if (e->key() == Qt::Key_Shift) {
if (tmp_bus.isVisible()) {
switch (wavetrace.preferredDirection()) {
@@ -652,13 +675,31 @@ void BlockView::keyPressEvent(QKeyEvent * e) {
case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break;
}
trace(last_trace_from, trace_to, &tmp_bus);
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
QPointF dp = last_multiconnect_pl[i]->scenePos() - last_trace_from;
//qDebug() << "trace" << i << dp;
trace(last_trace_from + dp, trace_to + dp, tmp_buses[i], false);
tmp_buses[i]->show();
}
return;
}
return;
}
QGraphicsView::keyPressEvent(e);
}
void BlockView::keyReleaseEvent(QKeyEvent * e) {
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
if (pin) {
//qDebug() << "pin" << pin->state();
if (pin->state() == BlockItemPin::Hover) {
highlightNearPins(pin, e->modifiers());
}
}
QGraphicsView::keyReleaseEvent(e);
}
void BlockView::resizeEvent(QResizeEvent * event) {
QGraphicsView::resizeEvent(event);
thick = lineThickness();
@@ -897,7 +938,8 @@ QList<BlockItem * > BlockView::blocks() const {
QList<QGraphicsItem * > BlockView::decors() const {
QList<QGraphicsItem*> ret, gi = scene_->items();
foreach (QGraphicsItem * i, gi)
if ((i->data(1009) == "decor") && !i->data(1008).toBool() && (i->parentItem() == 0) && (i != &sel_rect) && (i != &tmp_bus))
if ((i->data(1009) == "decor") && !i->data(1008).toBool() && (i->parentItem() == 0)
&& (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i))
ret << i;
return ret;
}
@@ -1040,7 +1082,7 @@ QRectF BlockView::itemsBoundingRect() const {
bool f = true;
QRectF ret;
foreach (QGraphicsItem * i, gi)
if (i->isVisible() && (i != &tmp_bus)) {
if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) {
if ((i->data(1007) != "item_selection") && !i->data(1008).toBool()) {
QRectF br = i->mapRectToScene(i->boundingRect());
//qDebug() << br << i;
@@ -1117,11 +1159,13 @@ void BlockView::applyGridStep() {
}
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus) {
if (hpin)
scene_pos_to = hpin->scenePos();
last_trace_from = scene_pos_from;
trace_to = scene_pos_to;
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) {
if (primary) {
if (hpin)
scene_pos_to = hpin->scenePos();
last_trace_from = scene_pos_from;
trace_to = scene_pos_to;
}
QRect sr = scene_->sceneRect().toRect();
int dx = sr.left() / grid_step, dy = sr.top() / grid_step;
//qDebug() << dp;
@@ -1433,6 +1477,74 @@ QList<BlockBusItem * > BlockView::internalBuses(const QList<BlockItem * > & item
}
QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
QList<BlockItemPin * > ret;
bool up = km.testFlag(Qt::ShiftModifier);
bool down = km.testFlag(Qt::ControlModifier);
bool ab = km.testFlag(Qt::AltModifier);
//qDebug() << "nearPins" << km;
if (!pin || (!up && !down)) return ret;
const BlockItem * src = pin->parent();
if (!src) return ret;
bool dirs[2] = {up, down};
double dy[2] = {-1, 1};
for (int i = 0; i < 2; ++i) {
if (!dirs[i]) continue;
const BlockItem * cb = src;
BlockItemPin * cpin = pin;
//qDebug() << "dir" << dirs[i];
while (cpin) {
//qDebug() << "cur" << cpin;
QList<QGraphicsItem * > il = items(mapFromScene(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin())));
BlockItemPin * np = getPin(il);
if (np == cpin) break;
cpin = np;
if (cpin) {
if (((cb != cpin->parent()) && !ab) ||
(cpin->state() != BlockItemPin::Disconnected)) {
break;
}
cb = cpin->parent();
ret << cpin;
}
}
}
return ret;
}
BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const {
foreach (QGraphicsItem * i, list) {
if (i->data(1004) == "pin")
return qgraphicsitem_cast<BlockItemPin*>(i);
}
return 0;
}
void BlockView::highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
//qDebug() << "restore for" << last_multiconnect_pl.size();
foreach (BlockItemPin * p, last_multiconnect_pl)
p->restoreState();
QList<BlockItemPin * > pl = nearPins(pin, km);
foreach (BlockItemPin * p, pl) {
p->saveState();
p->setState(BlockItemPin::Hover);
}
last_multiconnect_pl = pl;
}
void BlockView::hideTmpBuses(bool clear) {
tmp_bus.hide();
if (clear) {
tmp_bus.clear();
qDeleteAll(tmp_buses);
tmp_buses.clear();
}
}
QList<BlockItem * > BlockView::selectedBlocks() const {
QList<BlockItem * > ret;
QList<QGraphicsItem * > sil = scene()->selectedItems();
@@ -1519,6 +1631,12 @@ void BlockView::endBusPointMove() {
}
void BlockView::pinHoverInOut(BlockItemPin * pin) {
//qDebug() << "pinHoverInOut" << pin << pin->state();
highlightNearPins(pin, QApplication::keyboardModifiers());
}
void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) {
trace(item->press_pos, to, &tmp_bus);
@@ -1577,8 +1695,7 @@ void BlockView::newBranchCancel() {
unmarkPins();
//qDebug() << "cancel";
new_branch = false;
tmp_bus.hide();
tmp_bus.clear();
hideTmpBuses();
}
@@ -1805,6 +1922,7 @@ void BlockView::removeSelected() {
void BlockView::removeAll() {
last_multiconnect_pl.clear();
QList<QGraphicsItem*> gi = scene_->items(), ai;
blockSignals(true);
foreach (QGraphicsItem * i, gi) {

View File

@@ -114,6 +114,7 @@ protected:
void mousePressEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent * event);
void keyPressEvent(QKeyEvent * event);
void keyReleaseEvent(QKeyEvent * e);
void resizeEvent(QResizeEvent * event);
void scrollContentsBy(int dx, int dy);
void drawBackground(QPainter * painter, const QRectF & rect);
@@ -127,7 +128,7 @@ protected:
void restoreBusesState();
void applySelRect(QGraphicsSceneMouseEvent * me);
void applyGridStep();
void trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus);
void trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary = true);
void clearBusStates();
void matchBus();
bool connectTmpToBus(BlockBusItem* bus);
@@ -138,6 +139,10 @@ protected:
void simplifyBuses();
void moveBuses(const QList<QGraphicsItem * > & items, QPointF dp);
QList<BlockBusItem * > internalBuses(const QList<BlockItem * > & items);
QList<BlockItemPin * > nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
BlockItemPin * getPin(const QList<QGraphicsItem * > & list) const;
void highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
void hideTmpBuses(bool clear = true);
double _thumb() const {return _talpha;}
QRectF _nav() const;
void animateNav(QRectF d);
@@ -158,7 +163,8 @@ protected:
QGraphicsItem * mm_ci;
QList<QGraphicsItem * > sel_items;
QList<BlockItem * > copy_items;
QList<BlockBusItem * > copy_buses;
QList<BlockItemPin * > last_multiconnect_pl;
QList<BlockBusItem * > copy_buses, tmp_buses;
BlockBusItem tmp_bus, * match_bus, * bus_from;
BlockItemPin * hpin;
BlockItem * ghost_;
@@ -196,6 +202,7 @@ protected slots:
void _navFinished();
void startBusPointMove(int bus_type);
void endBusPointMove();
void pinHoverInOut(BlockItemPin * pin);
public slots:
void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();}

View File

@@ -787,7 +787,7 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
// return;
// }
// can_fast = false;
vx = DBL_MIN;
vx = -DBL_MAX;
minY = minX = DBL_MAX;
maxY = maxX = -DBL_MAX;
foreach (const GraphicType & t, graphics) {