-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathchartindicator.cpp
127 lines (103 loc) · 3.64 KB
/
chartindicator.cpp
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
/* -*- coding: utf-8-unix -*-
*
* chartindicator.cpp
*
* Copyright (C) 2022 Jukka Sirkka
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "chartindicator.h"
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
#include <QDebug>
#include "chartdisplay.h"
#include "chartmanager.h"
#include "geomutils.h"
ChartIndicator::ChartIndicator(QQuickItem* parent)
: QQuickItem(parent)
, m_doupdate(false)
{
setFlag(ItemHasContents, true);
connect(ChartManager::instance(), &ChartManager::chartIndicatorsChanged, this, &ChartIndicator::reset);
}
void ChartIndicator::sync() {
if (m_positions.isEmpty()) return;
auto encdis = qobject_cast<const ChartDisplay*>(parentItem());
if (encdis == nullptr) {
qWarning() << "Expected ChartDisplay parent, cannot sync";
return;
}
for (int i = 0; i < m_positions.size(); ++i) {
encdis->syncPositions(m_positions[i], m_vertices[i]);
}
m_doupdate = true;
update();
}
void ChartIndicator::reset(const WGS84Polygon& indicators) {
m_positions = indicators;
auto encdis = qobject_cast<const ChartDisplay*>(parentItem());
if (encdis == nullptr) {
qWarning() << "Expected ChartDisplay parent, cannot sync";
return;
}
m_vertices.resize(m_positions.size());
for (int i = 0; i < m_positions.size(); ++i) {
m_vertices[i].resize(m_positions[i].size());
encdis->syncPositions(m_positions[i], m_vertices[i]);
}
m_doupdate = true;
update();
}
QSGNode* ChartIndicator::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) {
QSGGeometryNode *node = nullptr;
QSGGeometry *geometry = nullptr;
GL::VertexVector vertices;
GL::IndexVector indices;
// Triangulate
if (m_doupdate) {
for (const PointVector& ps: m_vertices) {
thickerLines(ps, true, lineWidth, vertices, indices);
}
}
if (!oldNode) {
node = new QSGGeometryNode;
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(),
vertices.size() / 2,
indices.size(),
GL_UNSIGNED_INT);
geometry->setDrawingMode(GL_TRIANGLES);
geometry->setVertexDataPattern(QSGGeometry::DynamicPattern);
geometry->setIndexDataPattern(QSGGeometry::DynamicPattern);
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
auto material = new QSGFlatColorMaterial;
material->setColor(QColor("#2d962d"));
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
} else if (m_doupdate) {
node = static_cast<QSGGeometryNode*>(oldNode);
geometry = node->geometry();
if (geometry->vertexCount() != vertices.size() / 2 || geometry->indexCount() != indices.size()) {
geometry->allocate(vertices.size() / 2, indices.size());
}
}
if (m_doupdate) {
memcpy(geometry->vertexData(), vertices.constData(), vertices.size() * sizeof(GLfloat));
memcpy(geometry->indexData(), indices.constData(), indices.size() * sizeof(GLuint));
node->markDirty(QSGNode::DirtyGeometry);
geometry->markIndexDataDirty();
}
m_doupdate = false;
return node;
}