From ba3527d7b666c00af36dbd62e771fc2f227b1bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Fri, 14 May 2021 20:34:23 +0200 Subject: [PATCH] Add markers by right-clicking a graph --- Software/PC_Application/Traces/trace.cpp | 3 + Software/PC_Application/Traces/trace.h | 1 + .../PC_Application/Traces/tracemarker.cpp | 97 ++++++++++++------- Software/PC_Application/Traces/tracemarker.h | 3 +- .../Traces/tracemarkermodel.cpp | 1 + Software/PC_Application/Traces/tracemodel.cpp | 10 ++ Software/PC_Application/Traces/tracemodel.h | 6 ++ Software/PC_Application/Traces/traceplot.cpp | 47 ++++++++- Software/PC_Application/Traces/traceplot.h | 6 +- .../PC_Application/Traces/tracesmithchart.cpp | 74 +++++++------- .../PC_Application/Traces/tracesmithchart.h | 2 +- .../PC_Application/Traces/tracexyplot.cpp | 53 +++++++--- Software/PC_Application/Traces/tracexyplot.h | 2 +- Software/PC_Application/preferences.cpp | 8 ++ Software/PC_Application/preferences.h | 8 +- Software/PC_Application/preferencesdialog.ui | 23 +++++ 16 files changed, 253 insertions(+), 91 deletions(-) diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 848e9de..e489d07 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -6,6 +6,7 @@ #include #include #include "unit.h" +#include "tracemarker.h" using namespace std; @@ -263,11 +264,13 @@ void Trace::setColor(QColor color) { void Trace::addMarker(TraceMarker *m) { markers.insert(m); + connect(m, &TraceMarker::dataFormatChanged, this, &Trace::markerFormatChanged); emit markerAdded(m); } void Trace::removeMarker(TraceMarker *m) { + disconnect(m, &TraceMarker::dataFormatChanged, this, &Trace::markerFormatChanged); markers.erase(m); emit markerRemoved(m); } diff --git a/Software/PC_Application/Traces/trace.h b/Software/PC_Application/Traces/trace.h index b2d197a..65a8479 100644 --- a/Software/PC_Application/Traces/trace.h +++ b/Software/PC_Application/Traces/trace.h @@ -160,6 +160,7 @@ signals: void colorChanged(Trace *t); void markerAdded(TraceMarker *m); void markerRemoved(TraceMarker *m); + void markerFormatChanged(TraceMarker *m); private: QString _name; diff --git a/Software/PC_Application/Traces/tracemarker.cpp b/Software/PC_Application/Traces/tracemarker.cpp index de84e5a..28c40b7 100644 --- a/Software/PC_Application/Traces/tracemarker.cpp +++ b/Software/PC_Application/Traces/tracemarker.cpp @@ -10,6 +10,7 @@ #include #include #include +#include "preferences.h" using namespace std; @@ -46,10 +47,13 @@ TraceMarker::~TraceMarker() void TraceMarker::assignTrace(Trace *t) { + bool firstAssignment = false; if(parentTrace) { // remove connection from previous parent trace parentTrace->removeMarker(this); disconnect(parentTrace, &Trace::deleted, this, nullptr); + } else { + firstAssignment = true; } parentTrace = t; if(!getSupportedTypes().count(type)) { @@ -63,16 +67,29 @@ void TraceMarker::assignTrace(Trace *t) connect(parentTrace, &Trace::deleted, this, &TraceMarker::parentTraceDeleted); connect(parentTrace, &Trace::dataChanged, this, &TraceMarker::traceDataChanged); connect(parentTrace, &Trace::colorChanged, this, &TraceMarker::updateSymbol); - connect(parentTrace, &Trace::typeChanged, [=](){ - emit domainChanged(); - checkDeltaMarker(); - }); + connect(parentTrace, &Trace::typeChanged, this, &TraceMarker::domainChanged); + connect(parentTrace, &Trace::typeChanged, this, &TraceMarker::checkDeltaMarker); constrainPosition(); updateSymbol(); parentTrace->addMarker(this); for(auto m : helperMarkers) { m->assignTrace(t); } + + if(firstAssignment) { + // Marker was just created and this is the first assignment to a trace. + // Use display format on graph from preferences + auto p = Preferences::getInstance(); + if(p.General.markerDefault.showDataOnGraphs) { + if(p.General.markerDefault.showAllData) { + for(auto f : applicableFormats()) { + formatGraph.insert(f); + } + } else { + formatGraph.insert(applicableFormats().front()); + } + } + } constrainFormat(); update(); emit traceChanged(this); @@ -122,19 +139,19 @@ std::vector TraceMarker::formats() return ret; } -std::set TraceMarker::applicableFormats() +std::vector TraceMarker::applicableFormats() { - std::set ret; + std::vector ret; if(isTimeDomain()) { switch(type) { case Type::Manual: case Type::Delta: - ret.insert(Format::dB); - ret.insert(Format::RealImag); + ret.push_back(Format::dB); + ret.push_back(Format::RealImag); if(parentTrace) { auto step = parentTrace->sample(parentTrace->index(position), Trace::SampleType::TimeStep).y.real(); if(!isnan(step)) { - ret.insert(Format::Impedance); + ret.push_back(Format::Impedance); } } break; @@ -148,36 +165,36 @@ std::set TraceMarker::applicableFormats() case Type::Maximum: case Type::Minimum: case Type::PeakTable: - ret.insert(Format::dB); - ret.insert(Format::dBAngle); - ret.insert(Format::RealImag); + ret.push_back(Format::dB); + ret.push_back(Format::dBAngle); + ret.push_back(Format::RealImag); if(parentTrace) { if(parentTrace->isReflection()) { - ret.insert(Format::Impedance); + ret.push_back(Format::Impedance); } if(!isnan(parentTrace->getNoise(parentTrace->minX()))) { - ret.insert(Format::Noise); + ret.push_back(Format::Noise); } } break; case Type::Bandpass: - ret.insert(Format::CenterBandwidth); - ret.insert(Format::InsertionLoss); + ret.push_back(Format::CenterBandwidth); + ret.push_back(Format::InsertionLoss); break; case Type::Lowpass: case Type::Highpass: - ret.insert(Format::Cutoff); - ret.insert(Format::InsertionLoss); + ret.push_back(Format::Cutoff); + ret.push_back(Format::InsertionLoss); break; case Type::PhaseNoise: - ret.insert(Format::PhaseNoise); - ret.insert(Format::dB); + ret.push_back(Format::PhaseNoise); + ret.push_back(Format::dB); break; case Type::TOI: - ret.insert(Format::TOI); - ret.insert(Format::AvgTone); - ret.insert(Format::AvgModulationProduct); + ret.push_back(Format::TOI); + ret.push_back(Format::AvgTone); + ret.push_back(Format::AvgModulationProduct); break; case Type::Last: break; @@ -490,6 +507,7 @@ void TraceMarker::updateContextmenu() } contextmenu.clear(); + contextmenu.addSection("Marker"); auto typemenu = contextmenu.addMenu("Type"); auto typegroup = new QActionGroup(&contextmenu); @@ -534,9 +552,14 @@ void TraceMarker::updateContextmenu() } else { formatGraph.erase(f); } + emit dataFormatChanged(this); }); graph->addAction(setFormatAction); } + + auto deleteAction = new QAction("Delete"); + connect(deleteAction, &QAction::triggered, this, &TraceMarker::deleteLater); + contextmenu.addAction(deleteAction); } std::set TraceMarker::getSupportedTypes() @@ -554,16 +577,18 @@ std::set TraceMarker::getSupportedTypes() supported.insert(Type::Minimum); supported.insert(Type::Delta); supported.insert(Type::PeakTable); + if(!parentTrace->isReflection()) { + supported.insert(Type::Lowpass); + supported.insert(Type::Highpass); + supported.insert(Type::Bandpass); + } if(parentTrace->isLive()) { switch(parentTrace->liveParameter()) { case Trace::LiveParameter::S11: case Trace::LiveParameter::S12: case Trace::LiveParameter::S21: case Trace::LiveParameter::S22: - // special VNA marker types - supported.insert(Type::Lowpass); - supported.insert(Type::Highpass); - supported.insert(Type::Bandpass); + // no special marker types for VNA yet break; case Trace::LiveParameter::Port1: case Trace::LiveParameter::Port2: @@ -595,15 +620,20 @@ void TraceMarker::constrainPosition() void TraceMarker::constrainFormat() { + auto vec = applicableFormats(); // check format - if(!applicableFormats().count(formatTable)) { - setTableFormat(*applicableFormats().begin()); + if(std::find(vec.begin(), vec.end(), formatTable) == vec.end()) { + setTableFormat(vec.front()); } + std::set toErase; for(auto f : formatGraph) { - if(!applicableFormats().count(f)) { - formatGraph.erase(f); + if(std::find(vec.begin(), vec.end(), f) == vec.end()) { + toErase.insert(f); } } + for(auto f : toErase) { + formatGraph.erase(f); + } } TraceMarker *TraceMarker::bestDeltaCandidate() @@ -741,14 +771,15 @@ void TraceMarker::setTableFormat(TraceMarker::Format f) return; } - if(!applicableFormats().count(f)) { + auto vec = applicableFormats(); + if(std::find(vec.begin(), vec.end(), f) == vec.end()) { // can't use requested format for this type of marker qWarning() << "Requested marker format" << formatToString(f) << "(not applicable for type" << typeToString(type) <<")"; return; } formatTable = f; - emit dataChanged(this); + emit dataFormatChanged(this); } std::set TraceMarker::getGraphDisplayFormats() const diff --git a/Software/PC_Application/Traces/tracemarker.h b/Software/PC_Application/Traces/tracemarker.h index efe61ee..f6bc8a1 100644 --- a/Software/PC_Application/Traces/tracemarker.h +++ b/Software/PC_Application/Traces/tracemarker.h @@ -43,7 +43,7 @@ public: static QString formatToString(Format f); static Format formatFromString(QString s); static std::vector formats(); - std::set applicableFormats(); + std::vector applicableFormats(); QString readableData(Format format = Format::Last); QString readableSettings(); @@ -116,6 +116,7 @@ signals: void traceChanged(TraceMarker *m); void beginRemoveHelperMarkers(TraceMarker *m); void endRemoveHelperMarkers(TraceMarker *m); + void dataFormatChanged(TraceMarker *m); private slots: void parentTraceDeleted(Trace *t); diff --git a/Software/PC_Application/Traces/tracemarkermodel.cpp b/Software/PC_Application/Traces/tracemarkermodel.cpp index b7a6239..1b01054 100644 --- a/Software/PC_Application/Traces/tracemarkermodel.cpp +++ b/Software/PC_Application/Traces/tracemarkermodel.cpp @@ -13,6 +13,7 @@ TraceMarkerModel::TraceMarkerModel(TraceModel &model, QObject *parent) : QAbstractItemModel(parent), model(model) { + model.setMarkerModel(this); markers.clear(); root = new TraceMarker(this); } diff --git a/Software/PC_Application/Traces/tracemodel.cpp b/Software/PC_Application/Traces/tracemodel.cpp index 97ecfd4..daae0b6 100644 --- a/Software/PC_Application/Traces/tracemodel.cpp +++ b/Software/PC_Application/Traces/tracemodel.cpp @@ -242,3 +242,13 @@ void TraceModel::addSAData(const Protocol::SpectrumAnalyzerResult& d, const Prot } } } + +TraceMarkerModel *TraceModel::getMarkerModel() const +{ + return markerModel; +} + +void TraceModel::setMarkerModel(TraceMarkerModel *value) +{ + markerModel = value; +} diff --git a/Software/PC_Application/Traces/tracemodel.h b/Software/PC_Application/Traces/tracemodel.h index 21104a4..eb75529 100644 --- a/Software/PC_Application/Traces/tracemodel.h +++ b/Software/PC_Application/Traces/tracemodel.h @@ -7,6 +7,8 @@ #include "Device/device.h" #include "savable.h" +class TraceMarkerModel; + class TraceModel : public QAbstractTableModel, public Savable { Q_OBJECT @@ -40,6 +42,9 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + TraceMarkerModel *getMarkerModel() const; + void setMarkerModel(TraceMarkerModel *value); + signals: void SpanChanged(double fmin, double fmax); void traceAdded(Trace *t); @@ -54,6 +59,7 @@ public slots: private: std::vector traces; + TraceMarkerModel *markerModel; }; #endif // TRACEMODEL_H diff --git a/Software/PC_Application/Traces/traceplot.cpp b/Software/PC_Application/Traces/traceplot.cpp index c089a62..2060352 100644 --- a/Software/PC_Application/Traces/traceplot.cpp +++ b/Software/PC_Application/Traces/traceplot.cpp @@ -5,6 +5,7 @@ #include #include #include "unit.h" +#include "tracemarkermodel.h" std::set TracePlot::plots; @@ -21,6 +22,8 @@ TracePlot::TracePlot(TraceModel &model, QWidget *parent) markedForDeletion = false; setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); lastUpdate = QTime::currentTime(); + replotTimer.setSingleShot(true); + connect(&replotTimer, &QTimer::timeout, this, qOverload<>(&TracePlot::update)); sweep_fmin = std::numeric_limits::lowest(); sweep_fmax = std::numeric_limits::max(); // get notified when the span changes @@ -52,6 +55,7 @@ void TracePlot::enableTrace(Trace *t, bool enabled) // connect signals connect(t, &Trace::dataChanged, this, &TracePlot::triggerReplot); connect(t, &Trace::visibilityChanged, this, &TracePlot::triggerReplot); + connect(t, &Trace::markerFormatChanged, this, &TracePlot::triggerReplot); connect(t, &Trace::markerAdded, this, &TracePlot::markerAdded); connect(t, &Trace::markerRemoved, this, &TracePlot::markerRemoved); connect(t, &Trace::typeChanged, this, &TracePlot::checkIfStillSupported); @@ -59,6 +63,7 @@ void TracePlot::enableTrace(Trace *t, bool enabled) // disconnect from notifications disconnect(t, &Trace::dataChanged, this, &TracePlot::triggerReplot); disconnect(t, &Trace::visibilityChanged, this, &TracePlot::triggerReplot); + disconnect(t, &Trace::markerFormatChanged, this, &TracePlot::triggerReplot); disconnect(t, &Trace::markerAdded, this, &TracePlot::markerAdded); disconnect(t, &Trace::markerRemoved, this, &TracePlot::markerRemoved); disconnect(t, &Trace::typeChanged, this, &TracePlot::checkIfStillSupported); @@ -101,6 +106,7 @@ void TracePlot::contextMenuEvent(QContextMenuEvent *event) } else { // no marker, contextmenu of graph menu = contextmenu; + contextmenuClickpoint = event->pos(); } menu->exec(event->globalPos()); if(markedForDeletion) { @@ -183,7 +189,11 @@ void TracePlot::paintEvent(QPaintEvent *event) void TracePlot::mousePressEvent(QMouseEvent *event) { - selectedMarker = markerAtPosition(event->pos(), true); + if(event->buttons() == Qt::LeftButton) { + selectedMarker = markerAtPosition(event->pos(), true); + } else { + selectedMarker = nullptr; + } } void TracePlot::mouseReleaseEvent(QMouseEvent *event) @@ -259,6 +269,39 @@ TraceMarker *TracePlot::markerAtPosition(QPoint p, bool onlyMovable) } } +void TracePlot::createMarkerAtPosition(QPoint p) +{ + // transate from point in absolute coordinates to this widget + p -= QPoint(marginLeft, marginTop); + + double closestDistance = std::numeric_limits::max(); + Trace *trace = nullptr; + double xpos; + for(auto t : traces) { + if(!t.second) { + // trace not enabled, skip + continue; + } + double distance; + auto x = nearestTracePoint(t.first, p, &distance); + if(distance < closestDistance) { + trace = t.first; + xpos = x; + closestDistance = distance; + } + } + if(!trace) { + // failed to find trace (should not happen) + return; + } + + auto markerModel = model.getMarkerModel(); + auto marker = markerModel->createDefaultMarker(); + marker->assignTrace(trace); + marker->setPosition(xpos); + markerModel->addMarker(marker); +} + void TracePlot::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("trace/pointer")) { @@ -322,6 +365,8 @@ void TracePlot::triggerReplot() if (lastUpdate.msecsTo(now) >= MinUpdateInterval) { lastUpdate = now; replot(); + } else { + replotTimer.start(MinUpdateInterval); } } diff --git a/Software/PC_Application/Traces/traceplot.h b/Software/PC_Application/Traces/traceplot.h index f5a5bfb..27a66f7 100644 --- a/Software/PC_Application/Traces/traceplot.h +++ b/Software/PC_Application/Traces/traceplot.h @@ -44,12 +44,14 @@ protected: virtual bool supported(Trace *t) = 0; std::map traces; QMenu *contextmenu; + QPoint contextmenuClickpoint; // mouse coordinates when the contextmenu was invoked QTime lastUpdate; + QTimer replotTimer; bool markedForDeletion; static std::set plots; virtual QPoint markerToPixel(TraceMarker *m) = 0; - virtual double nearestTracePoint(Trace *t, QPoint pixel) = 0; + virtual double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) = 0; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; @@ -57,6 +59,8 @@ protected: TraceMarker *markerAtPosition(QPoint p, bool onlyMovable = false); + void createMarkerAtPosition(QPoint p); + // handle trace drops virtual bool dropSupported(Trace *t) = 0; void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/Software/PC_Application/Traces/tracesmithchart.cpp b/Software/PC_Application/Traces/tracesmithchart.cpp index 55c524b..420db83 100644 --- a/Software/PC_Application/Traces/tracesmithchart.cpp +++ b/Software/PC_Application/Traces/tracesmithchart.cpp @@ -94,7 +94,7 @@ QPoint TraceSmithChart::markerToPixel(TraceMarker *m) return ret; } -double TraceSmithChart::nearestTracePoint(Trace *t, QPoint pixel) +double TraceSmithChart::nearestTracePoint(Trace *t, QPoint pixel, double *distance) { double closestDistance = numeric_limits::max(); unsigned int closestIndex = 0; @@ -112,6 +112,9 @@ double TraceSmithChart::nearestTracePoint(Trace *t, QPoint pixel) closestIndex = i; } } + if(distance) { + *distance = closestDistance; + } return t->sample(closestIndex).x; } @@ -264,47 +267,13 @@ QString TraceSmithChart::mouseText(QPoint pos) } } -//void TraceSmithChart::paintEvent(QPaintEvent * /* the event */) -//{ -// auto pref = Preferences::getInstance(); -// QPainter painter(this); -// painter.setRenderHint(QPainter::Antialiasing); -// painter.setBackground(QBrush(pref.General.graphColors.background)); -// painter.fillRect(0, 0, width(), height(), QBrush(pref.General.graphColors.background)); - -// double side = qMin(width(), height()) * screenUsage; - -// //painter.setViewport((width()-side)/2, (height()-side)/2, side, side); -// //painter.setWindow(-smithCoordMax, -smithCoordMax, 2*smithCoordMax, 2*smithCoordMax); - -// plotToPixelXOffset = width()/2; -// plotToPixelYOffset = height()/2; -// plotToPixelXScale = side/2; -// plotToPixelYScale = -side/2; - -// draw(painter, 2*smithCoordMax/side); -//} - void TraceSmithChart::updateContextMenu() { - contextmenu->clear(); contextmenu->clear(); auto setup = new QAction("Setup...", contextmenu); connect(setup, &QAction::triggered, this, &TraceSmithChart::axisSetupDialog); contextmenu->addAction(setup); - contextmenu->addSection("Traces"); - // Populate context menu - for(auto t : traces) { - auto action = new QAction(t.first->name(), contextmenu); - action->setCheckable(true); - if(t.second) { - action->setChecked(true); - } - connect(action, &QAction::toggled, [=](bool active) { - enableTrace(t.first, active); - }); - contextmenu->addAction(action); - } + contextmenu->addSeparator(); auto image = new QAction("Save image...", contextmenu); contextmenu->addAction(image); @@ -320,6 +289,39 @@ void TraceSmithChart::updateContextMenu() filename += ".png"; grab().save(filename); }); + + auto createMarker = contextmenu->addAction("Add marker here"); + bool activeTraces = false; + for(auto t : traces) { + if(t.second) { + activeTraces = true; + break; + } + } + if(!activeTraces) { + createMarker->setEnabled(false); + } + connect(createMarker, &QAction::triggered, [=](){ + createMarkerAtPosition(contextmenuClickpoint); + }); + + contextmenu->addSection("Traces"); + // Populate context menu + for(auto t : traces) { + if(!supported(t.first)) { + continue; + } + auto action = new QAction(t.first->name(), contextmenu); + action->setCheckable(true); + if(t.second) { + action->setChecked(true); + } + connect(action, &QAction::toggled, [=](bool active) { + enableTrace(t.first, active); + }); + contextmenu->addAction(action); + } + contextmenu->addSeparator(); auto close = new QAction("Close", contextmenu); contextmenu->addAction(close); diff --git a/Software/PC_Application/Traces/tracesmithchart.h b/Software/PC_Application/Traces/tracesmithchart.h index 32dcd91..e5944d7 100644 --- a/Software/PC_Application/Traces/tracesmithchart.h +++ b/Software/PC_Application/Traces/tracesmithchart.h @@ -26,7 +26,7 @@ protected: QPoint dataToPixel(Trace::Data d); std::complex pixelToData(QPoint p); QPoint markerToPixel(TraceMarker *m) override; - double nearestTracePoint(Trace *t, QPoint pixel) override; + double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) override; virtual bool xCoordinateVisible(double x); //void paintEvent(QPaintEvent *event) override; diff --git a/Software/PC_Application/Traces/tracexyplot.cpp b/Software/PC_Application/Traces/tracexyplot.cpp index 12e44db..dabe146 100644 --- a/Software/PC_Application/Traces/tracexyplot.cpp +++ b/Software/PC_Application/Traces/tracexyplot.cpp @@ -229,6 +229,38 @@ void TraceXYPlot::updateContextMenu() auto setup = new QAction("Axis setup...", contextmenu); connect(setup, &QAction::triggered, this, &TraceXYPlot::axisSetupDialog); contextmenu->addAction(setup); + + contextmenu->addSeparator(); + auto image = new QAction("Save image...", contextmenu); + contextmenu->addAction(image); + connect(image, &QAction::triggered, [=]() { + auto filename = QFileDialog::getSaveFileName(nullptr, "Save plot image", "", "PNG image files (*.png)", nullptr, QFileDialog::DontUseNativeDialog); + if(filename.isEmpty()) { + // aborted selection + return; + } + if(filename.endsWith(".png")) { + filename.chop(4); + } + filename += ".png"; + grab().save(filename); + }); + + auto createMarker = contextmenu->addAction("Add marker here"); + bool activeTraces = false; + for(auto t : traces) { + if(t.second) { + activeTraces = true; + break; + } + } + if(!activeTraces) { + createMarker->setEnabled(false); + } + connect(createMarker, &QAction::triggered, [=](){ + createMarkerAtPosition(contextmenuClickpoint); + }); + for(int axis = 0;axis < 2;axis++) { if(YAxis[axis].type == YAxisType::Disabled) { continue; @@ -255,21 +287,7 @@ void TraceXYPlot::updateContextMenu() contextmenu->addAction(action); } } - contextmenu->addSeparator(); - auto image = new QAction("Save image...", contextmenu); - contextmenu->addAction(image); - connect(image, &QAction::triggered, [=]() { - auto filename = QFileDialog::getSaveFileName(nullptr, "Save plot image", "", "PNG image files (*.png)", nullptr, QFileDialog::DontUseNativeDialog); - if(filename.isEmpty()) { - // aborted selection - return; - } - if(filename.endsWith(".png")) { - filename.chop(4); - } - filename += ".png"; - grab().save(filename); - }); + contextmenu->addSeparator(); auto close = new QAction("Close", contextmenu); contextmenu->addAction(close); @@ -902,7 +920,7 @@ QPoint TraceXYPlot::markerToPixel(TraceMarker *m) return plotValueToPixel(plotPoint, 0); } -double TraceXYPlot::nearestTracePoint(Trace *t, QPoint pixel) +double TraceXYPlot::nearestTracePoint(Trace *t, QPoint pixel, double *distance) { if(!tracesAxis[0].count(t)) { // trace not enabled @@ -927,6 +945,9 @@ double TraceXYPlot::nearestTracePoint(Trace *t, QPoint pixel) if(XAxis.type == XAxisType::Distance) { closestXpos = t->distanceToTime(closestXpos); } + if(distance) { + *distance = closestDistance; + } return closestXpos; } diff --git a/Software/PC_Application/Traces/tracexyplot.h b/Software/PC_Application/Traces/tracexyplot.h index b5fdf2c..fa353f6 100644 --- a/Software/PC_Application/Traces/tracexyplot.h +++ b/Software/PC_Application/Traces/tracexyplot.h @@ -76,7 +76,7 @@ private: QPoint plotValueToPixel(QPointF plotValue, int Yaxis); QPointF pixelToPlotValue(QPoint pixel, int YAxis); QPoint markerToPixel(TraceMarker *m) override; - double nearestTracePoint(Trace *t, QPoint pixel) override; + double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) override; virtual bool xCoordinateVisible(double x); void traceDropped(Trace *t, QPoint position) override; QString mouseText(QPoint pos) override; diff --git a/Software/PC_Application/preferences.cpp b/Software/PC_Application/preferences.cpp index 7228234..2a4b662 100644 --- a/Software/PC_Application/preferences.cpp +++ b/Software/PC_Application/preferences.cpp @@ -82,6 +82,10 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) : ui->GeneralSCPIEnabled->setEnabled(false); } + connect(ui->GeneralMarkerDataGraph, &QCheckBox::toggled, [=](bool enabled) { + ui->GeneralMarkerDataGraphAll->setEnabled(enabled); + }); + // Page selection connect(ui->treeWidget, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *current, QTreeWidgetItem *) { auto name = current->text(0); @@ -128,6 +132,8 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) : p->General.graphColors.background = ui->GeneralGraphBackground->getColor(); p->General.graphColors.axis = ui->GeneralGraphAxis->getColor(); p->General.graphColors.divisions = ui->GeneralGraphDivisions->getColor(); + p->General.markerDefault.showDataOnGraphs = ui->GeneralMarkerDataGraph->isChecked(); + p->General.markerDefault.showAllData = ui->GeneralMarkerDataGraphAll->isChecked(); p->General.SCPI.enabled = ui->GeneralSCPIEnabled->isChecked(); p->General.SCPI.port = ui->GeneralSCPIPort->value(); accept(); @@ -184,6 +190,8 @@ void PreferencesDialog::setInitialGUIState() ui->GeneralGraphBackground->setColor(p->General.graphColors.background); ui->GeneralGraphAxis->setColor(p->General.graphColors.axis); ui->GeneralGraphDivisions->setColor(p->General.graphColors.divisions); + ui->GeneralMarkerDataGraph->setChecked(p->General.markerDefault.showDataOnGraphs); + ui->GeneralMarkerDataGraphAll->setChecked(p->General.markerDefault.showAllData); ui->GeneralSCPIEnabled->setChecked(p->General.SCPI.enabled); ui->GeneralSCPIPort->setValue(p->General.SCPI.port); diff --git a/Software/PC_Application/preferences.h b/Software/PC_Application/preferences.h index 5efb025..68f1d73 100644 --- a/Software/PC_Application/preferences.h +++ b/Software/PC_Application/preferences.h @@ -56,6 +56,10 @@ public: QColor axis; QColor divisions; } graphColors; + struct { + bool showDataOnGraphs; + bool showAllData; + } markerDefault; struct { bool enabled; int port; @@ -72,7 +76,7 @@ private: QString name; QVariant def; }; - const std::array descr = {{ + const std::array descr = {{ {&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true}, {&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false}, {&Startup.DefaultSweep.start, "Startup.DefaultSweep.start", 1000000.0}, @@ -98,6 +102,8 @@ private: {&General.graphColors.background, "General.graphColors.background", QColor(Qt::black)}, {&General.graphColors.axis, "General.graphColors.axis", QColor(Qt::white)}, {&General.graphColors.divisions, "General.graphColors.divisions", QColor(Qt::gray)}, + {&General.markerDefault.showDataOnGraphs, "General.MarkerDefault.ShowDataOnGraphs", true}, + {&General.markerDefault.showAllData, "General.MarkerDefault.ShowAllData", false}, {&General.SCPI.enabled, "General.SCPI.enabled", true}, {&General.SCPI.port, "General.SCPI.port", 19542}, }}; diff --git a/Software/PC_Application/preferencesdialog.ui b/Software/PC_Application/preferencesdialog.ui index b36bb01..ca2bb21 100644 --- a/Software/PC_Application/preferencesdialog.ui +++ b/Software/PC_Application/preferencesdialog.ui @@ -587,6 +587,29 @@ + + + + Marker Default Behavior + + + + + + Show data on graphs + + + + + + + Show data in all available formats + + + + + +