Skip to content

Commit 290572e

Browse files
authored
Merge pull request miek#215 from daniestevez/annotation-comments
Display annotation comments as tooltips
2 parents 6b8a440 + 11171c8 commit 290572e

9 files changed

Lines changed: 115 additions & 3 deletions

src/inputsource.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,9 @@ void InputSource::readMetaData(const QString &filename)
340340

341341
auto label = sigmf_annotation["core:label"].toString();
342342

343-
annotationList.emplace_back(sampleRange, frequencyRange, label);
343+
auto comment = sigmf_annotation["core:comment"].toString();
344+
345+
annotationList.emplace_back(sampleRange, frequencyRange, label, comment);
344346
}
345347
}
346348
}

src/mainwindow.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ MainWindow::MainWindow()
5151
connect(dock->cursorsCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableCursors);
5252
connect(dock->scalesCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableScales);
5353
connect(dock->annosCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnotations);
54+
connect(dock->annosCheckBox, &QCheckBox::stateChanged, dock, &SpectrogramControls::enableAnnotations);
55+
connect(dock->commentsCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnotationCommentsTooltips);
5456
connect(dock->cursorSymbolsSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), plots, &PlotView::setCursorSegments);
5557

5658
// Connect dock outputs

src/plotview.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <QRadioButton>
3333
#include <QScrollBar>
3434
#include <QSpinBox>
35+
#include <QToolTip>
3536
#include <QVBoxLayout>
3637
#include "plots.h"
3738

@@ -50,6 +51,7 @@ PlotView::PlotView(InputSource *input) : cursors(this), viewRange({0, 0})
5051
enableScales(true);
5152

5253
enableAnnotations(true);
54+
enableAnnotationCommentsTooltips(true);
5355

5456
addPlot(spectrogramPlot);
5557

@@ -62,6 +64,39 @@ void PlotView::addPlot(Plot *plot)
6264
connect(plot, &Plot::repaint, this, &PlotView::repaint);
6365
}
6466

67+
void PlotView::mouseMoveEvent(QMouseEvent *event)
68+
{
69+
updateAnnotationTooltip(event);
70+
QGraphicsView::mouseMoveEvent(event);
71+
}
72+
73+
void PlotView::mouseReleaseEvent(QMouseEvent *event)
74+
{
75+
// This is used to show the tooltip again on drag release if the mouse is
76+
// hovering over an annotation.
77+
updateAnnotationTooltip(event);
78+
QGraphicsView::mouseReleaseEvent(event);
79+
}
80+
81+
void PlotView::updateAnnotationTooltip(QMouseEvent *event)
82+
{
83+
// If there are any mouse buttons pressed, we assume
84+
// that the plot is being dragged and hide the tooltip.
85+
bool isDrag = event->buttons() != Qt::NoButton;
86+
if (!annotationCommentsEnabled
87+
|| !spectrogramPlot->isAnnotationsEnabled()
88+
|| isDrag) {
89+
QToolTip::hideText();
90+
} else {
91+
QString* comment = spectrogramPlot->mouseAnnotationComment(event);
92+
if (comment != nullptr) {
93+
QToolTip::showText(event->globalPos(), *comment);
94+
} else {
95+
QToolTip::hideText();
96+
}
97+
}
98+
}
99+
65100
void PlotView::contextMenuEvent(QContextMenuEvent * event)
66101
{
67102
QMenu menu;
@@ -612,6 +647,13 @@ void PlotView::enableAnnotations(bool enabled)
612647
viewport()->update();
613648
}
614649

