From 6ed6360bfde189191bd976d8969c2834b33ec64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 17 Jan 2018 21:35:51 +0100 Subject: Add logicblock and Control Unit to scheme --- qtmips_gui/coreview/logicblock.cpp | 99 ++++++++++++++++++++++++++++++++++++++ qtmips_gui/coreview/logicblock.h | 44 +++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 qtmips_gui/coreview/logicblock.cpp create mode 100644 qtmips_gui/coreview/logicblock.h (limited to 'qtmips_gui/coreview') diff --git a/qtmips_gui/coreview/logicblock.cpp b/qtmips_gui/coreview/logicblock.cpp new file mode 100644 index 0000000..6b5769a --- /dev/null +++ b/qtmips_gui/coreview/logicblock.cpp @@ -0,0 +1,99 @@ +#include "logicblock.h" +#include + +using namespace coreview; + +////////////////////// +#define GAP 3 +#define RADIUS GAP +#define LINE_OFFSET 1 +#define PENW 1 +////////////////////// + +LogicBlock::LogicBlock(QString name) { + LogicBlock({name}); +} + +LogicBlock::LogicBlock(QVector name) : QGraphicsItem(nullptr) { + QFont font; + font.setPointSize(7); + + qreal h = 0, w = 0; + for (int i = 0; i < name.size(); i++) { + QGraphicsSimpleTextItem *t = new QGraphicsSimpleTextItem(name[i], this); + t->setFont(font); + text.append(t); + QRectF t_box = t->boundingRect(); + t->setPos(-t_box.width()/2, h + LINE_OFFSET); + h += t_box.height() + LINE_OFFSET; + if (w < t_box.width()) + w = t_box.width(); + } + + box = QRectF(-w/2 - GAP, -GAP, w + (2*GAP), h + (2*GAP)); +} + +LogicBlock::~LogicBlock() { + for (int i = 0; i < connectors.size(); i++) + delete connectors[i].con; + for (int i = 0; i < text.size(); i++) + delete text[i]; +} + +QRectF LogicBlock::boundingRect() const { + return QRectF(box.x() - PENW/2, box.y() - PENW/2, box.width() + PENW, box.height() + PENW); +} + +void LogicBlock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) { + painter->drawRoundedRect(box, RADIUS, RADIUS); +} + +void LogicBlock::setPos(qreal x, qreal y) { + QGraphicsItem::setPos(x, y); + for (int i = 0; i < connectors.size(); i++) { + struct Con &c = connectors[i]; + c.con->setPos(x + c.p.x(), y + c.p.y()); + } +} + +void LogicBlock::setSize(qreal width, qreal height) { + box.setX(-width/2 - GAP); + box.setWidth(width + (2*GAP)); + box.setHeight(height + (2*GAP)); + for (int i = 0; i < connectors.size(); i++) { // Update point for all connectors + struct Con &c = connectors[i]; + c.p = con_pos(c.x, c.y); + } + setPos(x(), y()); +} + +static qreal sign(qreal v) { + // This intentionally doesn't return 0 on v == 0 + return (0 <= v) - (0 > v); +} + +const Connector *LogicBlock::new_connector(qreal x, qreal y) { + // stick to closest edge + if (fabs(x) > fabs(y)) + x = sign(x); + else + y = sign(y); + + // Note: we are using here that 0 and M_PI is same angle but different orientation (but we ignore orientation for now) + Connector *c = new Connector(fabs(x) > fabs(y) ? 0 : M_PI_2); + connectors.append({ + .con = c, + .x = x, + .y = y, + .p = con_pos(x, y) + }); + setPos(this->x(), this->y()); // Update connector position + return c; +} + +QPointF LogicBlock::con_pos(qreal x, qreal y) { + qreal px, py; + px = (box.right() - GAP) * x + (GAP * sign(x)); + py = (box.bottom()/2 - GAP) * (y + 1) + (GAP * sign(y)); + return QPointF(px, py); +} diff --git a/qtmips_gui/coreview/logicblock.h b/qtmips_gui/coreview/logicblock.h new file mode 100644 index 0000000..4c1310c --- /dev/null +++ b/qtmips_gui/coreview/logicblock.h @@ -0,0 +1,44 @@ +#ifndef LOGICBLOCK_H +#define LOGICBLOCK_H + +#include +#include +#include +#include +#include "connection.h" + +namespace coreview { + +class LogicBlock : public QGraphicsItem { +public: + LogicBlock(QString name); + LogicBlock(QVector name); + ~LogicBlock(); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setPos(qreal x, qreal y); + void setSize(qreal width, qreal height); + + // This creates new connector + // Position is determined by x and y in 0 to 1 range and is mapped to real size of this block + // Using x=y and x=-y coordinates is not supported + const Connector *new_connector(qreal x, qreal y); + +private: + QVector text; + QRectF box; + + struct Con { + Connector *con; + qreal x, y; + QPointF p; + }; + QVector connectors; + QPointF con_pos(qreal x, qreal y); +}; + +} + +#endif // LOGICBLOCK_H -- cgit v1.2.3