Fri, 28 Feb 2020 19:24:33 +0200
omg functional programming
47 | 1 | #include <QMouseEvent> |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
2 | #include <QPainter> |
47 | 3 | #include "canvas.h" |
4 | ||
5 | Canvas::Canvas( | |
6 | Model* model, | |
7 | DocumentManager* documents, | |
8 | const ldraw::ColorTable& colorTable, | |
9 | QWidget* parent) : | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
10 | PartRenderer{model, documents, colorTable, parent}, |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
11 | gridProgram{this} |
47 | 12 | { |
13 | this->setMouseTracking(true); | |
14 | } | |
15 | ||
51 | 16 | void Canvas::handleSelectionChange(const QSet<ldraw::Id>& selectedIds, const QSet<ldraw::Id>& deselectedIds) |
17 | { | |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
18 | Q_ASSERT(not selectedIds.contains(ldraw::NULL_ID)); |
51 | 19 | this->selection.subtract(deselectedIds); |
20 | this->selection.unite(selectedIds); | |
21 | this->compiler->setSelectedObjects(this->selection); | |
22 | this->update(); | |
23 | } | |
24 | ||
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
25 | QString vectorToString(const glm::vec3& vec) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
26 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
27 | return "(%1, %2, %3)"_q |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
28 | .arg(toDouble(vec.x)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
29 | .arg(toDouble(vec.y)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
30 | .arg(toDouble(vec.z)); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
31 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
32 | |
47 | 33 | void Canvas::mouseMoveEvent(QMouseEvent* event) |
34 | { | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
35 | const ldraw::Id id = this->pick(event->pos()); |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
36 | this->highlighted = id; |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
37 | this->totalMouseMove += (event->pos() - this->lastMousePosition).manhattanLength(); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
38 | this->worldPosition = this->screenToModelCoordinates(event->pos(), geom::XY); |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
39 | if (this->worldPosition.has_value()) |
55 | 40 | { |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
41 | this->worldPosition = glm::round(*this->worldPosition); |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
42 | } |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
43 | if (this->worldPosition.has_value()) |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
44 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
45 | this->newStatusText("Position: (%1, %2, %3)"_q |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
46 | .arg(toDouble(this->worldPosition->x)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
47 | .arg(toDouble(this->worldPosition->y)) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
48 | .arg(toDouble(this->worldPosition->z))); |
55 | 49 | } |
50 | else | |
51 | { | |
52 | this->newStatusText("Position: <none>"_q); | |
53 | } | |
47 | 54 | PartRenderer::mouseMoveEvent(event); |
55 | } | |
51 | 56 | |
57 | void Canvas::mousePressEvent(QMouseEvent* event) | |
58 | { | |
59 | this->totalMouseMove = 0; | |
60 | this->lastMousePosition = event->pos(); | |
61 | PartRenderer::mousePressEvent(event); | |
62 | } | |
63 | ||
64 | void Canvas::mouseReleaseEvent(QMouseEvent* event) | |
65 | { | |
66 | if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) | |
67 | { | |
52
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
68 | if (this->highlighted == ldraw::NULL_ID) |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
69 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
70 | this->selection = {}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
71 | } |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
72 | else |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
73 | { |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
74 | this->selection = {this->highlighted}; |
eee644f88e93
avoid having the null id in the selection
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
75 | } |
51 | 76 | this->compiler->setSelectedObjects(this->selection); |
77 | emit selectionChanged(this->selection); | |
78 | this->update(); | |
79 | } | |
80 | PartRenderer::mouseReleaseEvent(event); | |
81 | } | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
82 | |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
83 | void Canvas::initializeGL() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
84 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
85 | // We first create the grid program and connect everything and only then call the part renderer's initialization |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
86 | // functions so that when initialization sets up, the signals also set up the matrices on our side. |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
87 | this->gridProgram.emplace(this); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
88 | this->gridProgram->initialize(); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
89 | connect(this, &PartRenderer::projectionMatrixChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
90 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
91 | this->gridProgram->setProjectionMatrix(this->projectionMatrix); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
92 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
93 | connect(this, &PartRenderer::modelMatrixChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
94 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
95 | this->gridProgram->setModelMatrix(this->modelMatrix); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
96 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
97 | connect(this, &PartRenderer::viewMatrixChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
98 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
99 | this->gridProgram->setViewMatrix(this->viewMatrix); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
100 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
101 | connect(this, &PartRenderer::renderPreferencesChanged, [&]() |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
102 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
103 | if (this->gridProgram.has_value()) |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
104 | { |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
105 | const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
106 | this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
107 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
108 | }); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
109 | PartRenderer::initializeGL(); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
110 | } |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
111 | |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
112 | void Canvas::paintGL() |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
113 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
114 | PartRenderer::paintGL(); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
115 | glEnable(GL_BLEND); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
116 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
117 | this->gridProgram->draw(); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
118 | glDisable(GL_BLEND); |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
119 | if (this->worldPosition.has_value()) |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
120 | { |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
121 | QPainter painter{this}; |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
122 | painter.setRenderHint(QPainter::Antialiasing); |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
123 | painter.setPen(Qt::black); |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
124 | painter.setBrush(Qt::green); |
61
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
125 | const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
126 | painter.drawEllipse(pos, 5, 5); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
127 | painter.setPen(Qt::white); |
4585d8d7a7ec
moved GridProgram to Canvas
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
128 | painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); |
57
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
129 | } |
5c0005f63319
use glm::unProject to implement screenToModelCoordinates
Teemu Piippo <teemu@hecknology.net>
parents:
56
diff
changeset
|
130 | } |