удалено: build/.qt/QtDeploySupport.cmake
удалено: build/.qt/QtDeployTargets.cmake удалено: build/CMakeCache.txt удалено: build/CMakeFiles/4.1.2/CMakeCXXCompiler.cmake удалено: build/CMakeFiles/4.1.2/CMakeDetermineCompilerABI_CXX.bin удалено: build/CMakeFiles/4.1.2/CMakeSystem.cmake удалено: build/CMakeFiles/4.1.2/CompilerIdCXX/CMakeCXXCompilerId.cpp удалено: build/CMakeFiles/4.1.2/CompilerIdCXX/a.out удалено: build/CMakeFiles/CMakeConfigureLog.yaml удалено: build/CMakeFiles/CMakeDirectoryInformation.cmake удалено: build/CMakeFiles/CMakeRuleHashes.txt удалено: build/CMakeFiles/InstallScripts.json удалено: build/CMakeFiles/Makefile.cmake удалено: build/CMakeFiles/Makefile2 удалено: build/CMakeFiles/TargetDirectories.txt удалено: build/CMakeFiles/cmake.check_cache удалено: build/CMakeFiles/idef0_editor.dir/DependInfo.cmake удалено: build/CMakeFiles/idef0_editor.dir/build.make удалено: build/CMakeFiles/idef0_editor.dir/cmake_clean.cmake удалено: build/CMakeFiles/idef0_editor.dir/compiler_depend.internal удалено: build/CMakeFiles/idef0_editor.dir/compiler_depend.make удалено: build/CMakeFiles/idef0_editor.dir/compiler_depend.ts удалено: build/CMakeFiles/idef0_editor.dir/depend.make удалено: build/CMakeFiles/idef0_editor.dir/flags.make удалено: build/CMakeFiles/idef0_editor.dir/idef0_editor_autogen/mocs_compilation.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/idef0_editor_autogen/mocs_compilation.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/link.d удалено: build/CMakeFiles/idef0_editor.dir/link.txt удалено: build/CMakeFiles/idef0_editor.dir/progress.make удалено: build/CMakeFiles/idef0_editor.dir/src/MainWindow.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/MainWindow.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/src/items/ArrowItem.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/items/ArrowItem.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/src/items/BlockItem.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/items/BlockItem.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/src/items/DiagramScene.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/items/DiagramScene.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/src/items/JunctionItem.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/items/JunctionItem.cpp.o.d удалено: build/CMakeFiles/idef0_editor.dir/src/main.cpp.o удалено: build/CMakeFiles/idef0_editor.dir/src/main.cpp.o.d удалено: build/CMakeFiles/idef0_editor_autogen.dir/AutogenInfo.json удалено: build/CMakeFiles/idef0_editor_autogen.dir/AutogenUsed.txt удалено: build/CMakeFiles/idef0_editor_autogen.dir/DependInfo.cmake удалено: build/CMakeFiles/idef0_editor_autogen.dir/ParseCache.txt удалено: build/CMakeFiles/idef0_editor_autogen.dir/build.make удалено: build/CMakeFiles/idef0_editor_autogen.dir/cmake_clean.cmake удалено: build/CMakeFiles/idef0_editor_autogen.dir/compiler_depend.internal удалено: build/CMakeFiles/idef0_editor_autogen.dir/compiler_depend.make удалено: build/CMakeFiles/idef0_editor_autogen.dir/compiler_depend.ts удалено: build/CMakeFiles/idef0_editor_autogen.dir/progress.make удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/DependInfo.cmake удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/build.make удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/cmake_clean.cmake удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/compiler_depend.make удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/compiler_depend.ts удалено: build/CMakeFiles/idef0_editor_autogen_timestamp_deps.dir/progress.make удалено: build/CMakeFiles/progress.marks удалено: build/Makefile удалено: build/cmake_install.cmake удалено: build/idef0_editor удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_BlockItem.cpp удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_BlockItem.cpp.d удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_DiagramScene.cpp удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_DiagramScene.cpp.d удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_JunctionItem.cpp удалено: build/idef0_editor_autogen/DWIBBXP2LJ/moc_JunctionItem.cpp.d удалено: build/idef0_editor_autogen/UVLADIE3JM/moc_MainWindow.cpp удалено: build/idef0_editor_autogen/UVLADIE3JM/moc_MainWindow.cpp.d удалено: build/idef0_editor_autogen/deps удалено: build/idef0_editor_autogen/moc_predefs.h удалено: build/idef0_editor_autogen/mocs_compilation.cpp удалено: build/idef0_editor_autogen/timestamp удалено: codex изменено: src/items/ArrowItem.cpp изменено: src/items/ArrowItem.h изменено: src/items/BlockItem.h изменено: src/items/DiagramScene.cpp изменено: src/items/DiagramScene.h
This commit is contained in:
parent
53afa3f728
commit
abdbae5a11
79 changed files with 218 additions and 46399 deletions
|
|
@ -66,6 +66,47 @@ void ArrowItem::setLabelOffset(const QPointF& off) {
|
|||
updateLabelItem(m_lastPolyline.isEmpty() ? computePolyline() : m_lastPolyline);
|
||||
}
|
||||
|
||||
bool ArrowItem::adjustEndpoint(Endpoint& ep, const QPointF& delta) {
|
||||
if (ep.block) {
|
||||
auto seg = ep.block->portSegment(ep.port);
|
||||
QPointF local = ep.localPos.value_or(ep.block->portLocalPos(ep.port));
|
||||
local += ep.block->mapFromScene(delta);
|
||||
if (qFuzzyCompare(seg.first.x(), seg.second.x())) {
|
||||
local.setX(seg.first.x());
|
||||
local.setY(std::clamp(local.y(), seg.first.y(), seg.second.y()));
|
||||
} else {
|
||||
local.setY(seg.first.y());
|
||||
local.setX(std::clamp(local.x(), seg.first.x(), seg.second.x()));
|
||||
}
|
||||
ep.localPos = local;
|
||||
return true;
|
||||
}
|
||||
if (ep.scenePos) {
|
||||
QPointF p = *ep.scenePos + delta;
|
||||
if (scene()) {
|
||||
const QRectF r = scene()->sceneRect();
|
||||
// snap to nearest edge it was originally on
|
||||
const qreal tol = 4.0;
|
||||
if (std::abs(ep.scenePos->x() - r.left()) < tol) {
|
||||
p.setX(r.left());
|
||||
p.setY(std::clamp(p.y(), r.top(), r.bottom()));
|
||||
} else if (std::abs(ep.scenePos->x() - r.right()) < tol) {
|
||||
p.setX(r.right());
|
||||
p.setY(std::clamp(p.y(), r.top(), r.bottom()));
|
||||
} else if (std::abs(ep.scenePos->y() - r.top()) < tol) {
|
||||
p.setY(r.top());
|
||||
p.setX(std::clamp(p.x(), r.left(), r.right()));
|
||||
} else if (std::abs(ep.scenePos->y() - r.bottom()) < tol) {
|
||||
p.setY(r.bottom());
|
||||
p.setX(std::clamp(p.x(), r.left(), r.right()));
|
||||
}
|
||||
}
|
||||
ep.scenePos = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ArrowItem::setFrom(const Endpoint& ep) {
|
||||
if (m_from.block) m_from.block->removeArrow(this);
|
||||
if (m_from.junction) m_from.junction->removeArrow(this);
|
||||
|
|
@ -394,6 +435,13 @@ QVector<QPointF> ArrowItem::computePolyline() const {
|
|||
: QPointF(0, ((a - b).y() >= 0 ? 1 : -1)),
|
||||
QPointF(-1,0))
|
||||
: portDirection(m_to, false, QPointF(-1,0), scene());
|
||||
// ensure right border always behaves like an input (approach from left)
|
||||
if (!m_hasTempEnd && m_to.scenePos && scene()) {
|
||||
const qreal rightX = scene()->sceneRect().right();
|
||||
if (almostEqual(m_to.scenePos->x(), rightX)) {
|
||||
dirB = QPointF(-1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
auto expandRect = [](const QRectF& r, qreal m) {
|
||||
return QRectF(r.x()-m, r.y()-m, r.width()+2*m, r.height()+2*m);
|
||||
|
|
@ -594,6 +642,22 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent* e) {
|
|||
const QVector<QPointF> pts = computePolyline();
|
||||
const QPointF pos = e->scenePos();
|
||||
|
||||
// Проверим, не жмем ли по началу/концу для сдвига точки соединения.
|
||||
if (!pts.isEmpty()) {
|
||||
if (QLineF(pos, pts.first()).length() <= tol) {
|
||||
m_dragPart = DragPart::FromEnd;
|
||||
m_lastDragScenePos = pos;
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
if (QLineF(pos, pts.last()).length() <= tol) {
|
||||
m_dragPart = DragPart::ToEnd;
|
||||
m_lastDragScenePos = pos;
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_dragPart = DragPart::None;
|
||||
int closestIdx = -1;
|
||||
qreal best = tol;
|
||||
|
|
@ -637,6 +701,25 @@ void ArrowItem::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_dragPart == DragPart::FromEnd) {
|
||||
const QPointF delta = e->scenePos() - m_lastDragScenePos;
|
||||
m_lastDragScenePos = e->scenePos();
|
||||
if (adjustEndpoint(m_from, delta)) {
|
||||
updatePath();
|
||||
}
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
if (m_dragPart == DragPart::ToEnd) {
|
||||
const QPointF delta = e->scenePos() - m_lastDragScenePos;
|
||||
m_lastDragScenePos = e->scenePos();
|
||||
if (adjustEndpoint(m_to, delta)) {
|
||||
updatePath();
|
||||
}
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dragPart == DragPart::None) {
|
||||
QGraphicsPathItem::mouseMoveEvent(e);
|
||||
return;
|
||||
|
|
@ -673,6 +756,15 @@ void ArrowItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
|
|||
e->accept();
|
||||
return;
|
||||
}
|
||||
if ((m_dragPart == DragPart::FromEnd || m_dragPart == DragPart::ToEnd) && e->button() == Qt::LeftButton) {
|
||||
m_dragPart = DragPart::None;
|
||||
unsetCursor();
|
||||
if (auto* ds = qobject_cast<DiagramScene*>(scene())) {
|
||||
ds->requestSnapshot();
|
||||
}
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
if (m_dragPart != DragPart::None && e->button() == Qt::LeftButton) {
|
||||
m_dragPart = DragPart::None;
|
||||
unsetCursor();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
std::optional<QPointF> hitTest(const QPointF& scenePos, qreal radius) const;
|
||||
|
||||
private:
|
||||
enum class DragPart { None, BendX, TopHorizontal, BottomHorizontal };
|
||||
enum class DragPart { None, BendX, TopHorizontal, BottomHorizontal, FromEnd, ToEnd };
|
||||
|
||||
Endpoint m_from;
|
||||
Endpoint m_to;
|
||||
|
|
@ -77,4 +77,5 @@ protected:
|
|||
void mouseMoveEvent(QGraphicsSceneMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent* e) override;
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* e) override;
|
||||
bool adjustEndpoint(Endpoint& ep, const QPointF& delta);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ public:
|
|||
void setId(int id) { m_id = id; }
|
||||
|
||||
QPointF portScenePos(Port p) const;
|
||||
QPair<QPointF, QPointF> portSegment(Port p) const;
|
||||
bool hitTestPort(const QPointF& scenePos, Port* outPort, QPointF* outLocalPos = nullptr, qreal radiusPx = 10.0) const;
|
||||
QPointF portLocalPos(Port p) const;
|
||||
|
||||
void addArrow(ArrowItem* a);
|
||||
void removeArrow(ArrowItem* a);
|
||||
|
|
@ -39,7 +41,4 @@ private:
|
|||
QRectF m_rect; // local rect
|
||||
int m_id;
|
||||
QSet<ArrowItem*> m_arrows;
|
||||
|
||||
QPointF portLocalPos(Port p) const;
|
||||
QPair<QPointF, QPointF> portSegment(Port p) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,11 +19,7 @@ DiagramScene::DiagramScene(QObject* parent)
|
|||
const qreal w = 1122;
|
||||
const qreal h = 793;
|
||||
setSceneRect(-w * 0.5, -h * 0.5, w, h);
|
||||
auto* frame = addRect(sceneRect(), QPen(QColor(80, 80, 80), 1.5, Qt::DashLine), Qt::NoBrush);
|
||||
frame->setZValue(-5);
|
||||
frame->setEnabled(false);
|
||||
frame->setAcceptedMouseButtons(Qt::NoButton);
|
||||
frame->setData(0, QVariant(QStringLiteral("static-frame")));
|
||||
ensureFrame();
|
||||
pushSnapshot();
|
||||
}
|
||||
|
||||
|
|
@ -362,16 +358,8 @@ DiagramScene::Snapshot DiagramScene::captureSnapshot() const {
|
|||
void DiagramScene::restoreSnapshot(const Snapshot& snap) {
|
||||
m_restoringSnapshot = true;
|
||||
cancelCurrentDrag();
|
||||
// Clear dynamic items but keep the static frame.
|
||||
QList<QGraphicsItem*> toRemove;
|
||||
for (QGraphicsItem* it : items()) {
|
||||
if (it->data(0).toString() == QStringLiteral("static-frame")) continue;
|
||||
toRemove.append(it);
|
||||
}
|
||||
for (QGraphicsItem* it : toRemove) {
|
||||
removeItem(it);
|
||||
delete it;
|
||||
}
|
||||
clear();
|
||||
ensureFrame();
|
||||
|
||||
m_nextBlockId = 1;
|
||||
m_nextJunctionId = 1;
|
||||
|
|
@ -425,6 +413,7 @@ void DiagramScene::restoreSnapshot(const Snapshot& snap) {
|
|||
}
|
||||
|
||||
m_restoringSnapshot = false;
|
||||
resetHistory(captureSnapshot());
|
||||
}
|
||||
|
||||
void DiagramScene::pushSnapshot() {
|
||||
|
|
@ -452,7 +441,52 @@ void DiagramScene::undo() {
|
|||
restoreSnapshot(m_history[m_historyIndex]);
|
||||
}
|
||||
|
||||
bool DiagramScene::goDownIntoSelected() {
|
||||
const auto sel = selectedItems();
|
||||
if (sel.size() != 1) return false;
|
||||
auto* b = qgraphicsitem_cast<BlockItem*>(sel.first());
|
||||
if (!b) return false;
|
||||
|
||||
return goDownIntoBlock(b);
|
||||
}
|
||||
|
||||
bool DiagramScene::goUp() {
|
||||
if (m_hierarchy.isEmpty()) return false;
|
||||
Snapshot child = captureSnapshot();
|
||||
m_children[m_currentBlockId] = child;
|
||||
const HierNode parent = m_hierarchy.takeLast();
|
||||
m_currentBlockId = parent.blockId;
|
||||
restoreSnapshot(parent.snapshot);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DiagramScene::goDownIntoBlock(BlockItem* b) {
|
||||
if (!b) return false;
|
||||
Snapshot current = captureSnapshot();
|
||||
m_hierarchy.push_back({m_currentBlockId, current});
|
||||
m_currentBlockId = b->id();
|
||||
Snapshot child = m_children.value(m_currentBlockId, Snapshot{});
|
||||
restoreSnapshot(child);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent* e) {
|
||||
if (e->button() == Qt::MiddleButton) {
|
||||
const auto itemsUnder = items(e->scenePos());
|
||||
for (QGraphicsItem* it : itemsUnder) {
|
||||
if (auto* b = qgraphicsitem_cast<BlockItem*>(it)) {
|
||||
if (goDownIntoBlock(b)) {
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (goUp()) {
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (tryBranchAtArrow(e->scenePos())) {
|
||||
|
|
@ -526,6 +560,18 @@ void DiagramScene::keyPressEvent(QKeyEvent* e) {
|
|||
e->accept();
|
||||
return;
|
||||
}
|
||||
if ((e->key() == Qt::Key_Down || e->key() == Qt::Key_PageDown) && e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (goDownIntoSelected()) {
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((e->key() == Qt::Key_Up || e->key() == Qt::Key_PageUp) && e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (goUp()) {
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QGraphicsScene::keyPressEvent(e);
|
||||
}
|
||||
|
||||
|
|
@ -567,18 +613,20 @@ void DiagramScene::deleteSelection() {
|
|||
}
|
||||
}
|
||||
|
||||
// delete arrows first to avoid dangling removal from deleted blocks/junctions
|
||||
QVector<ArrowItem*> arrowsToDelete;
|
||||
QVector<QGraphicsItem*> othersToDelete;
|
||||
for (QGraphicsItem* it : toDelete) {
|
||||
if (qgraphicsitem_cast<ArrowItem*>(it)) {
|
||||
removeItem(it);
|
||||
delete it;
|
||||
if (it->type() == ArrowItem::Type) {
|
||||
if (auto* a = static_cast<ArrowItem*>(it)) arrowsToDelete.push_back(a);
|
||||
} else {
|
||||
othersToDelete.push_back(it);
|
||||
}
|
||||
}
|
||||
for (QGraphicsItem* it : toDelete) {
|
||||
if (!qgraphicsitem_cast<ArrowItem*>(it)) {
|
||||
removeItem(it);
|
||||
delete it;
|
||||
}
|
||||
for (ArrowItem* a : arrowsToDelete) {
|
||||
delete a;
|
||||
}
|
||||
for (QGraphicsItem* it : othersToDelete) {
|
||||
delete it;
|
||||
}
|
||||
|
||||
if (!toDelete.isEmpty()) pushSnapshot();
|
||||
|
|
@ -602,3 +650,26 @@ void DiagramScene::maybeSnapshotMovedItems() {
|
|||
m_pressPositions.clear();
|
||||
if (moved) pushSnapshot();
|
||||
}
|
||||
|
||||
void DiagramScene::resetHistory(const Snapshot& base) {
|
||||
m_history.clear();
|
||||
m_history.push_back(base);
|
||||
m_historyIndex = 0;
|
||||
}
|
||||
|
||||
void DiagramScene::ensureFrame() {
|
||||
bool exists = false;
|
||||
for (QGraphicsItem* it : items()) {
|
||||
if (it->data(0).toString() == QStringLiteral("static-frame")) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists) {
|
||||
auto* frame = addRect(sceneRect(), QPen(QColor(80, 80, 80), 1.5, Qt::DashLine), Qt::NoBrush);
|
||||
frame->setZValue(-5);
|
||||
frame->setEnabled(false);
|
||||
frame->setAcceptedMouseButtons(Qt::NoButton);
|
||||
frame->setData(0, QVariant(QStringLiteral("static-frame")));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ public:
|
|||
BlockItem* createBlockAt(const QPointF& scenePos);
|
||||
BlockItem* createBlockWithId(const QPointF& scenePos, int id, const QString& title);
|
||||
void requestSnapshot();
|
||||
bool goDownIntoSelected();
|
||||
bool goDownIntoBlock(BlockItem* b);
|
||||
bool goUp();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* e) override;
|
||||
|
|
@ -22,23 +25,6 @@ protected:
|
|||
void keyPressEvent(QKeyEvent* e) override;
|
||||
|
||||
private:
|
||||
ArrowItem* m_dragArrow = nullptr;
|
||||
QPointer<BlockItem> m_dragFromBlock;
|
||||
QPointer<JunctionItem> m_dragFromJunction;
|
||||
BlockItem::Port m_dragFromPort = BlockItem::Port::Output;
|
||||
int m_nextBlockId = 1;
|
||||
int m_nextJunctionId = 1;
|
||||
bool m_snapshotScheduled = false;
|
||||
bool m_restoringSnapshot = false;
|
||||
bool m_itemDragActive = false;
|
||||
QHash<QGraphicsItem*, QPointF> m_pressPositions;
|
||||
|
||||
bool tryStartArrowDrag(const QPointF& scenePos);
|
||||
bool tryFinishArrowDrag(const QPointF& scenePos);
|
||||
bool tryBranchAtArrow(const QPointF& scenePos);
|
||||
void cancelCurrentDrag();
|
||||
void deleteSelection();
|
||||
|
||||
struct Snapshot {
|
||||
struct Endpoint {
|
||||
enum class Kind { None, Block, Junction, Scene } kind = Kind::None;
|
||||
|
|
@ -63,6 +49,28 @@ private:
|
|||
QVector<Arrow> arrows;
|
||||
};
|
||||
|
||||
struct HierNode { int blockId; Snapshot snapshot; };
|
||||
|
||||
ArrowItem* m_dragArrow = nullptr;
|
||||
QPointer<BlockItem> m_dragFromBlock;
|
||||
QPointer<JunctionItem> m_dragFromJunction;
|
||||
BlockItem::Port m_dragFromPort = BlockItem::Port::Output;
|
||||
int m_nextBlockId = 1;
|
||||
int m_nextJunctionId = 1;
|
||||
bool m_snapshotScheduled = false;
|
||||
bool m_restoringSnapshot = false;
|
||||
bool m_itemDragActive = false;
|
||||
QHash<QGraphicsItem*, QPointF> m_pressPositions;
|
||||
int m_currentBlockId = -1;
|
||||
QVector<HierNode> m_hierarchy;
|
||||
QHash<int, Snapshot> m_children; // blockId -> saved child diagram
|
||||
|
||||
bool tryStartArrowDrag(const QPointF& scenePos);
|
||||
bool tryFinishArrowDrag(const QPointF& scenePos);
|
||||
bool tryBranchAtArrow(const QPointF& scenePos);
|
||||
void cancelCurrentDrag();
|
||||
void deleteSelection();
|
||||
|
||||
QVector<Snapshot> m_history;
|
||||
int m_historyIndex = -1;
|
||||
|
||||
|
|
@ -72,6 +80,8 @@ private:
|
|||
void scheduleSnapshot();
|
||||
void undo();
|
||||
void maybeSnapshotMovedItems();
|
||||
void resetHistory(const Snapshot& base);
|
||||
void ensureFrame();
|
||||
|
||||
enum class Edge { None, Left, Right, Top, Bottom };
|
||||
Edge hitTestEdge(const QPointF& scenePos, QPointF* outScenePoint = nullptr) const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue