From 9455a4c5f67a630ea811a050d975edd94025489b Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 21 Nov 2017 01:09:47 +0100 Subject: [PATCH] SSB mod/demod: improve LSB/USB experience: DSB/SSB icon shows right sideband. Filter limit sliders with ticks. Button to flip sidebands --- plugins/channelrx/demodssb/ssbdemodgui.cpp | 25 ++++++- plugins/channelrx/demodssb/ssbdemodgui.h | 8 ++- plugins/channelrx/demodssb/ssbdemodgui.ui | 44 +++++++++++- plugins/channelrx/demodssb/ssbplugin.cpp | 2 +- plugins/channeltx/modssb/ssbmodgui.cpp | 21 +++++- plugins/channeltx/modssb/ssbmodgui.h | 6 ++ plugins/channeltx/modssb/ssbmodgui.ui | 42 ++++++++++- plugins/channeltx/modssb/ssbmodplugin.cpp | 2 +- sdrgui/CMakeLists.txt | 2 + sdrgui/gui/tickedslider.cpp | 78 +++++++++++++++++++++ sdrgui/gui/tickedslider.h | 39 +++++++++++ sdrgui/resources/flip_sidebands.png | Bin 0 -> 735 bytes sdrgui/resources/res.qrc | 1 + 13 files changed, 258 insertions(+), 12 deletions(-) create mode 100644 sdrgui/gui/tickedslider.cpp create mode 100644 sdrgui/gui/tickedslider.h create mode 100644 sdrgui/resources/flip_sidebands.png diff --git a/plugins/channelrx/demodssb/ssbdemodgui.cpp b/plugins/channelrx/demodssb/ssbdemodgui.cpp index 92f1bc1b7..2b98415f6 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.cpp +++ b/plugins/channelrx/demodssb/ssbdemodgui.cpp @@ -1,10 +1,10 @@ +#include + #include "ssbdemodgui.h" #include "ssbdemodgui.h" #include #include "device/deviceuiset.h" -#include -#include #include "ui_ssbdemodgui.h" #include "dsp/spectrumvis.h" @@ -107,8 +107,9 @@ void SSBDemodGUI::on_audioFlipChannels_toggled(bool flip) applySettings(); } -void SSBDemodGUI::on_dsb_toggled(bool dsb __attribute__((unused))) +void SSBDemodGUI::on_dsb_toggled(bool dsb) { + ui->flipSidebands->setEnabled(!dsb); applyBandwidths(); } @@ -187,6 +188,14 @@ void SSBDemodGUI::on_spanLog2_valueChanged(int value) applyBandwidths(); } +void SSBDemodGUI::on_flipSidebands_clicked(bool checked __attribute__((unused))) +{ + int bwValue = ui->BW->value(); + int lcValue = ui->lowCut->value(); + ui->BW->setValue(-bwValue); + ui->lowCut->setValue(-lcValue); +} + void SSBDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) { } @@ -251,6 +260,11 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); + m_iconDSBUSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On); + m_iconDSBUSB.addPixmap(QPixmap("://usb.png"), QIcon::Normal, QIcon::Off); + m_iconDSBLSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On); + m_iconDSBLSB.addPixmap(QPixmap("://lsb.png"), QIcon::Normal, QIcon::Off); + displaySettings(); applyBandwidths(true); // does applySettings(true) } @@ -373,6 +387,7 @@ void SSBDemodGUI::applyBandwidths(bool force) bool wasBlocked = blockApplySettings(true); m_channelMarker.setBandwidth(bw * 200); m_channelMarker.setSidebands(dsb ? ChannelMarker::dsb : bw < 0 ? ChannelMarker::lsb : ChannelMarker::usb); + ui->dsb->setIcon(bw < 0 ? m_iconDSBLSB: m_iconDSBUSB); if (!dsb) { m_channelMarker.setLowCutoff(lw * 100); } blockApplySettings(wasBlocked); } @@ -385,13 +400,17 @@ void SSBDemodGUI::displaySettings() m_channelMarker.setBandwidth(m_settings.m_rfBandwidth * 2); m_channelMarker.setLowCutoff(m_settings.m_lowCutoff); + ui->flipSidebands->setEnabled(!m_settings.m_dsb); + if (m_settings.m_dsb) { m_channelMarker.setSidebands(ChannelMarker::dsb); } else { if (m_settings.m_rfBandwidth < 0) { m_channelMarker.setSidebands(ChannelMarker::lsb); + ui->dsb->setIcon(m_iconDSBLSB); } else { m_channelMarker.setSidebands(ChannelMarker::usb); + ui->dsb->setIcon(m_iconDSBUSB); } } diff --git a/plugins/channelrx/demodssb/ssbdemodgui.h b/plugins/channelrx/demodssb/ssbdemodgui.h index a54e99088..8e17379c4 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.h +++ b/plugins/channelrx/demodssb/ssbdemodgui.h @@ -1,7 +1,9 @@ #ifndef INCLUDE_SSBDEMODGUI_H #define INCLUDE_SSBDEMODGUI_H -#include +#include + +#include "plugin/plugininstancegui.h" #include "gui/rollupwidget.h" #include "dsp/channelmarker.h" #include "dsp/movingaverage.h" @@ -60,6 +62,9 @@ private: SpectrumVis* m_spectrumVis; MessageQueue m_inputMessageQueue; + QIcon m_iconDSBUSB; + QIcon m_iconDSBLSB; + explicit SSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet* deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0); virtual ~SSBDemodGUI(); @@ -89,6 +94,7 @@ private slots: void on_agcThresholdGate_valueChanged(int value); void on_audioMute_toggled(bool checked); void on_spanLog2_valueChanged(int value); + void on_flipSidebands_clicked(bool checked); void onWidgetRolled(QWidget* widget, bool rollDown); void tick(); }; diff --git a/plugins/channelrx/demodssb/ssbdemodgui.ui b/plugins/channelrx/demodssb/ssbdemodgui.ui index 47a31ee76..abd55ff25 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.ui +++ b/plugins/channelrx/demodssb/ssbdemodgui.ui @@ -205,6 +205,27 @@ + + + + Qt::Vertical + + + + + + + Flip sidebands in SSB mode (LSB->USB or USB->LSB) + + + + + + + :/flip_sidebands.png:/flip_sidebands.png + + + @@ -337,7 +358,7 @@ - + Lowpass filter cutoff frequency @@ -356,6 +377,12 @@ Qt::Horizontal + + QSlider::TicksBelow + + + 5 + @@ -404,7 +431,7 @@ - f + f: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -514,7 +541,7 @@ - + Highpass filter cutoff frequency (SSB) @@ -533,6 +560,12 @@ Qt::Horizontal + + QSlider::TicksAbove + + + 5 + @@ -893,6 +926,11 @@ QToolButton
gui/buttonswitch.h
+ + TickedSlider + QSlider +
gui/tickedslider.h
+
diff --git a/plugins/channelrx/demodssb/ssbplugin.cpp b/plugins/channelrx/demodssb/ssbplugin.cpp index 63e710335..cbb36c0fc 100644 --- a/plugins/channelrx/demodssb/ssbplugin.cpp +++ b/plugins/channelrx/demodssb/ssbplugin.cpp @@ -8,7 +8,7 @@ const PluginDescriptor SSBPlugin::m_pluginDescriptor = { QString("SSB Demodulator"), - QString("3.8.4"), + QString("3.8.5"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp index e9187a29f..0d86f82ca 100644 --- a/plugins/channeltx/modssb/ssbmodgui.cpp +++ b/plugins/channeltx/modssb/ssbmodgui.cpp @@ -150,8 +150,17 @@ void SSBModGUI::on_deltaFrequency_changed(qint64 value) applySettings(); } -void SSBModGUI::on_dsb_toggled(bool checked __attribute__((unused))) +void SSBModGUI::on_flipSidebands_clicked(bool checked __attribute__((unused))) { + int bwValue = ui->BW->value(); + int lcValue = ui->lowCut->value(); + ui->BW->setValue(-bwValue); + ui->lowCut->setValue(-lcValue); +} + +void SSBModGUI::on_dsb_toggled(bool dsb) +{ + ui->flipSidebands->setEnabled(!dsb); applyBandwidths(); } @@ -404,6 +413,11 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); connect(m_ssbMod, SIGNAL(levelChanged(qreal, qreal, int)), ui->volumeMeter, SLOT(levelChanged(qreal, qreal, int))); + m_iconDSBUSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On); + m_iconDSBUSB.addPixmap(QPixmap("://usb.png"), QIcon::Normal, QIcon::Off); + m_iconDSBLSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On); + m_iconDSBLSB.addPixmap(QPixmap("://lsb.png"), QIcon::Normal, QIcon::Off); + displaySettings(); applyBandwidths(true); // does applySettings(true) } @@ -526,6 +540,7 @@ void SSBModGUI::applyBandwidths(bool force) bool applySettingsWereBlocked = blockApplySettings(true); m_channelMarker.setBandwidth(bw * 200); m_channelMarker.setSidebands(dsb ? ChannelMarker::dsb : bw < 0 ? ChannelMarker::lsb : ChannelMarker::usb); + ui->dsb->setIcon(bw < 0 ? m_iconDSBLSB : m_iconDSBUSB); if (!dsb) { m_channelMarker.setLowCutoff(lw * 100); } blockApplySettings(applySettingsWereBlocked); } @@ -537,13 +552,17 @@ void SSBModGUI::displaySettings() m_channelMarker.setBandwidth(m_settings.m_bandwidth * 2); m_channelMarker.setLowCutoff(m_settings.m_lowCutoff); + ui->flipSidebands->setEnabled(!m_settings.m_dsb); + if (m_settings.m_dsb) { m_channelMarker.setSidebands(ChannelMarker::dsb); } else { if (m_settings.m_bandwidth < 0) { m_channelMarker.setSidebands(ChannelMarker::lsb); + ui->dsb->setIcon(m_iconDSBLSB); } else { m_channelMarker.setSidebands(ChannelMarker::usb); + ui->dsb->setIcon(m_iconDSBUSB); } } diff --git a/plugins/channeltx/modssb/ssbmodgui.h b/plugins/channeltx/modssb/ssbmodgui.h index b193ba837..ca27ab9d1 100644 --- a/plugins/channeltx/modssb/ssbmodgui.h +++ b/plugins/channeltx/modssb/ssbmodgui.h @@ -17,6 +17,8 @@ #ifndef PLUGINS_CHANNELTX_MODSSB_SSBMODGUI_H_ #define PLUGINS_CHANNELTX_MODSSB_SSBMODGUI_H_ +#include + #include #include "gui/rollupwidget.h" #include "dsp/channelmarker.h" @@ -78,6 +80,9 @@ private: SSBMod::SSBModInputAF m_modAFInput; MessageQueue m_inputMessageQueue; + QIcon m_iconDSBUSB; + QIcon m_iconDSBLSB; + explicit SSBModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = 0); virtual ~SSBModGUI(); @@ -96,6 +101,7 @@ private: private slots: void handleSourceMessages(); void on_deltaFrequency_changed(qint64 value); + void on_flipSidebands_clicked(bool checked); void on_dsb_toggled(bool checked); void on_audioBinaural_toggled(bool checked); void on_audioFlipChannels_toggled(bool checked); diff --git a/plugins/channeltx/modssb/ssbmodgui.ui b/plugins/channeltx/modssb/ssbmodgui.ui index 9fb3b6780..d73c6834d 100644 --- a/plugins/channeltx/modssb/ssbmodgui.ui +++ b/plugins/channeltx/modssb/ssbmodgui.ui @@ -205,6 +205,27 @@
+ + + + Qt::Vertical + + + + + + + Flip sidebands in SSB mode (LSB->USB or USB->LSB) + + + + + + + :/flip_sidebands.png:/flip_sidebands.png + + + @@ -301,7 +322,7 @@ - + Lowpass filter cutoff frequency @@ -320,6 +341,12 @@ Qt::Horizontal + + QSlider::TicksBelow + + + 5 + @@ -481,7 +508,7 @@ - + Highpass filter cutoff frequency (SSB) @@ -500,6 +527,12 @@ Qt::Horizontal + + QSlider::TicksAbove + + + 5 + @@ -1225,6 +1258,11 @@
gui/valuedialz.h
1 + + TickedSlider + QSlider +
gui/tickedslider.h
+
diff --git a/plugins/channeltx/modssb/ssbmodplugin.cpp b/plugins/channeltx/modssb/ssbmodplugin.cpp index e9ff58810..1a40e6dbd 100644 --- a/plugins/channeltx/modssb/ssbmodplugin.cpp +++ b/plugins/channeltx/modssb/ssbmodplugin.cpp @@ -24,7 +24,7 @@ const PluginDescriptor SSBModPlugin::m_pluginDescriptor = { QString("SSB Modulator"), - QString("3.8.4"), + QString("3.8.5"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 1e7f6c63c..5fb6e333a 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -34,6 +34,7 @@ set(sdrgui_SOURCES gui/samplingdevicedialog.cpp gui/scale.cpp gui/scaleengine.cpp + gui/tickedslider.cpp gui/transverterbutton.cpp gui/transverterdialog.cpp gui/valuedial.cpp @@ -85,6 +86,7 @@ set(sdrgui_HEADERS gui/samplingdevicedialog.h gui/scale.h gui/scaleengine.h + gui/tickedslider.h gui/transverterbutton.h gui/transverterdialog.h gui/valuedial.h diff --git a/sdrgui/gui/tickedslider.cpp b/sdrgui/gui/tickedslider.cpp new file mode 100644 index 000000000..4cbb01999 --- /dev/null +++ b/sdrgui/gui/tickedslider.cpp @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// 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 as version 3 of the License, or // +// // +// 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "tickedslider.h" + +TickedSlider::TickedSlider(QWidget* parent) : + QSlider(parent), + m_tickColor(Qt::white) +{ } + +void TickedSlider::paintEvent(QPaintEvent *ev __attribute__((unused))) +{ + + QStylePainter p(this); + QStyleOptionSlider opt; + initStyleOption(&opt); + + QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + + // draw tick marks + // do this manually because they are very badly behaved with style sheets + int interval = tickInterval(); + if (interval == 0) + { + interval = pageStep(); + } + + if (tickPosition() != NoTicks) + { + for (int i = minimum(); i <= maximum(); i += interval) + { + int x = round((double)((double)((double)(i - this->minimum()) / (double)(this->maximum() - this->minimum())) * (double)(this->width() - handle.width()) + (double)(handle.width() / 2.0))) - 1; + int h = 4; + p.setPen(m_tickColor); + if (tickPosition() == TicksBothSides || tickPosition() == TicksAbove) + { + int y = this->rect().top(); + p.drawLine(x, y, x, y + h); + } + if (tickPosition() == TicksBothSides || tickPosition() == TicksBelow) + { + int y = this->rect().bottom(); + p.drawLine(x, y, x, y - h); + } + + } + } + + // draw the slider (this is basically copy/pasted from QSlider::paintEvent) + opt.subControls = QStyle::SC_SliderGroove; + p.drawComplexControl(QStyle::CC_Slider, opt); + + // draw the slider handle + opt.subControls = QStyle::SC_SliderHandle; + p.drawComplexControl(QStyle::CC_Slider, opt); +} + + + + diff --git a/sdrgui/gui/tickedslider.h b/sdrgui/gui/tickedslider.h new file mode 100644 index 000000000..050881223 --- /dev/null +++ b/sdrgui/gui/tickedslider.h @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// 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 as version 3 of the License, or // +// // +// 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_GUI_TICKEDSLIDER_H_ +#define SDRGUI_GUI_TICKEDSLIDER_H_ + +#include +#include + +class TickedSlider : public QSlider +{ +public: + TickedSlider(QWidget* parent = 0); + void setTickColor(const QColor& color) { m_tickColor = color; } + +protected: + virtual void paintEvent(QPaintEvent *ev); + +private: + QColor m_tickColor; +}; + + +#endif /* SDRGUI_GUI_TICKEDSLIDER_H_ */ diff --git a/sdrgui/resources/flip_sidebands.png b/sdrgui/resources/flip_sidebands.png new file mode 100644 index 0000000000000000000000000000000000000000..ea28a008adf54afc9c547211c0a14ea52f1ce36e GIT binary patch literal 735 zcmV<50wDc~P)?EL%YaIX*je}iH0=85EDTB{B7znwf~FKL1TDqjs}aN) zAC-vM7zOncXeUYvgPo#+Vnnig|2A{t$?@(6SqFxlnVt8YnR}5GB-I>Kx+4Ne8kO`* z(zK*LNtWxGE1M&L{MQm1U<0t%>HB6jE9ng|?6POT81NaWxvh{?bikg3Zb+JUYPV&8x@ zPVWRB0sDbZNLnZ9o&G<}NLn3R^n>o8s>L6HR-B^E-louIf(+OQ9CZE`FzY%ifRn&L zqCW*31Lnzgz!D4@JtFD5<4CeIlag9VYc5Objed(HLu-?H!j?08S+G+rR`+ zx_&EUlcQz$91dm9kH+zgwxOLg)t^?yPziMWiBvp-K@JjOM6@w^mQ4P43I0v}#54(`J znm9$JJHH4VNMu)lOP*z!7?;VzYa9#pWfEOfp zs87=4q{IbDXZ-&{Qa!mv_3Uj|RPZ%PA)bl=EC8dxOtK^AfHB`_^LEy%7OH{|fW>ni z_o4K&dk1K^;#)HtmNewkW57M&eTUQjXW^1_9m_Ir*OY&f?D5-EROl|phu_3r(KGx! RZFv9y002ovPDHLkV1gvAJlink.png choose.png clocksource.png + flip_sidebands.png