Skip to content

Commit aaf5582

Browse files
authored
Merge branch 'main' into parser
2 parents 1acd89f + f709562 commit aaf5582

File tree

2 files changed

+164
-18
lines changed

2 files changed

+164
-18
lines changed

parser_gui/Widgets/include/TreeVisualiser.h

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,61 @@
44
#include <QWidget>
55
#include <QVBoxLayout>
66
#include <QLabel>
7+
#include <QPainter>
78

89
#include "Node.h"
910

10-
using namespace Tiny::Data;
1111
namespace Tiny::Widgets {
12+
using namespace Tiny::Data;
1213
class TreeVisualiser : public QWidget {
1314
Q_OBJECT
15+
16+
protected:
17+
void paintEvent(QPaintEvent *event) override;
1418
public:
1519
TreeVisualiser(QWidget *parent = nullptr);
16-
void setRoot(Node* root);
20+
void drawTree(QPainter *painter, Node *node, int x, int y, int availableWidth, int currentLevel);
21+
22+
int calculateTreeWidth(Node* node) {
23+
if (!node || node->getChildren().empty()) return 50;
24+
25+
int totalWidth = 0;
26+
for (Node* child : node->getChildren()) {
27+
totalWidth += calculateTreeWidth(child);
28+
}
29+
return std::max(totalWidth, 50);
30+
}
31+
32+
void setRoot(Node *root) {
33+
this->root = root;
34+
}
35+
36+
void wheelEvent(QWheelEvent* event) override;
1737

38+
bool isOval(Node::NodeType type) {
39+
if ((type == Node::NodeType::Identifier) ||
40+
(type == Node::NodeType::Number) ||
41+
(type == Node::NodeType::Comparison)) {
42+
return true;
43+
} else {
44+
return false;
45+
}
46+
}
1847

48+
bool hasValue(Node::NodeType type) {
49+
if ((type == Node::NodeType::Identifier) ||
50+
(type == Node::NodeType::Number) ||
51+
(type == Node::NodeType::ReadStatement) ||
52+
(type == Node::NodeType::AssignStatement) ||
53+
(type == Node::NodeType::Comparison)) {
54+
return true;
55+
} else {
56+
return false;
57+
}
58+
}
59+
private:
60+
Node *root = nullptr;
61+
qreal zoomFactor = 1.0;
1962
}; // class TreeVisualiser
2063
} // namespace Tiny::Widgets
2164

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,131 @@
11
#include "TreeVisualiser.h"
2+
#include <QPainter>
3+
#include <QWheelEvent>
24

35
using Tiny::Widgets::TreeVisualiser;
46