650+
void PlotView::enableAnnotationCommentsTooltips(bool enabled)
651+
{
652+
annotationCommentsEnabled = enabled;
653+
654+
viewport()->update();
655+
}
656+
615657
int PlotView::sampleToColumn(size_t sample)
616658
{
617659
return sample / samplesPerColumn();

src/plotview.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public slots:
4747
void enableCursors(bool enabled);
4848
void enableScales(bool enabled);
4949
void enableAnnotations(bool enabled);
50+
void enableAnnotationCommentsTooltips(bool enabled);
5051
void invalidateEvent() override;
5152
void repaint();
5253
void setCursorSegments(int segments);
@@ -55,6 +56,8 @@ public slots:
5556
void setPowerMax(int power);
5657

5758
protected:
59+
void mouseMoveEvent(QMouseEvent *event) override;
60+
void mouseReleaseEvent(QMouseEvent *event) override;
5861
void contextMenuEvent(QContextMenuEvent * event) override;
5962
void paintEvent(QPaintEvent *event) override;
6063
void resizeEvent(QResizeEvent * event) override;
@@ -80,6 +83,7 @@ public slots:
8083
double sampleRate = 0.0;
8184
bool timeScaleEnabled;
8285
int scrollZoomStepsAccumulated = 0;
86+
bool annotationCommentsEnabled;
8387

8488
void addPlot(Plot *plot);
8589
void emitTimeSelection();
@@ -91,6 +95,7 @@ public slots:
9195
void updateViewRange(bool reCenter);
9296
void updateView(bool reCenter = false, bool expanding = false);
9397
void paintTimeScale(QPainter &painter, QRect &rect, range_t<size_t> sampleRange);
98+
void updateAnnotationTooltip(QMouseEvent *event);
9499

95100
int sampleToColumn(size_t sample);
96101
size_t columnToSample(int col);

src/samplesource.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ class Annotation
3333
range_t<size_t> sampleRange;
3434
range_t<double> frequencyRange;
3535
QString label;
36+
QString comment;
3637

37-
Annotation(range_t<size_t> sampleRange, range_t<double>frequencyRange, QString label)
38-
: sampleRange(sampleRange), frequencyRange(frequencyRange), label(label) {}
38+
Annotation(range_t<size_t> sampleRange, range_t<double>frequencyRange, QString label,
39+
QString comment)
40+
: sampleRange(sampleRange), frequencyRange(frequencyRange), label(label),
41+
comment(comment) {}
3942
};
4043

4144
template<typename T>

src/spectrogramcontrols.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent
9999

100100
annosCheckBox = new QCheckBox(widget);
101101
layout->addRow(new QLabel(tr("Display Annotations:")), annosCheckBox);
102+
commentsCheckBox = new QCheckBox(widget);
103+
layout->addRow(new QLabel(tr("Display annotation comments tooltips:")), commentsCheckBox);
102104

103105
widget->setLayout(layout);
104106
setWidget(widget);
@@ -134,6 +136,7 @@ void SpectrogramControls::setDefaults()
134136
cursorSymbolsSpinBox->setValue(1);
135137

136138
annosCheckBox->setCheckState(Qt::Checked);
139+
commentsCheckBox->setCheckState(Qt::Checked);
137140

138141
// Try to set the sample rate from the last-used value
139142
QSettings settings;
@@ -235,3 +238,8 @@ void SpectrogramControls::zoomOut()
235238
{
236239
zoomLevelSlider->setValue(zoomLevelSlider->value() - 1);
237240
}
241+
242+
void SpectrogramControls::enableAnnotations(bool enabled) {
243+
// disable annotation comments checkbox when annotations are disabled
244+
commentsCheckBox->setEnabled(enabled);
245+
}

src/spectrogramcontrols.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public slots:
4444
void timeSelectionChanged(float time);
4545
void zoomIn();
4646
void zoomOut();
47+
void enableAnnotations(bool enabled);
4748

4849
private slots:
4950
void fftSizeChanged(int value);
@@ -74,4 +75,5 @@ private slots:
7475
QLabel *symbolPeriodLabel;
7576
QCheckBox *scalesCheckBox;
7677
QCheckBox *annosCheckBox;
78+
QCheckBox *commentsCheckBox;
7779
};

src/spectrogramplot.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ void SpectrogramPlot::paintAnnotations(QPainter &painter, QRect &rect, range_t<s
169169
painter.setPen(pen);
170170
QFontMetrics fm(painter.font());
171171

172+
visibleAnnotationLocations.clear();
173+
172174
for (int i = 0; i < inputSource->annotationList.size(); i++) {
173175
Annotation a = inputSource->annotationList.at(i);
174176

@@ -195,12 +197,27 @@ void SpectrogramPlot::paintAnnotations(QPainter &painter, QRect &rect, range_t<s
195197
// Draw the label 2 pixels above the box
196198
painter.drawText(x, y - 2, a.label);
197199
painter.drawRect(x, y, width, height);
200+
201+
visibleAnnotationLocations.emplace_back(a, x, y, width, height);
198202
}
199203
}
200204

201205
painter.restore();
202206
}
203207

208+
QString *SpectrogramPlot::mouseAnnotationComment(const QMouseEvent *event) {
209+
auto pos = event->pos();
210+
int mouse_x = pos.x();
211+
int mouse_y = pos.y();
212+
213+
for (auto& a : visibleAnnotationLocations) {
214+
if (a.isInside(mouse_x, mouse_y)) {
215+
return &a.annotation.comment;
216+
}
217+
}
218+
return nullptr;
219+
}
220+
204221
void SpectrogramPlot::paintMid(QPainter &painter, QRect &rect, range_t<size_t> sampleRange)
205222
{
206223
if (!inputSource || inputSource->count() == 0)
@@ -395,6 +412,11 @@ void SpectrogramPlot::enableAnnotations(bool enabled)
395412
sigmfAnnotationsEnabled = enabled;
396413
}
397414

415+
bool SpectrogramPlot::isAnnotationsEnabled(void)
416+
{
417+
return sigmfAnnotationsEnabled;
418+
}
419+
398420
bool SpectrogramPlot::tunerEnabled()
399421
{
400422
return (tunerTransform->subscriberCount() > 0);

src/spectrogramplot.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#pragma once
2121

2222
#include <QCache>
23+
#include <QString>
2324
#include <QWidget>
2425
#include "fft.h"
2526
#include "inputsource.h"
@@ -30,8 +31,10 @@
3031
#include <memory>
3132
#include <array>
3233
#include <math.h>
34+
#include <vector>
3335

3436
class TileCacheKey;
37+
class AnnotationLocation;
3538

3639
class SpectrogramPlot : public Plot
3740
{
@@ -49,6 +52,8 @@ class SpectrogramPlot : public Plot
4952
bool tunerEnabled();
5053
void enableScales(bool enabled);
5154
void enableAnnotations(bool enabled);
55+
bool isAnnotationsEnabled();
56+
QString *mouseAnnotationComment(const QMouseEvent *event);
5257

5358
public slots:
5459
void setFFTSize(int size);
@@ -62,6 +67,7 @@ public slots:
6267
static const int tileSize = 65536; // This must be a multiple of the maximum FFT size
6368

6469
std::shared_ptr<SampleSource<std::complex<float>>> inputSource;
70+
std::vector<AnnotationLocation> visibleAnnotationLocations;
6571
std::unique_ptr<FFT> fft;
6672
std::unique_ptr<float[]> window;
6773
QCache<TileCacheKey, QPixmap> pixmapCache;
@@ -110,3 +116,23 @@ class TileCacheKey
110116
int zoomLevel;
111117
size_t sample;
112118
};
119+
120+
class AnnotationLocation
121+
{
122+
public:
123+
Annotation annotation;
124+
125+
AnnotationLocation(Annotation annotation, int x, int y, int width, int height)
126+
: annotation(annotation), x(x), y(y), width(width), height(height) {}
127+
128+
bool isInside(int pos_x, int pos_y) {
129+
return (x <= pos_x) && (pos_x <= x + width)
130+
&& (y <= pos_y) && (pos_y <= y + height);
131+
}
132+
133+
private:
134+
int x;
135+
int y;
136+
int width;
137+
int height;
138+
};

0 commit comments

Comments
 (0)