From 96265dda8bc4175fdb7d1f9a37bb2d1e6eeb765a Mon Sep 17 00:00:00 2001 From: Mikhail Svechnikov <m.svechnikov@fz-juelich.de> Date: Fri, 24 Jun 2022 17:46:36 +0200 Subject: [PATCH] add SafeSpinBox --- GUI/View/Common/SafeSpinBox.cpp | 31 ++++++++++++++++ GUI/View/Common/SafeSpinBox.h | 35 +++++++++++++++++++ GUI/View/Fit/ParameterTuningDelegate.h | 2 -- GUI/View/Info/MessageBox.h | 4 --- GUI/View/Instrument/AxisPropertyEditor.cpp | 7 ++-- GUI/View/Instrument/AxisPropertyEditor.h | 3 +- .../Instrument/DetectorAlignmentEditor.cpp | 2 +- GUI/View/Instrument/DistributionEditor.cpp | 5 +-- .../Instrument/ResolutionFunctionEditor.cpp | 4 +-- GUI/View/Instrument/SphericalAxisEditor.cpp | 5 ++- GUI/View/Instrument/SphericalAxisEditor.h | 5 +-- GUI/View/Tool/WidgetUtils.cpp | 27 ++++++++------ GUI/View/Tool/WidgetUtils.h | 14 +++++--- 13 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 GUI/View/Common/SafeSpinBox.cpp create mode 100644 GUI/View/Common/SafeSpinBox.h diff --git a/GUI/View/Common/SafeSpinBox.cpp b/GUI/View/Common/SafeSpinBox.cpp new file mode 100644 index 00000000000..5693329d4e9 --- /dev/null +++ b/GUI/View/Common/SafeSpinBox.cpp @@ -0,0 +1,31 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/View/Common/DoubleLineEdit.h +//! @brief Defines class DoubleLineEdit +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "SafeSpinBox.h" +#include <QWheelEvent> + +SafeSpinBox::SafeSpinBox(bool easyScrollable, QWidget* parent) + : QSpinBox{parent} + , easyScrollable(easyScrollable) +{ + +} + +void SafeSpinBox::wheelEvent(QWheelEvent *event) +{ + if (hasFocus() || easyScrollable) + QSpinBox::wheelEvent(event); + else + event->ignore(); +} diff --git a/GUI/View/Common/SafeSpinBox.h b/GUI/View/Common/SafeSpinBox.h new file mode 100644 index 00000000000..aa388e29b45 --- /dev/null +++ b/GUI/View/Common/SafeSpinBox.h @@ -0,0 +1,35 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/View/Common/DoubleLineEdit.h +//! @brief Defines class DoubleLineEdit +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2021 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef SAFESPINBOX_H +#define SAFESPINBOX_H + +#include <QSpinBox> + +//! Spinbox that enables scrolling only on focus +//! +class SafeSpinBox : public QSpinBox +{ + Q_OBJECT +public: + explicit SafeSpinBox(bool easyScrollable = false, QWidget* parent = nullptr); + +protected: + void wheelEvent(QWheelEvent* event) override; + +private: + bool easyScrollable; +}; + +#endif // SAFESPINBOX_H diff --git a/GUI/View/Fit/ParameterTuningDelegate.h b/GUI/View/Fit/ParameterTuningDelegate.h index 45ede457b02..5f75ecaaf1c 100644 --- a/GUI/View/Fit/ParameterTuningDelegate.h +++ b/GUI/View/Fit/ParameterTuningDelegate.h @@ -19,11 +19,9 @@ #include <QItemDelegate> #include <memory> -class QDoubleSpinBox; class QHBoxLayout; class ParameterItem; class ScientificSpinBox; -class SessionItem; class ParameterTuningDelegate : public QItemDelegate { Q_OBJECT diff --git a/GUI/View/Info/MessageBox.h b/GUI/View/Info/MessageBox.h index a44b02b0893..55968caeef9 100644 --- a/GUI/View/Info/MessageBox.h +++ b/GUI/View/Info/MessageBox.h @@ -17,10 +17,6 @@ #include <QWidget> -class RealLimits; -class QDoubleSpinBox; -class QLineEdit; - namespace GUI::View::Helpers { void information(QWidget* parent, const QString& title, const QString& text, diff --git a/GUI/View/Instrument/AxisPropertyEditor.cpp b/GUI/View/Instrument/AxisPropertyEditor.cpp index ae8f660693b..b4019169c1b 100644 --- a/GUI/View/Instrument/AxisPropertyEditor.cpp +++ b/GUI/View/Instrument/AxisPropertyEditor.cpp @@ -15,6 +15,7 @@ #include "GUI/View/Instrument/AxisPropertyEditor.h" #include "GUI/Model/Descriptor/AxisProperty.h" #include "GUI/View/Common/DoubleSpinBox.h" +#include "GUI/View/Common/SafeSpinBox.h" #include "GUI/View/Tool/GroupBoxCollapser.h" #include "GUI/View/Tool/WidgetUtils.h" #include <QFormLayout> @@ -30,9 +31,9 @@ AxisPropertyEditor::AxisPropertyEditor(QWidget* parent, const QString& groupTitl auto* formLayout = new QFormLayout(this); formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); - m_nbinsSpinBox = GUI::Util::createSpinBox(formLayout, axisProperty->nbins()); - m_minSpinBox = GUI::Util::createSpinBox(formLayout, axisProperty->min()); - m_maxSpinBox = GUI::Util::createSpinBox(formLayout, axisProperty->max()); + m_nbinsSpinBox = GUI::Util::createSpinBox(axisProperty->nbins()); + m_minSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->min()); + m_maxSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->max()); GroupBoxCollapser::installIntoGroupBox(this); diff --git a/GUI/View/Instrument/AxisPropertyEditor.h b/GUI/View/Instrument/AxisPropertyEditor.h index 83c91c3902d..360dbf0ef80 100644 --- a/GUI/View/Instrument/AxisPropertyEditor.h +++ b/GUI/View/Instrument/AxisPropertyEditor.h @@ -20,6 +20,7 @@ class QSpinBox; class AxisProperty; class DoubleSpinBox; +class SafeSpinBox; //! Use this to edit an AxisProperty. //! @@ -38,7 +39,7 @@ signals: void dataChanged(); private: - QSpinBox* m_nbinsSpinBox; + SafeSpinBox* m_nbinsSpinBox; AxisProperty* m_axisProperty; DoubleSpinBox* m_minSpinBox; DoubleSpinBox* m_maxSpinBox; diff --git a/GUI/View/Instrument/DetectorAlignmentEditor.cpp b/GUI/View/Instrument/DetectorAlignmentEditor.cpp index 42ceabc8042..03736bf5444 100644 --- a/GUI/View/Instrument/DetectorAlignmentEditor.cpp +++ b/GUI/View/Instrument/DetectorAlignmentEditor.cpp @@ -63,7 +63,7 @@ DetectorAlignmentEditor::DetectorAlignmentEditor(QWidget* parent, RectangularDet DoubleSpinBox* DetectorAlignmentEditor::createSpinBox(QFormLayout* parentFormLayout, const DoubleDescriptor& d) { - auto* sb = GUI::Util::createSpinBox(parentFormLayout, d); + auto* sb = GUI::Util::createDoubleSpinBoxRow(parentFormLayout, d); connect(sb, &DoubleSpinBox::baseValueChanged, [=](double v) { if (d.get() != v) { d.set(v); diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Instrument/DistributionEditor.cpp index 662b5226e95..f9db76b7a67 100644 --- a/GUI/View/Instrument/DistributionEditor.cpp +++ b/GUI/View/Instrument/DistributionEditor.cpp @@ -19,6 +19,7 @@ #include "GUI/Support/XML/Backup.h" #include "GUI/Support/XML/Streamer.h" #include "GUI/View/Common/DoubleSpinBox.h" +#include "GUI/View/Common/SafeSpinBox.h" #include "GUI/View/Common/ScientificSpinBox.h" #include "GUI/View/Instrument/DistributionPlot.h" #include "GUI/View/Tool/GroupBoxCollapser.h" @@ -107,7 +108,7 @@ void DistributionSelector::createDistributionWidgets() DoubleSpinBox* DistributionSelector::createSpinBox(const DoubleDescriptor& d) { - auto* sb = GUI::Util::createSpinBox(m_formLayout, d); + auto* sb = GUI::Util::createDoubleSpinBoxRow(m_formLayout, d); connect(sb, &DoubleSpinBox::baseValueChanged, [=](double v) { d.set(v); emit distributionChanged(); @@ -117,7 +118,7 @@ DoubleSpinBox* DistributionSelector::createSpinBox(const DoubleDescriptor& d) QSpinBox* DistributionSelector::createSpinBox(const UIntDescriptor& d) { - auto* sb = GUI::Util::createSpinBox(m_formLayout, d); + auto* sb = GUI::Util::createSpinBoxRow(m_formLayout, d); connect(sb, QOverload<int>::of(&QSpinBox::valueChanged), [=](int v) { d.set(v); emit distributionChanged(); diff --git a/GUI/View/Instrument/ResolutionFunctionEditor.cpp b/GUI/View/Instrument/ResolutionFunctionEditor.cpp index 4e9bd28e4fd..eaf948dc3b3 100644 --- a/GUI/View/Instrument/ResolutionFunctionEditor.cpp +++ b/GUI/View/Instrument/ResolutionFunctionEditor.cpp @@ -50,8 +50,8 @@ void ResolutionFunctionEditor::createResolutionWidgets() auto* resFunction = m_item->resolutionFunctionSelection().currentItem(); if (auto* p = dynamic_cast<ResolutionFunction2DGaussianItem*>(resFunction)) { - auto* sigmaXSpinBox = GUI::Util::createSpinBox(m_formLayout, p->sigmaX()); - auto* sigmaYSpinBox = GUI::Util::createSpinBox(m_formLayout, p->sigmaY()); + auto* sigmaXSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaX()); + auto* sigmaYSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaY()); connect(sigmaXSpinBox, qOverload<double>(&DoubleSpinBox::baseValueChanged), [=](double newValue) { diff --git a/GUI/View/Instrument/SphericalAxisEditor.cpp b/GUI/View/Instrument/SphericalAxisEditor.cpp index 87429e22469..d5a184c4685 100644 --- a/GUI/View/Instrument/SphericalAxisEditor.cpp +++ b/GUI/View/Instrument/SphericalAxisEditor.cpp @@ -13,17 +13,16 @@ // ************************************************************************************************ #include "GUI/View/Instrument/SphericalAxisEditor.h" +#include "GUI/View/Common/SafeSpinBox.h" #include "GUI/Model/Device/AxesItems.h" -#include <QDoubleSpinBox> #include <QFormLayout> #include <QGroupBox> -#include <QSpinBox> SphericalAxisForm::SphericalAxisForm(QFormLayout* form, QWidget* parent) : QObject(parent) , m_item(nullptr) { - m_nbinsSpinBox = new QSpinBox(parent); + m_nbinsSpinBox = new SafeSpinBox(false); m_nbinsSpinBox->setRange(1, 65536); connect(m_nbinsSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, &SphericalAxisForm::onNbinsValueChanged); diff --git a/GUI/View/Instrument/SphericalAxisEditor.h b/GUI/View/Instrument/SphericalAxisEditor.h index 5a8d6ef22b6..744f150a62c 100644 --- a/GUI/View/Instrument/SphericalAxisEditor.h +++ b/GUI/View/Instrument/SphericalAxisEditor.h @@ -20,7 +20,8 @@ class BasicAxisItem; class QDoubleSpinBox; class QFormLayout; -class QSpinBox; +class SafeSpinBox; + /// The form for a spherical axis: contains the bare bone widgets for the user to enter /// the number of bins and to select the range in degrees (minimum & maximum) @@ -45,7 +46,7 @@ private slots: void onMaximumValueChanged(double value); private: - QSpinBox* m_nbinsSpinBox; + SafeSpinBox* m_nbinsSpinBox; QDoubleSpinBox* m_minimumSpinBox; QDoubleSpinBox* m_maximumSpinBox; BasicAxisItem* m_item; diff --git a/GUI/View/Tool/WidgetUtils.cpp b/GUI/View/Tool/WidgetUtils.cpp index 236fcc1490e..61cdfac908d 100644 --- a/GUI/View/Tool/WidgetUtils.cpp +++ b/GUI/View/Tool/WidgetUtils.cpp @@ -16,6 +16,7 @@ #include "GUI/Model/Descriptor/UIntDescriptor.h" #include "GUI/View/Common/DoubleSpinBox.h" #include "GUI/View/Common/ScientificSpinBox.h" +#include "GUI/View/Common/SafeSpinBox.h" #include "GUI/View/Tool/EditUtil.h" #include <QFormLayout> #include <QLabel> @@ -23,10 +24,11 @@ #include <QCheckBox> #include <QLineEdit> -QSpinBox* GUI::Util::createSpinBox(QWidget* parent, const UIntDescriptor& d, - std::function<void(uint)> slot) +SafeSpinBox* GUI::Util::createSpinBox(const UIntDescriptor& d, + std::function<void(uint)> slot, + bool easyScrollable) { - auto* spinBox = new QSpinBox(parent); + auto* spinBox = new SafeSpinBox(easyScrollable); spinBox->setFocusPolicy(Qt::StrongFocus); spinBox->setToolTip(d.tooltip); spinBox->setMaximum(std::numeric_limits<int>::max()); @@ -46,8 +48,17 @@ QSpinBox* GUI::Util::createSpinBox(QWidget* parent, const UIntDescriptor& d, return spinBox; } -DoubleSpinBox* GUI::Util::createSpinBox(QFormLayout* parentLayout, const DoubleDescriptor& d, - std::function<void(double)> slot) +SafeSpinBox* GUI::Util::createSpinBoxRow(QFormLayout* parentLayout, + const UIntDescriptor& d) +{ + auto* sb = createSpinBox(d); + parentLayout->addRow(labelWithUnit(d.label, d.unit) + ":", sb); + return sb; +} + +DoubleSpinBox* GUI::Util::createDoubleSpinBoxRow(QFormLayout* parentLayout, + const DoubleDescriptor& d, + std::function<void(double)> slot) { auto* sb = new DoubleSpinBox(parentLayout->parentWidget(), d); parentLayout->addRow(labelWithUnit(d.label, d.unit) + ":", sb); @@ -58,12 +69,6 @@ DoubleSpinBox* GUI::Util::createSpinBox(QFormLayout* parentLayout, const DoubleD return sb; } -QSpinBox* GUI::Util::createSpinBox(QFormLayout* parentLayout, const UIntDescriptor& d) -{ - auto* sb = createSpinBox(parentLayout->parentWidget(), d); - parentLayout->addRow(labelWithUnit(d.label, d.unit) + ":", sb); - return sb; -} QString GUI::Util::labelWithUnit(const QString& label, variant<QString, Unit> unit) { diff --git a/GUI/View/Tool/WidgetUtils.h b/GUI/View/Tool/WidgetUtils.h index cd3d36f5ab5..748dcbe0d3b 100644 --- a/GUI/View/Tool/WidgetUtils.h +++ b/GUI/View/Tool/WidgetUtils.h @@ -22,6 +22,7 @@ #include <variant> class QSpinBox; +class SafeSpinBox; class QCheckBox; class UIntDescriptor; class DoubleSpinBox; @@ -91,15 +92,17 @@ QComboBox* createComboBox(SelectionDescriptor<T> d, //! No connections to update the descriptor will be established! Therefore changes in the spin box //! will *not* be notified to the descriptor. The additional (and optional) slot can be used to be //! notified about a value change. -QSpinBox* createSpinBox(QWidget* parent, const UIntDescriptor& d, - std::function<void(uint)> slot = nullptr); +SafeSpinBox* createSpinBox(const UIntDescriptor& d, + std::function<void(uint)> slot = nullptr, + bool easyScrollable = false); //! Create a label and a spin box with the information found in a UIntDescriptor and place them in a //! row in a form layout. //! //! The label will also contain the unit, if present. //! Regarding the spin box creation see the method above. -QSpinBox* createSpinBox(QFormLayout* parentLayout, const UIntDescriptor& d); +SafeSpinBox* createSpinBoxRow(QFormLayout* parentLayout, + const UIntDescriptor& d); //! Create a label and a spin box with the information found in a DoubleDescriptor and place them in //! a row in a form layout. @@ -113,8 +116,9 @@ QSpinBox* createSpinBox(QFormLayout* parentLayout, const UIntDescriptor& d); //! will *not* be notified to the descriptor. The additional (and optional) slot can be used to be //! notified about a value change (the notified new value is in the base unit of the //! DoubleDescriptor). -DoubleSpinBox* createSpinBox(QFormLayout* parentLayout, const DoubleDescriptor& d, - std::function<void(double)> slot = nullptr); +DoubleSpinBox* createDoubleSpinBoxRow(QFormLayout* parentLayout, + const DoubleDescriptor& d, + std::function<void(double)> slot = nullptr); //! Create a label and a scientific spin box with the information found in a DoubleDescriptor and //! place them in a row in a form layout. -- GitLab