Skip to content

Commit e63124c

Browse files
committed
Updated Links to be bezier curves + Added break link option when right click on it + Improved undo commands
1 parent ff43545 commit e63124c

16 files changed

+262
-42
lines changed

NodalScene.cpp

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ void NodalScene::save(QString fileName, const AudioSettings& settings)
100100
file.close();
101101
}
102102

103+
void CheckCommand(const QUndoCommand* _command, int _depth = 0)
104+
{
105+
qDebug() << "[DEBUG]" + QString(" ").repeated(_depth) + " - Command:" << _command->text();
106+
for(int i = 0; i < _command->childCount(); ++i)
107+
{
108+
CheckCommand(_command->child(i), _depth + 1);
109+
}
110+
}
111+
103112
void NodalScene::load(QString fileName, AudioSettings& settings)
104113
{
105114
QFile file(fileName);
@@ -135,15 +144,62 @@ void NodalScene::load(QString fileName, AudioSettings& settings)
135144
settings.setDuration(root[DURATION].toDouble());
136145
}
137146

138-
reset();
139147

140148
// ============== CREATE COMPONENTS =============
141149
if(!Utils::CheckJsonValue(root, COMPONENTS, QJsonValue::Array, 120))
142150
return;
143151
QJsonArray componentArray = root[COMPONENTS].toArray();
144152

153+
qDebug() << "[DEBUG] Check UndoStack";
154+
for(int i = 0; i < m_undoStack->count(); ++i)
155+
{
156+
CheckCommand(m_undoStack->command(i));
157+
}
158+
159+
qDebug() << "[DEBUG] Clear UndoStack";
160+
m_undoStack->clear();
161+
162+
qDebug() << "[DEBUG] Check UndoStack";
163+
for(int i = 0; i < m_undoStack->count(); ++i)
164+
{
165+
CheckCommand(m_undoStack->command(i));
166+
}
167+
168+
qDebug() << "[DEBUG] Reset";
169+
reset();
170+
171+
qDebug() << "[DEBUG] Check UndoStack";
172+
for(int i = 0; i < m_undoStack->count(); ++i)
173+
{
174+
CheckCommand(m_undoStack->command(i));
175+
}
176+
177+
qDebug() << "[DEBUG] Clear UndoStack";
178+
m_undoStack->clear();
179+
180+
qDebug() << "[DEBUG] Check UndoStack";
181+
for(int i = 0; i < m_undoStack->count(); ++i)
182+
{
183+
CheckCommand(m_undoStack->command(i));
184+
}
185+
186+
qDebug() << "[DEBUG] Create Conponents";
145187
NodeItem::JsonToNodeArray(componentArray, this, QPointF(), m_undoStack);
188+
189+
qDebug() << "[DEBUG] Check UndoStack";
190+
for(int i = 0; i < m_undoStack->count(); ++i)
191+
{
192+
CheckCommand(m_undoStack->command(i));
193+
}
194+
195+
qDebug() << "[DEBUG] Clear UndoStack";
146196
m_undoStack->clear();
197+
198+
qDebug() << "[DEBUG] Check UndoStack";
199+
for(int i = 0; i < m_undoStack->count(); ++i)
200+
{
201+
CheckCommand(m_undoStack->command(i));
202+
}
147203
}
148204

149205
int NodalScene::clearItems(int from)
@@ -152,8 +208,12 @@ int NodalScene::clearItems(int from)
152208
for(int i = m_nodeList.size()-1; i >= from; --i)
153209
{
154210
m_nodeList[i]->unlink();
211+
m_undoStack->push(new DeleteComponentCommand(this, m_nodeList[i], m_nodeList[i]->pos()));
212+
213+
/*m_nodeList[i]->unlink();
214+
removeItem(m_nodeList[i]);
155215
delete m_nodeList[i];
156-
m_nodeList.remove(i);
216+
m_nodeList.remove(i);*/
157217
nbRemoved++;
158218
}
159219

UI/LinkItem.cpp

Lines changed: 84 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "LinkItem.h"
2222
#include "NodalView.h"
2323
#include "PinItem.h"
24+
#include "NodeItem.h"
25+
#include "PinOutputItem.h"
2426
#include <QtMath>
2527

2628
QVector<LinkItem*> LinkItem::s_linkList;
@@ -35,16 +37,18 @@ LinkItem::LinkItem(QGraphicsItem *parent)
3537

3638
m_mousePos = QPointF(0, 0);
3739

38-
setZValue(10000);
40+
setZValue(-10000);
3941

40-
s_linkList.append(this);
42+
qDebug() << "Create LinkItem";
4143
}
4244

