aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/coreview
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-12-15 22:45:28 +0100
committerKarel Kočí <cynerd@email.cz>2017-12-15 22:45:28 +0100
commite6ca4b4568e311b47239bfe83de15ed9e91c57b9 (patch)
tree3da2f72faf360058bae02c35b0c724233bd64d61 /qtmips_gui/coreview
parentbbea996112eb7ac81ec50d2af08f4bd681d0e50d (diff)
downloadqtmips-e6ca4b4568e311b47239bfe83de15ed9e91c57b9.tar.gz
qtmips-e6ca4b4568e311b47239bfe83de15ed9e91c57b9.tar.bz2
qtmips-e6ca4b4568e311b47239bfe83de15ed9e91c57b9.zip
Implement few initial graphic elements
Diffstat (limited to 'qtmips_gui/coreview')
-rw-r--r--qtmips_gui/coreview/connection.cpp79
-rw-r--r--qtmips_gui/coreview/connection.h60
-rw-r--r--qtmips_gui/coreview/latch.cpp51
-rw-r--r--qtmips_gui/coreview/latch.h45
-rw-r--r--qtmips_gui/coreview/multiplexer.cpp79
-rw-r--r--qtmips_gui/coreview/multiplexer.h41
-rw-r--r--qtmips_gui/coreview/programcounter.cpp48
-rw-r--r--qtmips_gui/coreview/programcounter.h42
8 files changed, 445 insertions, 0 deletions
diff --git a/qtmips_gui/coreview/connection.cpp b/qtmips_gui/coreview/connection.cpp
new file mode 100644
index 0000000..ebca519
--- /dev/null
+++ b/qtmips_gui/coreview/connection.cpp
@@ -0,0 +1,79 @@
+#include "connection.h"
+
+using namespace coreview;
+
+void Connector::setPos(qreal x, qreal y) {
+ qx = x;
+ qy = y;
+ emit updated();
+}
+
+qreal Connector::x() const {
+ return qx;
+}
+
+qreal Connector::y() const {
+ return qy;
+}
+
+QPointF Connector::point() const {
+ return QPointF(qx, qy);
+}
+
+Connection::Connection(const Connector *a, const Connector *b) : QGraphicsObject(nullptr) {
+ connect(a, SIGNAL(updated()), this, SLOT(moved()));
+ connect(b, SIGNAL(updated()), this, SLOT(moved()));
+ this->a = a;
+ this->b = b;
+ update_pos();
+}
+
+void Connection::setHasText(bool has) {
+ if (has && value == nullptr) {
+ value = new QGraphicsSimpleTextItem(this);
+ value->setText(text);
+ } else if (!has && value != nullptr) {
+ delete value;
+ }
+ update_pos();
+}
+
+void Connection::setText(QString val) {
+ text = val;
+ if (value != nullptr)
+ value->setText(val);
+}
+
+void Connection::moved() {
+ update_pos();
+}
+
+QRectF Connection::boundingRect() const {
+ QRectF rect;
+ for (int i = 0; i < (points.size() - 1); i++) {
+ qreal x = points[i].x();
+ if (x > points[i+1].x())
+ x = points[i+1].x();
+ qreal y = points[i].y();
+ if (y > points[i+1].y())
+ y = points[i+1].y();
+ // TODO pen width
+ rect.united(QRectF(x - 0.5, y - 0.5, fabs(points[i].x() - points[i+1].x()) + 1, fabs(points[i].y() - points[i+1].y()) + 1));
+ }
+ //return rect;
+ return QRectF(0, 0, 300, 300);
+}
+
+void Connection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ for (int i = 0; i < (points.size() - 1); i++)
+ painter->drawLine(points[i], points[i+1]);
+ // TODO meaby use QPath instead?
+}
+
+void Connection::update_pos() {
+ points.clear();
+ points.append(a->point());
+ points.append(b->point());
+ // TODO more than one line
+ // TODO update position of value
+}
diff --git a/qtmips_gui/coreview/connection.h b/qtmips_gui/coreview/connection.h
new file mode 100644
index 0000000..eda6afe
--- /dev/null
+++ b/qtmips_gui/coreview/connection.h
@@ -0,0 +1,60 @@
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include <QGraphicsObject>
+#include <QList>
+#include <cmath>
+#include "../coreview.h"
+
+namespace coreview {
+
+class Connector : public QObject {
+ Q_OBJECT
+public:
+ void setPos(qreal x, qreal y);
+ qreal x() const;
+ qreal y() const;
+ QPointF point() const;
+
+signals:
+ void updated();
+
+private:
+ qreal qx, qy;
+};
+
+class Connection : public QGraphicsObject {
+ Q_OBJECT
+public:
+ Connection(const Connector *a, const Connector *b);
+
+ void setHasText(bool has);
+ void setText(QString val);
+
+private slots:
+ void moved();
+
+private:
+ QGraphicsSimpleTextItem *value;
+ QList<QPointF> points;
+ const Connector *a, *b;
+ QString text;
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ // TODO line width and possibly bus width
+
+ void update_pos();
+};
+
+}
+
+#else
+
+namespace coreview {
+ class Connector;
+ class Connection;
+};
+
+#endif // CONNECTION_H
diff --git a/qtmips_gui/coreview/latch.cpp b/qtmips_gui/coreview/latch.cpp
new file mode 100644
index 0000000..77bb317
--- /dev/null
+++ b/qtmips_gui/coreview/latch.cpp
@@ -0,0 +1,51 @@
+#include "latch.h"
+
+using namespace coreview;
+
+//////////////////////
+#define WIDTH 10
+#define PENW 1
+//////////////////////
+
+Latch::Latch(QtMipsMachine *machine, qreal height) {
+ this->height = height;
+ connect(machine, SIGNAL(tick()), this, SLOT(tick()));
+}
+
+QRectF Latch::boundingRect() const {
+ return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, height + PENW);
+}
+
+void Latch::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ painter->drawRect(0, 0, WIDTH, height);
+ // Now tick rectangle
+ const QPointF tickPolygon[] = {
+ QPointF(0, 0),
+ QPointF(WIDTH/2, WIDTH/2),
+ QPointF(WIDTH, 0)
+ };
+ painter->drawPolygon(tickPolygon, 3);
+}
+
+void Latch::setPos(qreal x, qreal y) {
+ QGraphicsObject::setPos(x, y);
+ for (unsigned i = 0; i < connectors.size(); i++) {
+ connectors[i].in->setPos(x, y + connectors_off[i]);
+ connectors[i].out->setPos(x + WIDTH, y + connectors_off[i]);
+ }
+}
+
+struct Latch::ConnectorPair Latch::new_connector(qreal cy) {
+ SANITY_ASSERT(cy < height, "Latch: Trying to create connector outside of latch height");
+ ConnectorPair cp;
+ cp.in = new Connector();
+ cp.out = new Connector();
+ connectors.append(cp);
+ connectors_off.append(cy);
+ setPos(x(), y()); // Update connectors position
+ return cp;
+}
+
+void Latch::tick() {
+ // TODO animate
+}
diff --git a/qtmips_gui/coreview/latch.h b/qtmips_gui/coreview/latch.h
new file mode 100644
index 0000000..a8738b3
--- /dev/null
+++ b/qtmips_gui/coreview/latch.h
@@ -0,0 +1,45 @@
+#ifndef LATCH_H
+#define LATCH_H
+
+#include <QGraphicsObject>
+#include <QList>
+#include "qtmipsexception.h"
+#include "qtmipsmachine.h"
+#include "../coreview.h"
+#include "connection.h"
+
+namespace coreview {
+
+class Latch : public QGraphicsObject {
+ Q_OBJECT
+public:
+ Latch(QtMipsMachine *machine, qreal height);
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ void setPos(qreal x, qreal y);
+
+ struct ConnectorPair { Connector *in, *out; };
+
+ struct ConnectorPair new_connector(qreal y); // Create new connectors pair that is given y from top of latch
+
+private slots:
+ void tick();
+
+private:
+ qreal height;
+ QList<ConnectorPair> connectors;
+ QList<qreal> connectors_off;
+
+};
+
+}
+
+#else
+
+namespace coreview {
+ class Latch;
+};
+
+#endif // LATCH_H
diff --git a/qtmips_gui/coreview/multiplexer.cpp b/qtmips_gui/coreview/multiplexer.cpp
new file mode 100644
index 0000000..57fa443
--- /dev/null
+++ b/qtmips_gui/coreview/multiplexer.cpp
@@ -0,0 +1,79 @@
+#include "multiplexer.h"
+
+using namespace coreview;
+
+//////////////////////
+#define WIDTH 20
+#define HEIGHT 20
+#define PENW 1
+//////////////////////
+
+Multiplexer::Multiplexer(unsigned size) {
+ this->size = size;
+ seton = 0;
+ ctlfrom = false;
+ con_ctl = new Connector();
+ con_out = new Connector();
+ con_in = new Connector*[size];
+ for (unsigned i = 0; i < size; i++)
+ con_in[i] = new Connector();
+ setPos(x(), y()); // Set connectors possitions
+}
+
+Multiplexer::~Multiplexer() {
+ delete con_ctl;
+ delete con_out;
+ for (unsigned i = 0; i < size; i++)
+ delete con_in[i];
+ delete con_in;
+}
+
+QRectF Multiplexer::boundingRect() const {
+ return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, (HEIGHT * size) + PENW);
+}
+
+void Multiplexer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ // Draw pointing line first so it isn't over the border lines
+ painter->setPen(QColor(200, 200, 200));
+ painter->drawLine(0, (HEIGHT / 2) + (seton * HEIGHT), WIDTH, (HEIGHT * size) / 2);
+
+ painter->setPen(QColor());
+ painter->drawLine(0, 0, 0, (HEIGHT * size)); // (|)
+ painter->drawLine(0, 0, WIDTH, WIDTH); // (\)
+ painter->drawLine(0, (HEIGHT * size), WIDTH, (HEIGHT * size) - WIDTH); // (/)
+ painter->drawLine(WIDTH, WIDTH, WIDTH, (HEIGHT * size) - WIDTH); // (|)
+}
+
+void Multiplexer::setPos(qreal x, qreal y) {
+ QGraphicsItem::setPos(x, y);
+ if (ctlfrom)
+ con_ctl->setPos(x + (WIDTH / 2), y + (WIDTH / 2));
+ else
+ con_ctl->setPos(x + (WIDTH / 2), y + (HEIGHT * size) - (WIDTH / 2));
+ con_out->setPos(x + WIDTH, y + ((HEIGHT *size) / 2));
+ for (unsigned i = 0; i < size; i++)
+ con_in[i]->setPos(x, y + (HEIGHT / 2) + (i * HEIGHT));
+}
+
+const Connector *Multiplexer::connector_ctl() const {
+ return con_ctl;
+}
+
+const Connector *Multiplexer::connector_out() const {
+ return con_out;
+}
+
+const Connector *Multiplexer::connector_in(unsigned i) const {
+ SANITY_ASSERT(i < size, "Multiplexer: requested out of range input connector");
+ return con_in[i];
+}
+
+void Multiplexer::set(unsigned i) {
+ seton = i;
+ update(boundingRect());
+}
+
+void Multiplexer::setCtl(bool up) {
+ ctlfrom = up;
+ setPos(x(), y()); // Update connectors
+}
diff --git a/qtmips_gui/coreview/multiplexer.h b/qtmips_gui/coreview/multiplexer.h
new file mode 100644
index 0000000..6aa11a6
--- /dev/null
+++ b/qtmips_gui/coreview/multiplexer.h
@@ -0,0 +1,41 @@
+#ifndef MULTIPLEXER_H
+#define MULTIPLEXER_H
+
+#include <QGraphicsItem>
+#include "qtmipsexception.h"
+#include "../coreview.h"
+#include "connection.h"
+
+namespace coreview {
+
+class Multiplexer : public QGraphicsItem {
+public:
+ Multiplexer(unsigned size);
+ ~Multiplexer();
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ void setPos(qreal x, qreal y);
+ const Connector *connector_ctl() const; // Control input
+ const Connector *connector_out() const; // Output
+ const Connector *connector_in(unsigned i) const; // Inputs
+
+ void set(unsigned i); // Set what value should be set as connected
+ void setCtl(bool up); // Set if control signal is from up or down (in default down)
+
+private:
+ bool ctlfrom;
+ unsigned size, seton;
+ Connector *con_ctl, *con_out, **con_in;
+};
+
+}
+
+#else
+
+namespace coreview {
+ class Multiplexer;
+}
+
+#endif // MULTIPLEXER_H
diff --git a/qtmips_gui/coreview/programcounter.cpp b/qtmips_gui/coreview/programcounter.cpp
new file mode 100644
index 0000000..32c907c
--- /dev/null
+++ b/qtmips_gui/coreview/programcounter.cpp
@@ -0,0 +1,48 @@
+#include "programcounter.h"
+
+using namespace coreview;
+
+//////////////////////
+#define WIDTH 80
+#define HEIGHT 100
+#define PENW 1
+//////////////////////
+
+ProgramCounter::ProgramCounter(QtMipsMachine *machine) : QGraphicsObject(nullptr), value(this), name(this) {
+ value.setText(QString("0x") + QString::number(machine->registers()->read_pc(), 16));
+ value.setPos(0, HEIGHT/2 - value.boundingRect().height()/2);
+ name.setText(QString("PC"));
+ name.setPos(WIDTH/2 - name.boundingRect().width()/2, 0);
+
+ connect(machine->registers(), SIGNAL(pc_update(std::uint32_t)), this, SLOT(pc_update(std::uint32_t)));
+
+ con_in = new Connector();
+ con_out = new Connector();
+ setPos(x(), y()); // To set initial connectors positions
+}
+
+QRectF ProgramCounter::boundingRect() const {
+ return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, HEIGHT + PENW);
+}
+
+void ProgramCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ painter->drawRect(0, 0, WIDTH, HEIGHT);
+}
+
+void ProgramCounter::setPos(qreal x, qreal y) {
+ QGraphicsObject::setPos(x, y);
+ con_in->setPos(x, y + HEIGHT/2);
+ con_out->setPos(x + WIDTH, y + HEIGHT/2);
+}
+
+const Connector *ProgramCounter::connector_in() const {
+ return con_in;
+}
+
+const Connector *ProgramCounter::connector_out() const {
+ return con_out;
+}
+
+void ProgramCounter::pc_update(std::uint32_t val) {
+ value.setText(QString("0x") + QString::number(val, 16));
+}
diff --git a/qtmips_gui/coreview/programcounter.h b/qtmips_gui/coreview/programcounter.h
new file mode 100644
index 0000000..98b161d
--- /dev/null
+++ b/qtmips_gui/coreview/programcounter.h
@@ -0,0 +1,42 @@
+#ifndef PROGRAMCOUNTER_H
+#define PROGRAMCOUNTER_H
+
+#include <QGraphicsObject>
+#include <QPainter>
+#include "qtmipsmachine.h"
+#include "../coreview.h"
+#include "connection.h"
+
+namespace coreview {
+
+class ProgramCounter : public QGraphicsObject {
+ Q_OBJECT
+public:
+ ProgramCounter(QtMipsMachine *machine);
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ void setPos(qreal x, qreal y);
+ const Connector *connector_in() const;
+ const Connector *connector_out() const;
+
+private slots:
+ void pc_update(std::uint32_t val);
+
+private:
+ QGraphicsSimpleTextItem value;
+ QGraphicsSimpleTextItem name;
+
+ Connector *con_in, *con_out;
+};
+
+}
+
+#else
+
+namespace coreview {
+ class ProgramCounter;
+};
+
+#endif // PROGRAMCOUNTER_H