-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphics_items.cpp
More file actions
127 lines (107 loc) · 4.3 KB
/
Copy pathgraphics_items.cpp
File metadata and controls
127 lines (107 loc) · 4.3 KB
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
#include "graphics_items.h"
#include "mainwindow.h"
#include <QFont>
#include <QGraphicsScene>
#include <algorithm>
GraphNode::GraphNode(int id, double radius, MainWindow* window, QGraphicsItem* parent)
: QGraphicsEllipseItem(-radius / 2.0, -radius / 2.0, radius, radius, parent),
nodeId(id), mainWindow(window)
{
setPen(QPen(Qt::black, 2));
setBrush(Qt::white);
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
setAcceptHoverEvents(true);
textItem = new QGraphicsSimpleTextItem(QString::number(id), this);
updateNodeSize(radius);
}
void GraphNode::updateNodeSize(double newRadius) {
setRect(-newRadius / 2.0, -newRadius / 2.0, newRadius, newRadius);
int fontSize = qMax(10, static_cast<int>(newRadius * 0.45));
QFont nodeFont("Arial", fontSize, QFont::Bold);
textItem->setFont(nodeFont);
centerText();
}
void GraphNode::centerText() {
if (!textItem) return;
QRectF textBounds = textItem->boundingRect();
textItem->setPos(-textBounds.width() / 2.0, -textBounds.height() / 2.0);
}
void GraphNode::addEdge(GraphEdge* edge) {
edgeList.append(edge);
}
void GraphNode::setCustomSelected(bool selected) {
isCustomSelected = selected;
updateAppearance();
}
void GraphNode::setNodeInPath(bool inPath) {
isPartOfPath = inPath;
updateAppearance();
}
void GraphNode::updateAppearance(bool isHovered) {
// Приоритет у выделения и пути — они красятся в оранжевый
if (isCustomSelected || isPartOfPath) {
setBrush(QBrush(QColor(255, 167, 38))); // Приятный жёлто-оранжевый
} else if (isHovered) {
setBrush(QBrush(QColor(230, 230, 230))); // Мягкий серый при наведении
} else {
setBrush(QBrush(Qt::white)); // Базовый белый
}
}
void GraphNode::hoverEnterEvent(QGraphicsSceneHoverEvent* event) {
updateAppearance(true);
QGraphicsEllipseItem::hoverEnterEvent(event);
}
void GraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) {
updateAppearance(false);
QGraphicsEllipseItem::hoverLeaveEvent(event);
}
void GraphNode::mousePressEvent(QGraphicsSceneMouseEvent* event) {
if (mainWindow && mainWindow->getSelectionMode()) {
mainWindow->handleNodeClick(this);
}
QGraphicsEllipseItem::mousePressEvent(event); // Чтобы перетаскивание продолжало работать
}
QVariant GraphNode::itemChange(GraphicsItemChange change, const QVariant& value) {
if (change == ItemPositionChange && scene()) {
QPointF newPos = value.toPointF();
QRectF rect = scene()->sceneRect();
double r = rect.width() > 0 ? boundingRect().width() / 2.0 : 0;
newPos.setX(std::clamp(newPos.x(), rect.left() + r, rect.right() - r));
newPos.setY(std::clamp(newPos.y(), rect.top() + r, rect.bottom() - r));
return newPos;
}
if (change == ItemPositionHasChanged) {
if (scene() && scene()->sceneRect().width() > 0) {
normPos.setX(pos().x() / scene()->sceneRect().width());
normPos.setY(pos().y() / scene()->sceneRect().height());
}
for (GraphEdge* edge : edgeList) {
edge->adjust();
}
// ДИНАМИЧЕСКИЙ ПЕРЕРАСЧЁТ: Если путь уже горит, перестраиваем его при движении мышью!
if (mainWindow && mainWindow->hasActivePath()) {
mainWindow->calculateDijkstra(false); // false — не спамить QMessageBox при перетаскивании
}
}
return QGraphicsEllipseItem::itemChange(change, value);
}
// ================= GraphEdge =================
GraphEdge::GraphEdge(GraphNode* source, GraphNode* dest, QGraphicsItem* parent)
: QGraphicsLineItem(parent), sourceNode(source), destNode(dest)
{
setPen(QPen(Qt::darkGray, 2));
setZValue(-1.0);
adjust();
}
void GraphEdge::adjust() {
if (!sourceNode || !destNode) return;
setLine(QLineF(sourceNode->scenePos(), destNode->scenePos()));
}
void GraphEdge::setHighlighted(bool highlighted) {
if (highlighted) {
setPen(QPen(QColor(255, 167, 38), 4)); // Жирное оранжевое ребро для пути
} else {
setPen(QPen(Qt::darkGray, 2));
}
}