Implement IO point positioning and drawing
MODIFY
src/graphics/connection.cpp
src/graphics/connection.cpp
#include "connection.h"
+#include "shape.h"
-namespace Graphics {
+#include <QPainter>
-Connection::Connection(Shape* source, Shape* dest) : m_source(source), m_dest(dest)
-{
+namespace Graphics {
+static const float Pi = 3.1415926535;
+Connection::Connection(Shape *source, QPointF sourcePoint, Shape *dest,
+ QPointF destPoint) {
+ m_sourcePoint = mapFromItem(source, sourcePoint);
+ m_destPoint = mapFromItem(dest, destPoint);
}
QRectF Connection::boundingRect() const {
- return QRectF();
+ qreal penWidth = 1;
+ qreal extra = (penWidth + m_arrowSize) / 2.0;
+
+ return QRectF(m_sourcePoint, QSizeF(m_destPoint.x() - m_sourcePoint.x(),
+ m_destPoint.y() - m_sourcePoint.y()))
+ .normalized()
+ .adjusted(-extra, -extra, extra, extra);
}
-void Connection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
+void Connection::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget) {
+ QLineF line(m_sourcePoint, m_destPoint);
+
+ painter->setPen(
+ QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+ painter->drawLine(line);
+ // Draw destination arrow
+ double angle = ::acos(line.dx() / line.length());
+ QPointF destArrowP1 =
+ m_destPoint + QPointF(sin(angle - Pi / 3) * m_arrowSize,
+ cos(angle - Pi / 3) * m_arrowSize);
+ QPointF destArrowP2 =
+ m_destPoint + QPointF(sin(angle - Pi + Pi / 3) * m_arrowSize,
+ cos(angle - Pi + Pi / 3) * m_arrowSize);
+ painter->setBrush(Qt::black);
+ painter->drawPolygon(QPolygonF()
+ << m_destPoint << destArrowP1 << destArrowP2);
}
} // namespace Graphics

MODIFY
src/graphics/connection.h
src/graphics/connection.h
@@ -14,7 +14,8 @@ enum class ValueDrawPos { Source, Middle, Destination };
*/
class Connection : public QGraphicsItem {
public:
- Connection(Shape *source, Shape *dest);
+ Connection(Shape *source, QPointF sourcePoint, Shape *dest,
+ QPointF destPoint);
void setValueDrawPos(ValueDrawPos pos) { m_valuePos = pos, update(); }
void setValue(int value) { m_value = value; }
@@ -22,8 +23,6 @@ class Connection : public QGraphicsItem {
m_showValue = state;
update();
}
- Shape *getSource() const { return m_source; }
- Shape *getDest() const { return m_dest; }
protected:
QRectF boundingRect() const override;
@@ -31,9 +30,6 @@ class Connection : public QGraphicsItem {
QWidget *widget) override;
private:
- Shape *m_source;
- Shape *m_dest;
-
// A list of IO points, which all connect to this widget -
// used to form attachment points to this connection
QList<QPointF *> m_connectsToThis;
@@ -43,6 +39,7 @@ class Connection : public QGraphicsItem {
int m_value;
ValueDrawPos m_valuePos = ValueDrawPos::Source;
+ int m_arrowSize = 10;
QPointF m_sourcePoint;
QPointF m_destPoint;
};

MODIFY
src/graphics/pipelinewidget.cpp
src/graphics/pipelinewidget.cpp
#include "pipelinewidget.h"
+#include "connection.h"
#include "shape.h"
#include <QWheelEvent>
@@ -15,7 +16,7 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
// ------------ Create pipeline objects ---------------
// Instruction memory
Graphics::Shape* registers =
- new Graphics::Shape(Graphics::ShapeType::Block, 15, 15);
+ new Graphics::Shape(Graphics::ShapeType::Block, 10, 15);
registers->addInput(QStringList() << "Read\nregister 1"
<< "Read\nregister 2"
<< "Write\nregister"
@@ -34,24 +35,27 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
// Instruction memory
Graphics::Shape* instr_mem =
- new Graphics::Shape(Graphics::ShapeType::Block, 50, 5);
- instr_mem->addInput(QStringList() << "Address");
+ new Graphics::Shape(Graphics::ShapeType::Block, 30, 0);
+ instr_mem->addInput(QStringList() << "Read\naddress");
instr_mem->addOutput(QStringList() << "Instruction");
instr_mem->setName("Instruction\nmemory");
// PC
- Graphics::Shape* pc =
- new Graphics::Shape(Graphics::ShapeType::Block, 30, 3);
+ Graphics::Shape* pc = new Graphics::Shape(Graphics::ShapeType::Block, 30, 3);
+ pc->addInput("");
+ pc->addOutput("");
pc->setName("PC");
// MUX
- Graphics::Shape* mux1 =
- new Graphics::Shape(Graphics::ShapeType::MUX, 20, 8);
+ Graphics::Shape* mux1 = new Graphics::Shape(Graphics::ShapeType::MUX, 20, 8);
+ mux1->addInput(QStringList() << "0"
+ << "1"
+ << "2");
+ mux1->addOutput("C");
mux1->setName("M\nu\nx");
// ALU
- Graphics::Shape* ALU1 =
- new Graphics::Shape(Graphics::ShapeType::ALU, 70, 30);
+ Graphics::Shape* ALU1 = new Graphics::Shape(Graphics::ShapeType::ALU, 70, 30);
ALU1->setName("Add");
ALU1->addOutput("Sum");
@@ -65,11 +69,15 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
// Set item positions
pc->setPos(-250, -100);
- instr_mem->setPos(-200, 0);
+ instr_mem->setPos(-300, 0);
registers->setPos(0, 0);
data_mem->setPos(200, 0);
- mux1->setPos(0, -100);
- ALU1->setPos(100, 100);
+ mux1->setPos(0, -200);
+ ALU1->setPos(100, 200);
+
+ // Create connections
+ scene->addItem(new Graphics::Connection(
+ registers, registers->getOutputPoint(1), mux1, mux1->getInputPoint(0)));
}
void PipelineWidget::wheelEvent(QWheelEvent* event) {

MODIFY
src/graphics/shape.h
src/graphics/shape.h
@@ -23,6 +23,9 @@ class Shape : public QGraphicsItem {
void addOutput(QStringList output);
void setName(QString name);
+ QPointF getInputPoint(int index) const;
+ QPointF getOutputPoint(int index) const;
+
private:
void calculateRect();
QRectF m_rect;
@@ -56,7 +59,7 @@ class Shape : public QGraphicsItem {
qreal ioFontSize = 8;
qreal nodePadding = 5; // padding between each text descriptor for a node
qreal sidePadding =
- 3; // padding between an IO description and the side of the shape
+ 7; // padding between an IO description and the side of the shape
};
} // namespace Graphics

Implement IO point positioning and drawing