From ec78344f88f5392ce827b2267847d5fd1d68b855 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 2 Oct 2022 20:06:52 +0100 Subject: [PATCH] Size spectrum measurements table. --- sdrgui/gui/glspectrum.cpp | 74 +++++++++++++++++++++++++++ sdrgui/gui/glspectrum.h | 6 +-- sdrgui/gui/spectrummeasurements.cpp | 79 +++++++++++++++++++++-------- sdrgui/gui/spectrummeasurements.h | 12 ++++- 4 files changed, 144 insertions(+), 27 deletions(-) diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index f65b59157..4d15f7d57 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -32,6 +32,7 @@ GLSpectrum::GLSpectrum(QWidget *parent) : m_spectrum->setMeasurements(m_measurements); m_splitter->addWidget(m_spectrum); m_splitter->addWidget(m_measurements); + m_position = SpectrumSettings::PositionBelow; QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_splitter); @@ -66,4 +67,77 @@ void GLSpectrum::setMeasurementsPosition(SpectrumSettings::MeasurementsPosition m_splitter->insertWidget(0, m_spectrum); break; } + m_position = position; +} + +void GLSpectrum::setMeasurementParams(SpectrumSettings::Measurement measurement, + int centerFrequencyOffset, int bandwidth, int chSpacing, int adjChBandwidth, + int harmonics, int peaks, bool highlight, int precision) +{ + m_spectrum->setMeasurementParams(measurement, centerFrequencyOffset, bandwidth, chSpacing, adjChBandwidth, harmonics, peaks, highlight, precision); + // Resize splitter so there's just enough space for the measurements table + // But don't use more than 50% + QList sizes = m_splitter->sizes(); + if ((sizes[0] == 0) && (sizes[1] == 0)) + { + // Initial sizing when first created + QSize s = parentWidget()->size(); + switch (m_position) + { + case SpectrumSettings::PositionAbove: + sizes[0] = m_measurements->sizeHint().height(); + sizes[1] = s.height() - sizes[0] - m_splitter->handleWidth(); + sizes[1] = std::max(sizes[1], sizes[0]); + break; + case SpectrumSettings::PositionLeft: + sizes[0] = m_measurements->sizeHint().width(); + sizes[1] = s.width() - sizes[0] - m_splitter->handleWidth(); + sizes[1] = std::max(sizes[1], sizes[0]); + break; + case SpectrumSettings::PositionBelow: + sizes[1] = m_measurements->sizeHint().height(); + sizes[0] = s.height() - sizes[1] - m_splitter->handleWidth(); + sizes[0] = std::max(sizes[0], sizes[1]); + break; + case SpectrumSettings::PositionRight: + sizes[1] = m_measurements->sizeHint().width(); + sizes[0] = s.width() - sizes[1] - m_splitter->handleWidth(); + sizes[0] = std::max(sizes[0], sizes[1]); + break; + } + } + else + { + // When measurement type is changed when already visible + int diff = 0; + switch (m_position) + { + case SpectrumSettings::PositionAbove: + diff = m_measurements->sizeHint().height() - sizes[0]; + sizes[0] += diff; + sizes[1] -= diff; + sizes[1] = std::max(sizes[1], sizes[0]); + break; + case SpectrumSettings::PositionLeft: + diff = m_measurements->sizeHint().width() - sizes[0]; + sizes[0] += diff; + sizes[1] -= diff; + sizes[1] = std::max(sizes[1], sizes[0]); + break; + case SpectrumSettings::PositionBelow: + diff = m_measurements->sizeHint().height() - sizes[1]; + sizes[1] += diff; + sizes[0] -= diff; + sizes[0] = std::max(sizes[0], sizes[1]); + break; + case SpectrumSettings::PositionRight: + diff = m_measurements->sizeHint().width() - sizes[1]; + sizes[1] += diff; + sizes[0] -= diff; + sizes[0] = std::max(sizes[0], sizes[1]); + break; + } + } + m_splitter->setSizes(sizes); + //resize(size().expandedTo(minimumSizeHint())); } diff --git a/sdrgui/gui/glspectrum.h b/sdrgui/gui/glspectrum.h index dcc0f077e..2e784e5fe 100644 --- a/sdrgui/gui/glspectrum.h +++ b/sdrgui/gui/glspectrum.h @@ -67,10 +67,7 @@ public: void setUseCalibration(bool useCalibration) { m_spectrum->setUseCalibration(useCalibration); } void setMeasurementParams(SpectrumSettings::Measurement measurement, int centerFrequencyOffset, int bandwidth, int chSpacing, int adjChBandwidth, - int harmonics, int peaks, bool highlight, int precision) - { - m_spectrum->setMeasurementParams(measurement, centerFrequencyOffset, bandwidth, chSpacing, adjChBandwidth, harmonics, peaks, highlight, precision); - } + int harmonics, int peaks, bool highlight, int precision); qint32 getSampleRate() const { return m_spectrum->getSampleRate(); } void addChannelMarker(ChannelMarker* channelMarker) { m_spectrum->addChannelMarker(channelMarker); } void removeChannelMarker(ChannelMarker* channelMarker) { m_spectrum->removeChannelMarker(channelMarker); } @@ -110,6 +107,7 @@ private: QSplitter *m_splitter; GLSpectrumView *m_spectrum; SpectrumMeasurements *m_measurements; + SpectrumSettings::MeasurementsPosition m_position; }; diff --git a/sdrgui/gui/spectrummeasurements.cpp b/sdrgui/gui/spectrummeasurements.cpp index f7bd9be33..b90d42d59 100644 --- a/sdrgui/gui/spectrummeasurements.cpp +++ b/sdrgui/gui/spectrummeasurements.cpp @@ -24,10 +24,39 @@ #include #include #include +#include #include "gui/spectrummeasurements.h" -#include +QSize SpectrumMeasurementsTable::sizeHint() const +{ + // QAbstractScrollArea::sizeHint() always returns 256x192 when sizeAdjustPolicy == AdjustIgnored + // If using AdjustToContents policy, the default sizeHint includes the stretched empty column + // which we don't want, as that prevents the Auto Stack feature from reducing it + // So we need some custom code to set size ignoring this column + int width = 0; + int height = 0; + for (int i = 0; i < columnCount() - 1; i++) { // -1 to ignore empty column at end of row + width += columnWidth(i); + } + for (int i = 0; i < rowCount(); i++) { + height += rowHeight(i); + } + + int doubleFrame = 2 * frameWidth(); + + width += verticalHeader()->width() + doubleFrame; + height += horizontalHeader()->height() + doubleFrame; + + return QSize(width, height); +} + +QSize SpectrumMeasurementsTable::minimumSizeHint() const +{ + QSize min1 = QTableWidget::minimumSizeHint(); // This seems to include vertical space for scroll bar, which we don't need + int height = horizontalHeader()->height() + 2 * frameWidth() + rowHeight(0); + return QSize(min1.width(), height); +} class SDRGUI_API UnitsDelegate : public QStyledItemDelegate { @@ -138,7 +167,6 @@ void UnitsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->drawText(option.rect.x() + option.rect.width() - 1 - sWidth, y, s); } - const QStringList SpectrumMeasurements::m_measurementColumns = { "Current", "Mean", @@ -184,7 +212,7 @@ SpectrumMeasurements::SpectrumMeasurements(QWidget *parent) : void SpectrumMeasurements::createMeasurementsTable(const QStringList &rows, const QStringList &units) { - m_table = new QTableWidget(); + m_table = new SpectrumMeasurementsTable(); m_table->horizontalHeader()->setSectionsMovable(true); m_table->verticalHeader()->setSectionsMovable(true); @@ -196,16 +224,7 @@ void SpectrumMeasurements::createMeasurementsTable(const QStringList &rows, cons item->setToolTip(m_tooltips[i]); m_table->setHorizontalHeaderItem(i, item); } - - // Cell context menu - m_table->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_table, &QTableWidget::customContextMenuRequested, this, &SpectrumMeasurements::tableContextMenu); - - m_table->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - m_table->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); - - // Fill up space at end of rows - m_table->horizontalHeader()->setSectionResizeMode(COL_EMPTY, QHeaderView::Stretch); + m_table->horizontalHeader()->setStretchLastSection(true); m_table->setRowCount(rows.size()); for (int i = 0; i < rows.size(); i++) @@ -232,16 +251,23 @@ void SpectrumMeasurements::createMeasurementsTable(const QStringList &rows, cons m_measurements.append(m); } resizeMeasurementsTable(); + + m_table->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + m_table->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + for (int i = 0; i < COL_COUNT; i++) { m_table->setItemDelegateForColumn(i, new UnitsDelegate()); } createTableMenus(); + // Cell context menu + m_table->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_table, &QTableWidget::customContextMenuRequested, this, &SpectrumMeasurements::tableContextMenu); } void SpectrumMeasurements::createPeakTable(int peaks) { - m_peakTable = new QTableWidget(); + m_peakTable = new SpectrumMeasurementsTable(); m_peakTable->horizontalHeader()->setSectionsMovable(true); QStringList columns = QStringList{"Frequency", "Power", ""}; @@ -252,6 +278,8 @@ void SpectrumMeasurements::createPeakTable(int peaks) for (int i = 0; i < columns.size(); i++) { m_peakTable->setHorizontalHeaderItem(i, new QTableWidgetItem(columns[i])); } + m_peakTable->horizontalHeader()->setStretchLastSection(true); + for (int i = 0; i < peaks; i++) { for (int j = 0; j < 3; j++) @@ -269,15 +297,12 @@ void SpectrumMeasurements::createPeakTable(int peaks) } resizePeakTable(); - m_peakTable->setItemDelegateForColumn(COL_FREQUENCY, new UnitsDelegate()); - m_peakTable->setItemDelegateForColumn(COL_POWER, new UnitsDelegate()); - - // Fill up space at end of rows - m_peakTable->horizontalHeader()->setSectionResizeMode(COL_PEAK_EMPTY, QHeaderView::Stretch); - m_peakTable->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); m_peakTable->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + m_peakTable->setItemDelegateForColumn(COL_FREQUENCY, new UnitsDelegate()); + m_peakTable->setItemDelegateForColumn(COL_POWER, new UnitsDelegate()); + // Cell context menu m_peakTable->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_peakTable, &QTableWidget::customContextMenuRequested, this, &SpectrumMeasurements::peakTableContextMenu); @@ -287,7 +312,7 @@ void SpectrumMeasurements::createTableMenus() { // Add context menu to allow hiding/showing of columns m_rowMenu = new QMenu(m_table); - for (int i = 0; i < m_table->verticalHeader()->count(); i++) + for (int i = 0; i < m_table->verticalHeader()->count() - 1; i++) // -1 to skip empty column { QString text = m_table->verticalHeaderItem(i)->text(); m_rowMenu->addAction(createCheckableItem(text, i, true, true)); @@ -495,6 +520,18 @@ void SpectrumMeasurements::setMeasurementParams(SpectrumSettings::Measurement me default: break; } + + // Set size to show full table + if (m_peakTable) + { + m_peakTable->show(); // Need to call show() so that sizeHint() is not 0,0 + resize(sizeHint()); + } + else if (m_table) + { + m_table->show(); + resize(sizeHint()); + } } } diff --git a/sdrgui/gui/spectrummeasurements.h b/sdrgui/gui/spectrummeasurements.h index 41fa5aeab..ab14999b6 100644 --- a/sdrgui/gui/spectrummeasurements.h +++ b/sdrgui/gui/spectrummeasurements.h @@ -25,6 +25,14 @@ #include "dsp/spectrumsettings.h" #include "export.h" +class SDRGUI_API SpectrumMeasurementsTable : public QTableWidget { + Q_OBJECT + +public: + virtual QSize sizeHint() const override; + virtual QSize minimumSizeHint() const override; +}; + // Displays spectrum measurements in a table class SDRGUI_API SpectrumMeasurements : public QWidget { Q_OBJECT @@ -113,12 +121,12 @@ private: SpectrumSettings::Measurement m_measurement; int m_precision; - QTableWidget *m_table; + SpectrumMeasurementsTable *m_table; QMenu *m_rowMenu; QMenu *m_columnMenu; QList m_measurements; - QTableWidget *m_peakTable; + SpectrumMeasurementsTable *m_peakTable; QBrush m_textBrush; QBrush m_redBrush;