7+
void TreeVisualiser::paintEvent(QPaintEvent *event) {
8+
Q_UNUSED(event);
9+
if (!root) return;
10+
11+
QPainter painter(this);
12+
painter.setRenderHint(QPainter::Antialiasing);
13+
14+
// Clear background
15+
painter.fillRect(rect(), QColor(240, 240, 240));
16+
painter.scale(zoomFactor, zoomFactor);
17+
18+
// Calculate the total width needed for the tree
19+
int treeWidth = calculateTreeWidth(root);
20+
21+
// Draw the entire tree
22+
drawTree(&painter, root, width() / 2, 50, treeWidth, root->getLevel());
23+
}
24+
525
TreeVisualiser::TreeVisualiser(QWidget *parent) : QWidget(parent) {
6-
// set the layout
7-
QVBoxLayout* layout = new QVBoxLayout(this);
8-
layout->setContentsMargins(0, 0, 0, 0);
9-
setLayout(layout);
26+
Node *nroot = new Node(Node::NodeType::Expression, "+");
27+
nroot->setLevel(1);
28+
Node *child1 = new Node(Node::NodeType::Number, "3");
29+
child1->setLevel(2);
30+
Node *child2 = new Node(Node::NodeType::Number, "4");
31+
child2->setLevel(1);
32+
Node *child3 = new Node(Node::NodeType::Number, "5");
33+
child3->setLevel(3);
34+
35+
Node *child4 = new Node(Node::NodeType::Number, "A7a");
36+
Node *child5 = new Node(Node::NodeType::Addition, "5555555");
37+
38+
this->root = nroot;
39+
this->root->addChild(child1);
40+
this->root->addChild(child2);
41+
child2->addChild(child3);
42+
child2->addChild(child4);
43+
child1->addChild(child5);
44+
}
45+
46+
void TreeVisualiser::drawTree(QPainter *painter, Node *node, int x, int y, int availableWidth, int level) {
47+
if (!node) return;
48+
49+
// Draw the current node
50+
painter->setPen(QPen(Qt::black, 2));
51+
painter->setBrush(QColor(70, 130, 180)); // Steel Blue
52+
53+
if (isOval(node->getType())) {
54+
painter->drawEllipse(x - 20, y - 20, 40, 40); // Node as an oval
55+
} else {
56+
painter->drawRect(x - 40, y - 20, 80, 40); // Node as a rectangle
57+
}
58+
59+
// Draw node value
60+
painter->setPen(Qt::white);
61+
QString nodeText;
62+
if (!hasValue(node->getType())) {
63+
nodeText = node->getNodeTypeString().toString() + "\n(" + node->getValue() + ")";
64+
} else {
65+
nodeText = node->getValue();
66+
}
67+
painter->drawText(QRect(x - 40, y - 20, 80, 40),
68+
Qt::AlignCenter | Qt::TextWordWrap, nodeText);
1069

11-
// set the style
12-
setStyleSheet("background-color: #2e2e2e ; color: #c0c0c0; border: 1px solid #2a2a2a;");
70+
if (node->getChildren().empty()) return;
1371

14-
// add the label
15-
QLabel* label = new QLabel("Tree Visualiser");
16-
label->setAlignment(Qt::AlignCenter);
17-
label->setStyleSheet("font-size: 20px; color: #c0c0c0;");
72+
// Calculate the total width and starting positions for children
73+
int childCount = node->getChildren().size();
74+
std::vector<int> childWidths;
75+
int totalChildWidth = 0;
1876

19-
// add the label to the layout
20-
layout->addWidget(label);
77+
// Calculate width for each child's subtree
78+
for (Node* child : node->getChildren()) {
79+
int childWidth = calculateTreeWidth(child);
80+
childWidths.push_back(childWidth);
81+
totalChildWidth += childWidth;
82+
}
83+
84+
// Vertical and horizontal spacing between nodes
85+
int verticalSpacing = 100;
86+
int horizontalSpacing = 100;
87+
88+
// Starting X position for the first child node
89+
int startX = x - totalChildWidth / 2;
90+
91+
// Draw children and their subtrees
92+
for (size_t i = 0; i < node->getChildren().size(); ++i) {
93+
Node* child = node->getChildren()[i];
94+
int childWidth = childWidths[i];
95+
96+
// Calculate position for each child
97+
int childX = startX + childWidth / 2;
98+
int childY = (child->getLevel() == node->getLevel())? y : y + verticalSpacing;
99+
100+
// Draw connection line to child node
101+
painter->setPen(QPen(Qt::black, 2));
102+
int yLineOffset = (child->getLevel() == node->getLevel())? 0 : 20;
103+
104+
painter->drawLine(x, y + yLineOffset, childX, childY);
105+
106+
// Recursively draw the child node
107+
drawTree(painter, child, childX, childY, childWidth, child->getLevel());
108+
109+
// Update the starting position for the next child
110+
startX += childWidth + horizontalSpacing;
111+
}
21112
}
22113

23-
void TreeVisualiser::setRoot(Node *root)
114+
void TreeVisualiser::wheelEvent(QWheelEvent *event)
24115
{
25-
qDebug() << "Drawing tree";
26-
// print the tree
27-
root->printTree();
116+
117+
const qreal zoomStep = 0.1; // Amount to zoom in/out
118+
const qreal minZoom = 0.5; // Minimum zoom level
119+
const qreal maxZoom = 3.0; // Maximum zoom level
120+
121+
if (event->angleDelta().y() > 0) {
122+
// Zoom in
123+
zoomFactor = qMin(maxZoom, zoomFactor + zoomStep);
124+
} else {
125+
// Zoom out
126+
zoomFactor = qMax(minZoom, zoomFactor - zoomStep);
127+
}
128+
129+
update(); // Redraw the widget
28130
}
131+

0 commit comments

Comments
 (0)