4345
LinkItem::~LinkItem()
4446
{
45-
int index = s_linkList.indexOf(this);
46-
Q_ASSERT(index >= 0);
47-
s_linkList.removeAt(index);
47+
qDebug() << "Destroy LinkItem";
48+
if (isRegistered(this))
49+
{
50+
unregisterLink(this);
51+
}
4852
}
4953

5054
void LinkItem::setMousePos(QPointF mousePos)
@@ -64,6 +68,36 @@ void LinkItem::prepareChange()
6468
prepareGeometryChange();
6569
}
6670

71+
void LinkItem::check()
72+
{
73+
qDebug() << "Check Link Item";
74+
Q_ASSERT(scene() == nullptr);
75+
Q_ASSERT(m_pinA == nullptr && m_pinB == nullptr);
76+
}
77+
78+
void LinkItem::registerLink(LinkItem*_link)
79+
{
80+
Q_ASSERT(_link != nullptr);
81+
if(!isRegistered(_link))
82+
{
83+
s_linkList.append(_link);
84+
}
85+
}
86+
87+
void LinkItem::unregisterLink(LinkItem*_link)
88+
{
89+
Q_ASSERT(_link != nullptr);
90+
int index = s_linkList.indexOf(_link);
91+
Q_ASSERT(index >= 0);
92+
s_linkList.removeAt(index);
93+
}
94+
95+
bool LinkItem::isRegistered(LinkItem *_link)
96+
{
97+
Q_ASSERT(_link != nullptr);
98+
return s_linkList.indexOf(_link) >= 0;
99+
}
100+
67101
LinkItem *LinkItem::getLinkBetween(PinItem *_pinA, PinItem *_pinB)
68102
{
69103
LinkItem* link = nullptr;
@@ -77,6 +111,19 @@ LinkItem *LinkItem::getLinkBetween(PinItem *_pinA, PinItem *_pinB)
77111
return link;
78112
}
79113

114+
QList<LinkItem*> LinkItem::getLinksWithPin(PinItem* _pin)
115+
{
116+
QList<LinkItem*> links;
117+
for(int i = 0; i < s_linkList.size(); ++i)
118+
{
119+
if(s_linkList[i]->m_pinA == _pin || s_linkList[i]->m_pinB == _pin)
120+
{
121+
links.append(s_linkList[i]);
122+
}
123+
}
124+
return links;
125+
}
126+
80127
PinItem *LinkItem::getPinThatIsNot(PinItem *pin)
81128
{
82129
PinItem* toReturn = nullptr;
@@ -97,15 +144,18 @@ void LinkItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
97144
Q_UNUSED(option);
98145
Q_UNUSED(widget);
99146

100-
QPen pen(QColor(200, 200, 200));
101-
pen.setWidth(1);
102-
pen.setCosmetic(true);
147+
if(m_pinA != nullptr || m_pinB != nullptr)
148+
{
149+
bool isCompSelected = (m_pinA != nullptr && m_pinA->parentNode()->isSelected())
150+
|| (m_pinB != nullptr && m_pinB->parentNode()->isSelected());
103151

104-
QPointF firstPoint = (m_pinA != nullptr) ? m_pinA->scenePos() : m_mousePos;
105-
QPointF secondPoint = (m_pinB != nullptr) ? m_pinB->scenePos() : m_mousePos;
152+
QPen pen(QColor(200, 200, 200));
153+
pen.setWidth(isCompSelected ? 3 : 1);
154+
pen.setCosmetic(true);
106155

107-
painter->setPen(pen);
108-
painter->drawLine(firstPoint, secondPoint);
156+
painter->setPen(pen);
157+
painter->drawPath(getLinePath());
158+
}
109159
}
110160

111161
QRectF LinkItem::boundingRect() const
@@ -124,21 +174,32 @@ QRectF LinkItem::boundingRect() const
124174

