From bd7e9ae655c83fb9d79576063eeaffb6d7c1a99b Mon Sep 17 00:00:00 2001 From: Mikhail Svechnikov <m.svechnikov@fz-juelich.de> Date: Mon, 23 Sep 2024 12:42:18 +0200 Subject: [PATCH] add fixed step and rework adaptive step --- GUI/View/Numeric/DSpinBox.cpp | 45 +++++++++++++++++++---------------- GUI/View/Numeric/DSpinBox.h | 2 -- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/GUI/View/Numeric/DSpinBox.cpp b/GUI/View/Numeric/DSpinBox.cpp index 64948d998db..4d227946daa 100644 --- a/GUI/View/Numeric/DSpinBox.cpp +++ b/GUI/View/Numeric/DSpinBox.cpp @@ -40,21 +40,25 @@ QString toString(double val, int decimal_points = 6) "\\3\\5\\7"); } +int orderOfMagnitude(double x) +{ + if (x == 0) + return 0; + + return std::floor(std::log10(std::abs(x))); +} + } // namespace DSpinBox::DSpinBox(DoubleProperty* d) - : m_step(::step0) { replaceProperty(d); connect(this, &QAbstractSpinBox::editingFinished, [this] { ASSERT(m_property); setValue(fromDisplay()); - m_old_dir = 0; - m_step = ::step0; }); - // setSingleStep(m_property->step()); } void DSpinBox::replaceProperty(DoubleProperty* d) @@ -68,7 +72,6 @@ void DSpinBox::replaceProperty(DoubleProperty* d) setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); lineEdit()->setText(toString(m_property->dVal())); connect(d, &DoubleProperty::setAndNotifyCalled, this, &DSpinBox::updateValue); - // [this] { updateValue(); }); } setReadOnly(!m_property); updateValue(); @@ -118,22 +121,22 @@ void DSpinBox::wheelEvent(QWheelEvent* event) void DSpinBox::stepBy(int steps) { ASSERT(m_property); + const double val = m_property->dVal(); - const int new_dir = steps > 0 ? +1 : -1; - if (m_old_dir == new_dir) - m_step = std::min(m_step * (std::abs(steps) == 1 ? 1.2 : 2.) * (1 + m_step), 9.); - else if (m_old_dir == -new_dir) - m_step = std::abs(steps) == 1 ? std::max(m_step / 9, 1e-6) : m_step; - - const double fac = (steps > 0) ^ (m_property->dVal() < 0) ? 1 + m_step : 1 / (1 + m_step); - const int decimals = std::min(6, std::max(2, (int)(2 - std::log10(m_step)))); - - // std::cout << "DEBUG steps=" << steps << " m_s=" << m_step << " fac=" << fac - // << " dec=" << decimals << " old=" << m_property->dVal() - // << " new=" << m_property->dVal() * fac - // << " rnd=" << Numeric::round_decimal(m_property->dVal() * fac, decimals) - // << std::endl; - setValue(Numeric::round_decimal(m_property->dVal() * fac, decimals)); + if (m_property->limits().isLimited()) { + setValue(val + m_property->step() * steps); + return; + } - m_old_dir = new_dir; + // "step digit" is the orger of magnitude of the step. + // If it is "1", then we increment/decrement the first digit of the value. + // If it is "2", then we increment/decrement the second digit of the value and so on. + const int step_digit = 2; + const int order_of_mag = ::orderOfMagnitude(val); + // special cases: if the current value is 100 and step digit is 2, then the diminished value + // should be not 90, but 99. + const int correction = (val == std::pow(10, order_of_mag) && steps < 0) ? 1 : 0; + const double adaptive_step = std::pow(10, order_of_mag - step_digit - correction + 1); + const double step = (val == 0) ? ::step0 : adaptive_step; + setValue(val + step * steps); } diff --git a/GUI/View/Numeric/DSpinBox.h b/GUI/View/Numeric/DSpinBox.h index 4817d840291..e365c10184a 100644 --- a/GUI/View/Numeric/DSpinBox.h +++ b/GUI/View/Numeric/DSpinBox.h @@ -50,8 +50,6 @@ private: void stepBy(int steps) override; DoubleProperty* m_property; - int m_old_dir = 0; - double m_step; }; #endif // BORNAGAIN_GUI_VIEW_NUMERIC_DSPINBOX_H -- GitLab