diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 5b62544bb..d524583d5 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -104,6 +104,8 @@ set(sdrgui_SOURCES gui/workspaceselectiondialog.cpp gui/wsspectrumsettingsdialog.cpp gui/wrappingdatetimeedit.cpp + gui/wrappingdial.cpp + gui/wrappingspinbox.cpp dsp/scopevisxy.cpp @@ -235,6 +237,8 @@ set(sdrgui_HEADERS gui/workspaceselectiondialog.h gui/wsspectrumsettingsdialog.h gui/wrappingdatetimeedit.h + gui/wrappingdial.h + gui/wrappingspinbox.h dsp/scopevisxy.h diff --git a/sdrgui/gui/wrappingdial.cpp b/sdrgui/gui/wrappingdial.cpp new file mode 100644 index 000000000..b21c076b3 --- /dev/null +++ b/sdrgui/gui/wrappingdial.cpp @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// 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 // +// (at your option) any later version. // +// // +// 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 "wrappingdial.h" + +#include + +WrappingDial::WrappingDial(QWidget *parent) : + QDial(parent), + m_wheelEvent(false), + m_wheelUp(false) +{ + setWrapping(true); + + connect(this, &QDial::actionTriggered, this, &WrappingDial::on_actionTriggered); +} + +void WrappingDial::on_actionTriggered(int action) +{ + if (wrapping()) + { + if ( ( (action == QAbstractSlider::SliderSingleStepSub) + || (action == QAbstractSlider::SliderPageStepSub) + || ((action == QAbstractSlider::SliderMove) && m_wheelEvent && !m_wheelUp) + ) + && (value() < sliderPosition())) + { + emit wrapDown(); + } + if ( ( (action == QAbstractSlider::SliderSingleStepAdd) + || (action == QAbstractSlider::SliderPageStepAdd) + || ((action == QAbstractSlider::SliderMove) && m_wheelEvent && m_wheelUp) + ) + && (value() > sliderPosition())) + { + emit wrapUp(); + } + } +} + +// QAbstractSlider just generates SliderMove actions for wheel events, so we can't distinguish between +// wheel and dial being clicked to a new position - so we set a flag here, before passing up the event +void WrappingDial::wheelEvent(QWheelEvent *e) +{ + m_wheelEvent = true; + m_wheelUp = e->angleDelta().y() > 0; + QDial::wheelEvent(e); + m_wheelEvent = false; +} diff --git a/sdrgui/gui/wrappingdial.h b/sdrgui/gui/wrappingdial.h new file mode 100644 index 000000000..fa3b63ff0 --- /dev/null +++ b/sdrgui/gui/wrappingdial.h @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// 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 // +// (at your option) any later version. // +// // +// 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_WRAPPINGDDIAL_H +#define SDRGUI_GUI_WRAPPINGDDIAL_H + +#include + +#include "export.h" + +// Extends QDial to generate a signal when dial wraps +class SDRGUI_API WrappingDial : public QDial { + Q_OBJECT + +public: + explicit WrappingDial(QWidget *parent = nullptr); + +protected: + void wheelEvent(QWheelEvent *e) override; + +private: + bool m_wheelEvent; + bool m_wheelUp; + +private slots: + void on_actionTriggered(int action); + +signals: + void wrapUp(); + void wrapDown(); + +}; + +#endif // SDRGUI_GUI_WRAPPINGDDIAL_H diff --git a/sdrgui/gui/wrappingspinbox.cpp b/sdrgui/gui/wrappingspinbox.cpp new file mode 100644 index 000000000..3c2c7ee23 --- /dev/null +++ b/sdrgui/gui/wrappingspinbox.cpp @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// 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 // +// (at your option) any later version. // +// // +// 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 "wrappingspinbox.h" + +#include + +WrappingSpinBox::WrappingSpinBox(QWidget *parent) : + QSpinBox(parent), + m_wheelEvent(false), + m_wheelUp(false) +{ + setWrapping(true); +} + +void WrappingSpinBox::stepBy(int steps) +{ + int v = value(); + QSpinBox::stepBy(steps); + if (wrapping()) + { + if (v + steps > maximum()) { + emit wrapUp(); + } + if (v + steps < minimum()) { + emit wrapDown(); + } + } +} + +// QAbstractSlider just generates SliderMove actions for wheel events, so we can't distinguish between +// wheel and dial being clicked to a new position - so we set a flag here, before passing up the event +void WrappingSpinBox::wheelEvent(QWheelEvent *e) +{ + m_wheelEvent = true; + m_wheelUp = e->angleDelta().y() > 0; + QSpinBox::wheelEvent(e); + m_wheelEvent = false; +} diff --git a/sdrgui/gui/wrappingspinbox.h b/sdrgui/gui/wrappingspinbox.h new file mode 100644 index 000000000..e775ecb86 --- /dev/null +++ b/sdrgui/gui/wrappingspinbox.h @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// 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 // +// (at your option) any later version. // +// // +// 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_WRAPPINGDSPINBOX_H +#define SDRGUI_GUI_WRAPPINGDSPINBOX_H + +#include + +#include "export.h" + +// Extends QSpinBox to generate a signal when spinbox wraps +class SDRGUI_API WrappingSpinBox : public QSpinBox { + Q_OBJECT + +public: + explicit WrappingSpinBox(QWidget *parent = nullptr); + + void stepBy(int steps) override; + +protected: + void wheelEvent(QWheelEvent *e) override; + +private: + bool m_wheelEvent; + bool m_wheelUp; + +signals: + void wrapUp(); + void wrapDown(); + +}; + +#endif // SDRGUI_GUI_WRAPPINGDSPINBOX_H