aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/coreview/connection.cpp
blob: 3355eed629e1d004b1f48bfcfdea5e991082b122 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "connection.h"
#include <cmath>

using namespace coreview;

Connector::Connector(enum Axis ax) {
    this->ax = ax;
}

void Connector::setPos(qreal x, qreal y) {
    qx = x;
    qy = y;
    emit updated(point());
    emit updated(vector());
}

enum Connector::Axis Connector::axis() const {
    return ax;
}

qreal Connector::x() const {
    return qx;
}

qreal Connector::y() const {
    return qy;
}

QPointF Connector::point() const {
    return QPointF(qx, qy);
}

QLineF Connector::vector() const {
    QPointF p = point();
    switch (ax) {
    case AX_X:
        return QLineF(p, p + QPointF(1, 0));
    case AX_Y:
        return QLineF(p, p + QPointF(0, 1));
    case AX_XY:
        return QLineF(p, p + QPointF(1, 1));
    case AX_MXY:
        return QLineF(p, p + QPoint(1, -1));
    }
}

Connection::Connection(const Connector *a, const Connector *b) : QGraphicsObject(nullptr) {
    pen_width = 1;

    ax_start = a->vector();
    ax_end = a->vector();

    connect(a, SIGNAL(updated(QLineF)), this, SLOT(moved_start(QLineF)));
    connect(b, SIGNAL(updated(QLineF)), this, SLOT(moved_end(QLineF)));
    moved_start(a->vector());
    moved_end(b->vector());
}

void Connection::setHasText(bool has) {
    if (has && value == nullptr) {
        value = new QGraphicsSimpleTextItem(this);
        value->setText(text);
    } else if (!has && value != nullptr) {
        delete value;
    }
}

void Connection::setText(QString val) {
    text = val;
    if (value != nullptr)
        value->setText(val);
}

void Connection::setAxes(QVector<QLineF> axes) {
    break_axes = axes;
    recalc_line();
}

void Connection::moved_start(QLineF p) {
    ax_start = p;
    recalc_line();
}

void Connection::moved_end(QLineF p) {
    ax_end = p;
    recalc_line();
}

QRectF Connection::boundingRect() const {
    QRectF rect;
    for (int i = 0; i < (points.size() - 1); i++) {
        qreal x = points[i].x() > points[i+1].x() ? points[i].x() : points[i+1].x();
        qreal y = points[i].y() > points[i+1].y() ? points[i].y() : points[i+1].y();
        rect |= QRectF(x - pen_width/2.0, y - pen_width/2.0, fabs(points[i].x() - points[i+1].x()) + pen_width, fabs(points[i].y() - points[i+1].y()) + pen_width);
    }
    return rect;
}

void Connection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) {
    QPen pen;
    pen.setWidth(pen_width);
    pen.setColor(color);
    pen.setCapStyle(Qt::FlatCap);
    pen.setJoinStyle(Qt::BevelJoin);
    painter->setPen(pen);

    painter->drawPolyline(QPolygonF(points));
}

void Connection::recalc_line() {
    points.clear();

    points.append(ax_start.p1());

    QLineF cur_l = ax_start;
    for (int i = 0; i < break_axes.size(); i++) {
        if (recalc_line_add_point(cur_l, break_axes[i]))
            cur_l = break_axes[i];
    }
    recalc_line_add_point(cur_l, ax_end);

    points.append(ax_end.p1());
}

bool Connection::recalc_line_add_point(const QLineF &l1, const QLineF &l2) {
    QPointF intersec;
    if (l1.intersect(l2, &intersec) == QLineF::NoIntersection)
        return false;
    points.append(intersec);
    return true;
}

Bus::Bus(const Connector *start, const Connector *end, unsigned width) : Connection(start, end) {
    pen_width = width;
}

const Connector *Bus::new_connector(qreal x, qreal y, enum Connector::Axis axis) {
    Connector *c = new Connector(axis);
    conns.append({
        .c = c,
        .p = QPoint(x, y)
     });
    // TODO update positions
    return c;
}

const Connector *Bus::new_connector(const QPointF &p, enum Connector::Axis axis) {
    return new_connector(p.x(), p.y(), axis);
}

Signal::Signal(const Connector *start, const Connector *end) : Connection(start, end) {
    color = QColor(0, 0, 255);
}