##// END OF EJS Templates
Basic mouse wheel interactions + mode drag
trabillard -
r1001:ebb8b3d01eee
parent child
Show More
@@ -1,53 +1,55
1 #include "Visualization/VisualizationDragWidget.h"
1 #include "Visualization/VisualizationDragWidget.h"
2 #include "Visualization/VisualizationDragDropContainer.h"
2 #include "Visualization/VisualizationDragDropContainer.h"
3
3
4 #include <QApplication>
4 #include <QApplication>
5 #include <QMouseEvent>
5 #include <QMouseEvent>
6
6
7 #include <SqpApplication.h>
8
7 struct VisualizationDragWidget::VisualizationDragWidgetPrivate {
9 struct VisualizationDragWidget::VisualizationDragWidgetPrivate {
8
10
9 QPoint m_DragStartPosition;
11 QPoint m_DragStartPosition;
10 bool m_DragStartPositionValid = false;
12 bool m_DragStartPositionValid = false;
11
13
12 explicit VisualizationDragWidgetPrivate() {}
14 explicit VisualizationDragWidgetPrivate() {}
13 };
15 };
14
16
15 VisualizationDragWidget::VisualizationDragWidget(QWidget *parent)
17 VisualizationDragWidget::VisualizationDragWidget(QWidget *parent)
16 : QWidget{parent}, impl{spimpl::make_unique_impl<VisualizationDragWidgetPrivate>()}
18 : QWidget{parent}, impl{spimpl::make_unique_impl<VisualizationDragWidgetPrivate>()}
17 {
19 {
18 }
20 }
19
21
20 void VisualizationDragWidget::mousePressEvent(QMouseEvent *event)
22 void VisualizationDragWidget::mousePressEvent(QMouseEvent *event)
21 {
23 {
22 if (event->button() == Qt::LeftButton) {
24 if (event->button() == Qt::LeftButton) {
23 impl->m_DragStartPosition = event->pos();
25 impl->m_DragStartPosition = event->pos();
24 }
26 }
25
27
26 impl->m_DragStartPositionValid = isDragAllowed();
28 impl->m_DragStartPositionValid = isDragAllowed();
27
29
28 QWidget::mousePressEvent(event);
30 QWidget::mousePressEvent(event);
29 }
31 }
30
32
31 void VisualizationDragWidget::mouseMoveEvent(QMouseEvent *event)
33 void VisualizationDragWidget::mouseMoveEvent(QMouseEvent *event)
32 {
34 {
33 if (!impl->m_DragStartPositionValid || !isDragAllowed()) {
35 if (!impl->m_DragStartPositionValid || !isDragAllowed()) {
34 return;
36 return;
35 }
37 }
36
38
37 if (!(event->buttons() & Qt::LeftButton)) {
39 if (!(event->buttons() & Qt::LeftButton)) {
38 return;
40 return;
39 }
41 }
40
42
41 if (!event->modifiers().testFlag(Qt::AltModifier)) {
43 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::DragAndDrop
42 return;
44 || event->modifiers().testFlag(Qt::AltModifier)) {
43 }
44
45
45 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
46 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
46 < QApplication::startDragDistance()) {
47 < QApplication::startDragDistance()) {
47 return;
48 return;
48 }
49 }
49
50
50 emit dragDetected(this, impl->m_DragStartPosition);
51 emit dragDetected(this, impl->m_DragStartPosition);
52 }
51
53
52 QWidget::mouseMoveEvent(event);
54 QWidget::mouseMoveEvent(event);
53 }
55 }
@@ -1,402 +1,416
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationDefs.h"
3 #include "Visualization/VisualizationDefs.h"
4 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphHelper.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7 #include "ui_VisualizationGraphWidget.h"
7 #include "ui_VisualizationGraphWidget.h"
8
8
9 #include <Common/MimeTypesDef.h>
9 #include <Common/MimeTypesDef.h>
10 #include <Data/ArrayData.h>
10 #include <Data/ArrayData.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <DragAndDrop/DragDropHelper.h>
12 #include <DragAndDrop/DragDropHelper.h>
13 #include <Settings/SqpSettingsDefs.h>
13 #include <Settings/SqpSettingsDefs.h>
14 #include <SqpApplication.h>
14 #include <SqpApplication.h>
15 #include <Time/TimeController.h>
15 #include <Time/TimeController.h>
16 #include <Variable/Variable.h>
16 #include <Variable/Variable.h>
17 #include <Variable/VariableController.h>
17 #include <Variable/VariableController.h>
18
18
19 #include <unordered_map>
19 #include <unordered_map>
20
20
21 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
21 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
22
22
23 namespace {
23 namespace {
24
24
25 /// Key pressed to enable zoom on horizontal axis
25 /// Key pressed to enable zoom on horizontal axis
26 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
26 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier;
27
27
28 /// Key pressed to enable zoom on vertical axis
28 /// Key pressed to enable zoom on vertical axis
29 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
29 const auto VERTICAL_ZOOM_MODIFIER = Qt::ShiftModifier;
30
31 /// Speed of a step of a wheel event for a pan, in percentage of the axis range
32 const auto PAN_SPEED = 5;
33
34 /// Key pressed to enable a calibration pan
35 const auto VERTICAL_PAN_MODIFIER = Qt::AltModifier;
30
36
31 } // namespace
37 } // namespace
32
38
33 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
39 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
34
40
35 explicit VisualizationGraphWidgetPrivate(const QString &name)
41 explicit VisualizationGraphWidgetPrivate(const QString &name)
36 : m_Name{name},
42 : m_Name{name},
37 m_DoAcquisition{true},
43 m_DoAcquisition{true},
38 m_IsCalibration{false},
44 m_IsCalibration{false},
39 m_RenderingDelegate{nullptr}
45 m_RenderingDelegate{nullptr}
40 {
46 {
41 }
47 }
42
48
43 QString m_Name;
49 QString m_Name;
44 // 1 variable -> n qcpplot
50 // 1 variable -> n qcpplot
45 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
51 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
46 bool m_DoAcquisition;
52 bool m_DoAcquisition;
47 bool m_IsCalibration;
53 bool m_IsCalibration;
48 /// Delegate used to attach rendering features to the plot
54 /// Delegate used to attach rendering features to the plot
49 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
55 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
50 };
56 };
51
57
52 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
58 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
53 : VisualizationDragWidget{parent},
59 : VisualizationDragWidget{parent},
54 ui{new Ui::VisualizationGraphWidget},
60 ui{new Ui::VisualizationGraphWidget},
55 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
61 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
56 {
62 {
57 ui->setupUi(this);
63 ui->setupUi(this);
58
64
59 // 'Close' options : widget is deleted when closed
65 // 'Close' options : widget is deleted when closed
60 setAttribute(Qt::WA_DeleteOnClose);
66 setAttribute(Qt::WA_DeleteOnClose);
61
67
62 // Set qcpplot properties :
68 // Set qcpplot properties :
63 // - Drag (on x-axis) and zoom are enabled
69 // - Drag (on x-axis) and zoom are enabled
64 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
70 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
65 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
71 ui->widget->setInteractions(QCP::iRangeZoom | QCP::iSelectItems);
66 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
67
72
68 // The delegate must be initialized after the ui as it uses the plot
73 // The delegate must be initialized after the ui as it uses the plot
69 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
74 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
70
75
71 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
76 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
72 connect(ui->widget, &QCustomPlot::mouseRelease, this,
77 connect(ui->widget, &QCustomPlot::mouseRelease, this,
73 &VisualizationGraphWidget::onMouseRelease);
78 &VisualizationGraphWidget::onMouseRelease);
74 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
79 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
75 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
80 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
76 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
81 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
77 &QCPAxis::rangeChanged),
82 &QCPAxis::rangeChanged),
78 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
83 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
79
84
80 // Activates menu when right clicking on the graph
85 // Activates menu when right clicking on the graph
81 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
86 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
82 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
87 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
83 &VisualizationGraphWidget::onGraphMenuRequested);
88 &VisualizationGraphWidget::onGraphMenuRequested);
84
89
85 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
90 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
86 &VariableController::onRequestDataLoading);
91 &VariableController::onRequestDataLoading);
87
92
88 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
93 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
89 &VisualizationGraphWidget::onUpdateVarDisplaying);
94 &VisualizationGraphWidget::onUpdateVarDisplaying);
90 }
95 }
91
96
92
97
93 VisualizationGraphWidget::~VisualizationGraphWidget()
98 VisualizationGraphWidget::~VisualizationGraphWidget()
94 {
99 {
95 delete ui;
100 delete ui;
96 }
101 }
97
102
98 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
103 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
99 {
104 {
100 auto parent = parentWidget();
105 auto parent = parentWidget();
101 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
106 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
102 parent = parent->parentWidget();
107 parent = parent->parentWidget();
103 }
108 }
104
109
105 return qobject_cast<VisualizationZoneWidget *>(parent);
110 return qobject_cast<VisualizationZoneWidget *>(parent);
106 }
111 }
107
112
108 void VisualizationGraphWidget::enableAcquisition(bool enable)
113 void VisualizationGraphWidget::enableAcquisition(bool enable)
109 {
114 {
110 impl->m_DoAcquisition = enable;
115 impl->m_DoAcquisition = enable;
111 }
116 }
112
117
113 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
118 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
114 {
119 {
115 // Uses delegate to create the qcpplot components according to the variable
120 // Uses delegate to create the qcpplot components according to the variable
116 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
121 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
117
122
118 if (auto dataSeries = variable->dataSeries()) {
123 if (auto dataSeries = variable->dataSeries()) {
119 // Set axes properties according to the units of the data series
124 // Set axes properties according to the units of the data series
120 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
125 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
121
126
122 // Sets rendering properties for the new plottables
127 // Sets rendering properties for the new plottables
123 // Warning: this method must be called after setAxesProperties(), as it can access to some
128 // Warning: this method must be called after setAxesProperties(), as it can access to some
124 // axes properties that have to be initialized
129 // axes properties that have to be initialized
125 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
130 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
126 }
131 }
127
132
128 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
133 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
129
134
130 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
135 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
131
136
132 this->enableAcquisition(false);
137 this->enableAcquisition(false);
133 this->setGraphRange(range);
138 this->setGraphRange(range);
134 this->enableAcquisition(true);
139 this->enableAcquisition(true);
135
140
136 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
141 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
137
142
138 emit variableAdded(variable);
143 emit variableAdded(variable);
139 }
144 }
140
145
141 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
146 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
142 {
147 {
143 // Each component associated to the variable :
148 // Each component associated to the variable :
144 // - is removed from qcpplot (which deletes it)
149 // - is removed from qcpplot (which deletes it)
145 // - is no longer referenced in the map
150 // - is no longer referenced in the map
146 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
151 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
147 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
152 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
148 emit variableAboutToBeRemoved(variable);
153 emit variableAboutToBeRemoved(variable);
149
154
150 auto &plottablesMap = variableIt->second;
155 auto &plottablesMap = variableIt->second;
151
156
152 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
157 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
153 plottableIt != plottableEnd;) {
158 plottableIt != plottableEnd;) {
154 ui->widget->removePlottable(plottableIt->second);
159 ui->widget->removePlottable(plottableIt->second);
155 plottableIt = plottablesMap.erase(plottableIt);
160 plottableIt = plottablesMap.erase(plottableIt);
156 }
161 }
157
162
158 impl->m_VariableToPlotMultiMap.erase(variableIt);
163 impl->m_VariableToPlotMultiMap.erase(variableIt);
159 }
164 }
160
165
161 // Updates graph
166 // Updates graph
162 ui->widget->replot();
167 ui->widget->replot();
163 }
168 }
164
169
165 QList<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
170 QList<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
166 {
171 {
167 auto variables = QList<std::shared_ptr<Variable> >{};
172 auto variables = QList<std::shared_ptr<Variable> >{};
168 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
173 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
169 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
174 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
170 variables << it->first;
175 variables << it->first;
171 }
176 }
172
177
173 return variables;
178 return variables;
174 }
179 }
175
180
176 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
181 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
177 {
182 {
178 if (!variable) {
183 if (!variable) {
179 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
184 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
180 return;
185 return;
181 }
186 }
182
187
183 VisualizationGraphHelper::setYAxisRange(variable, *ui->widget);
188 VisualizationGraphHelper::setYAxisRange(variable, *ui->widget);
184 }
189 }
185
190
186 SqpRange VisualizationGraphWidget::graphRange() const noexcept
191 SqpRange VisualizationGraphWidget::graphRange() const noexcept
187 {
192 {
188 auto graphRange = ui->widget->xAxis->range();
193 auto graphRange = ui->widget->xAxis->range();
189 return SqpRange{graphRange.lower, graphRange.upper};
194 return SqpRange{graphRange.lower, graphRange.upper};
190 }
195 }
191
196
192 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
197 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
193 {
198 {
194 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
199 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
195 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
200 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
196 ui->widget->replot();
201 ui->widget->replot();
197 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
202 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
198 }
203 }
199
204
200 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
205 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
201 {
206 {
202 if (visitor) {
207 if (visitor) {
203 visitor->visit(this);
208 visitor->visit(this);
204 }
209 }
205 else {
210 else {
206 qCCritical(LOG_VisualizationGraphWidget())
211 qCCritical(LOG_VisualizationGraphWidget())
207 << tr("Can't visit widget : the visitor is null");
212 << tr("Can't visit widget : the visitor is null");
208 }
213 }
209 }
214 }
210
215
211 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
216 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
212 {
217 {
213 /// @todo : for the moment, a graph can always accomodate a variable
218 /// @todo : for the moment, a graph can always accomodate a variable
214 Q_UNUSED(variable);
219 Q_UNUSED(variable);
215 return true;
220 return true;
216 }
221 }
217
222
218 bool VisualizationGraphWidget::contains(const Variable &variable) const
223 bool VisualizationGraphWidget::contains(const Variable &variable) const
219 {
224 {
220 // Finds the variable among the keys of the map
225 // Finds the variable among the keys of the map
221 auto variablePtr = &variable;
226 auto variablePtr = &variable;
222 auto findVariable
227 auto findVariable
223 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
228 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
224
229
225 auto end = impl->m_VariableToPlotMultiMap.cend();
230 auto end = impl->m_VariableToPlotMultiMap.cend();
226 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
231 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
227 return it != end;
232 return it != end;
228 }
233 }
229
234
230 QString VisualizationGraphWidget::name() const
235 QString VisualizationGraphWidget::name() const
231 {
236 {
232 return impl->m_Name;
237 return impl->m_Name;
233 }
238 }
234
239
235 QMimeData *VisualizationGraphWidget::mimeData() const
240 QMimeData *VisualizationGraphWidget::mimeData() const
236 {
241 {
237 auto mimeData = new QMimeData;
242 auto mimeData = new QMimeData;
238 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
243 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
239
244
240 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
245 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
241 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
246 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
242
247
243 return mimeData;
248 return mimeData;
244 }
249 }
245
250
246 bool VisualizationGraphWidget::isDragAllowed() const
251 bool VisualizationGraphWidget::isDragAllowed() const
247 {
252 {
248 return true;
253 return true;
249 }
254 }
250
255
251 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
256 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
252 {
257 {
253 if (highlighted) {
258 if (highlighted) {
254 plot().setBackground(QBrush(QColor("#BBD5EE")));
259 plot().setBackground(QBrush(QColor("#BBD5EE")));
255 }
260 }
256 else {
261 else {
257 plot().setBackground(QBrush(Qt::white));
262 plot().setBackground(QBrush(Qt::white));
258 }
263 }
259
264
260 plot().update();
265 plot().update();
261 }
266 }
262
267
263 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
268 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
264 {
269 {
265 Q_UNUSED(event);
270 Q_UNUSED(event);
266
271
267 // Prevents that all variables will be removed from graph when it will be closed
272 // Prevents that all variables will be removed from graph when it will be closed
268 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
273 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
269 emit variableAboutToBeRemoved(variableEntry.first);
274 emit variableAboutToBeRemoved(variableEntry.first);
270 }
275 }
271 }
276 }
272
277
273 void VisualizationGraphWidget::enterEvent(QEvent *event)
278 void VisualizationGraphWidget::enterEvent(QEvent *event)
274 {
279 {
275 Q_UNUSED(event);
280 Q_UNUSED(event);
276 impl->m_RenderingDelegate->showGraphOverlay(true);
281 impl->m_RenderingDelegate->showGraphOverlay(true);
277 }
282 }
278
283
279 void VisualizationGraphWidget::leaveEvent(QEvent *event)
284 void VisualizationGraphWidget::leaveEvent(QEvent *event)
280 {
285 {
281 Q_UNUSED(event);
286 Q_UNUSED(event);
282 impl->m_RenderingDelegate->showGraphOverlay(false);
287 impl->m_RenderingDelegate->showGraphOverlay(false);
283 }
288 }
284
289
285 QCustomPlot &VisualizationGraphWidget::plot() noexcept
290 QCustomPlot &VisualizationGraphWidget::plot() noexcept
286 {
291 {
287 return *ui->widget;
292 return *ui->widget;
288 }
293 }
289
294
290 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
295 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
291 {
296 {
292 QMenu graphMenu{};
297 QMenu graphMenu{};
293
298
294 // Iterates on variables (unique keys)
299 // Iterates on variables (unique keys)
295 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
300 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
296 end = impl->m_VariableToPlotMultiMap.cend();
301 end = impl->m_VariableToPlotMultiMap.cend();
297 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
302 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
298 // 'Remove variable' action
303 // 'Remove variable' action
299 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
304 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
300 [ this, var = it->first ]() { removeVariable(var); });
305 [ this, var = it->first ]() { removeVariable(var); });
301 }
306 }
302
307
303 if (!graphMenu.isEmpty()) {
308 if (!graphMenu.isEmpty()) {
304 graphMenu.exec(QCursor::pos());
309 graphMenu.exec(QCursor::pos());
305 }
310 }
306 }
311 }
307
312
308 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
313 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
309 {
314 {
310 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
315 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
311 << QThread::currentThread()->objectName() << "DoAcqui"
316 << QThread::currentThread()->objectName() << "DoAcqui"
312 << impl->m_DoAcquisition;
317 << impl->m_DoAcquisition;
313
318
314 auto graphRange = SqpRange{t1.lower, t1.upper};
319 auto graphRange = SqpRange{t1.lower, t1.upper};
315 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
320 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
316
321
317 if (impl->m_DoAcquisition) {
322 if (impl->m_DoAcquisition) {
318 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
323 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
319
324
320 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
325 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
321 end = impl->m_VariableToPlotMultiMap.end();
326 end = impl->m_VariableToPlotMultiMap.end();
322 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
327 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
323 variableUnderGraphVector.push_back(it->first);
328 variableUnderGraphVector.push_back(it->first);
324 }
329 }
325 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange,
330 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange,
326 !impl->m_IsCalibration);
331 !impl->m_IsCalibration);
327
332
328 if (!impl->m_IsCalibration) {
333 if (!impl->m_IsCalibration) {
329 qCDebug(LOG_VisualizationGraphWidget())
334 qCDebug(LOG_VisualizationGraphWidget())
330 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
335 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
331 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
336 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
332 emit synchronize(graphRange, oldGraphRange);
337 emit synchronize(graphRange, oldGraphRange);
333 }
338 }
334 }
339 }
335 }
340 }
336
341
337 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
342 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
338 {
343 {
339 // Handles plot rendering when mouse is moving
344 // Handles plot rendering when mouse is moving
340 impl->m_RenderingDelegate->onMouseMove(event);
345 impl->m_RenderingDelegate->onMouseMove(event);
341
346
342 VisualizationDragWidget::mouseMoveEvent(event);
347 VisualizationDragWidget::mouseMoveEvent(event);
343 }
348 }
344
349
345 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
350 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
346 {
351 {
347 auto zoomOrientations = QFlags<Qt::Orientation>{};
352 auto value = event->angleDelta().x() + event->angleDelta().y();
353 if (value != 0) {
348
354
349 // Lambda that enables a zoom orientation if the key modifier related to this orientation
355 auto direction = value > 0 ? 1.0 : -1.0;
350 // has
356 auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
351 // been pressed
357 auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
352 auto enableOrientation
358 impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
353 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
359
354 auto orientationEnabled = event->modifiers().testFlag(modifier);
360 auto zoomOrientations = QFlags<Qt::Orientation>{};
355 zoomOrientations.setFlag(orientation, orientationEnabled);
361 zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
356 };
362 zoomOrientations.setFlag(Qt::Vertical, isZoomY);
357 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
358 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
359
363
360 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
364 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
365
366 if (!isZoomX && !isZoomY) {
367 auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
368 auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
369
370 axis->setRange(axis->range() + diff);
371
372 if (plot().noAntialiasingOnDrag()) {
373 plot().setNotAntialiasedElements(QCP::aeAll);
374 }
375
376 plot().replot(QCustomPlot::rpQueuedReplot);
377 }
378 }
361 }
379 }
362
380
363 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
381 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
364 {
382 {
365 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
366
367 plot().setInteraction(QCP::iRangeDrag, !event->modifiers().testFlag(Qt::AltModifier));
368
369 VisualizationDragWidget::mousePressEvent(event);
383 VisualizationDragWidget::mousePressEvent(event);
370 }
384 }
371
385
372 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
386 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
373 {
387 {
374 impl->m_IsCalibration = false;
388 impl->m_IsCalibration = false;
375 }
389 }
376
390
377 void VisualizationGraphWidget::onDataCacheVariableUpdated()
391 void VisualizationGraphWidget::onDataCacheVariableUpdated()
378 {
392 {
379 auto graphRange = ui->widget->xAxis->range();
393 auto graphRange = ui->widget->xAxis->range();
380 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
394 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
381
395
382 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
396 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
383 auto variable = variableEntry.first;
397 auto variable = variableEntry.first;
384 qCDebug(LOG_VisualizationGraphWidget())
398 qCDebug(LOG_VisualizationGraphWidget())
385 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
399 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
386 qCDebug(LOG_VisualizationGraphWidget())
400 qCDebug(LOG_VisualizationGraphWidget())
387 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
401 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
388 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
402 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
389 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
403 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
390 variable->range());
404 variable->range());
391 }
405 }
392 }
406 }
393 }
407 }
394
408
395 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
409 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
396 const SqpRange &range)
410 const SqpRange &range)
397 {
411 {
398 auto it = impl->m_VariableToPlotMultiMap.find(variable);
412 auto it = impl->m_VariableToPlotMultiMap.find(variable);
399 if (it != impl->m_VariableToPlotMultiMap.end()) {
413 if (it != impl->m_VariableToPlotMultiMap.end()) {
400 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
414 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
401 }
415 }
402 }
416 }
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now