125175
QPainterPath LinkItem::shape() const
126176
{
127-
qreal width = 1.;
128-
qreal pinRadius = 10.;
177+
qreal width = 10.;
178+
QPainterPathStroker pathStroker;
179+
pathStroker.setWidth(width);
180+
return pathStroker.createStroke(getLinePath());
181+
}
182+
183+
QPainterPath LinkItem::getLinePath() const
184+
{
129185
QPointF firstPoint = (m_pinA != nullptr) ? m_pinA->scenePos() : m_mousePos;
130186
QPointF secondPoint = (m_pinB != nullptr) ? m_pinB->scenePos() : m_mousePos;
131187

132-
QPointF delta = secondPoint - firstPoint;
133-
qreal length = qSqrt(delta.x() * delta.x() + delta.y() * delta.y());
134-
QPointF dir = delta / length;
135-
QPointF ortho(-dir.y(), dir.x());
188+
qreal firstPointSign = 1.0;
189+
if(m_pinA != nullptr)
190+
{
191+
firstPointSign = qgraphicsitem_cast<PinOutputItem*>(m_pinA) != nullptr ? 1.0 : -1.0 ;
192+
}
193+
qreal secondPointSign = -firstPointSign;
194+
195+
qreal minDist = 200.0;
196+
qreal alpha = 0.6;
197+
qreal dist = qMax(abs(firstPoint.x() - secondPoint.x()), minDist);
198+
QPointF ctrlPoint1(firstPoint.x() + firstPointSign * dist * alpha, firstPoint.y());
199+
QPointF ctrlPoint2(secondPoint.x() + secondPointSign * dist * alpha, secondPoint.y());
136200

137201
QPainterPath path;
138-
path.moveTo(firstPoint + dir * pinRadius + ortho * width);
139-
path.lineTo(secondPoint - dir * pinRadius + ortho * width);
140-
path.lineTo(secondPoint - dir * pinRadius - ortho * width);
141-
path.lineTo(firstPoint + dir * pinRadius - ortho * width);
142-
path.closeSubpath();
202+
path.moveTo(firstPoint);
203+
path.cubicTo(ctrlPoint1, ctrlPoint2, secondPoint);
143204
return path;
144205
}

UI/LinkItem.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class LinkItem : public QGraphicsItem
3434
int type() const override { return Type; }
3535

3636
LinkItem(QGraphicsItem *parent = nullptr);
37-
~LinkItem();
37+
virtual ~LinkItem() override;
3838

3939
void setPenStyle(Qt::PenStyle penStyle) { m_penStyle = penStyle; }
4040
void setPenSize(int size) { m_size = size; }
@@ -51,14 +51,22 @@ class LinkItem : public QGraphicsItem
5151

5252
void prepareChange();
5353

54-
static LinkItem *getLinkBetween(PinItem* _pinA, PinItem* _pinB);
54+
void check();
55+
56+
static void registerLink(LinkItem* _link);
57+
static void unregisterLink(LinkItem* _link);
58+
static bool isRegistered(LinkItem* _link);
59+
static LinkItem* getLinkBetween(PinItem* _pinA, PinItem* _pinB);
60+
static QList<LinkItem*> getLinksWithPin(PinItem* _pin);
5561

5662
protected:
5763
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget* widget) override;
5864
virtual QRectF boundingRect() const override;
5965
virtual QPainterPath shape() const override;
6066

6167
private:
68+
QPainterPath getLinePath() const;
69+
6270
int m_size;
6371
Qt::PenStyle m_penStyle;
6472
PinItem* m_pinA;

UI/NodalView.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ void NodalView::showCustomContextMenu(const QPoint& _pos)
345345
// for QAbstractScrollArea and derived classes you would use:
346346
// QPoint globalPos = myWidget->viewport()->mapToGlobal(pos);
347347

348-
QAction act_breakLink("Break link(s)");
348+
QAction act_breakAllLinks("Break all link(s)");
349+
QAction act_breakLink("Break link");
349350
QAction act_removeComponents("Remove Component(s)");
350351

351352
QMenu myMenu;
@@ -361,12 +362,11 @@ void NodalView::showCustomContextMenu(const QPoint& _pos)
361362
LinkItem* link = dynamic_cast<LinkItem*>(item);
362363
if(link != nullptr)
363364
{
364-
//myMenu.addAction(&act_breakLink);
365-
qDebug() << "Link !";
365+
myMenu.addAction(&act_breakLink);
366366
}
367367
else if(pin != nullptr && pin->isLinked())
368368
{
369-
myMenu.addAction(&act_breakLink);
369+
myMenu.addAction(&act_breakAllLinks);
370370
}
371371
if(scene()->selectedItems().size() > 0)
372372
{
@@ -379,11 +379,15 @@ void NodalView::showCustomContextMenu(const QPoint& _pos)
379379

380380
QAction* selectedAction = myMenu.exec(globalPos);
381381
if (selectedAction == &act_breakLink)
382+
{
383+
link->firstPin()->unlink(link->secondPin());
384+
}
385+
if (selectedAction == &act_breakAllLinks)
382386
{
383387
qDebug() << "break links";
384388
pin->unlinkAll();
385389
}
386-
else if(selectedAction == &act_removeComponents)
390+
else if (selectedAction == &act_removeComponents)
387391
{
388392
// something was chosen, do stuff
389393
getScene()->deleteSelection();

0 commit comments

Comments
 (0)