1 /* 2 SPDX-FileCopyrightText: 2017 Robert Lancaster <rlancaste@gmail.com> 3 4 Based on an idea discussed in the QT Centre: http://www.qtcentre.org/threads/47535-QDoubleSpinBox-with-nonlinear-values 5 6 SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #include "auxiliary/nonlineardoublespinbox.h" 10 NonLinearDoubleSpinBox(QWidget * parent)11NonLinearDoubleSpinBox::NonLinearDoubleSpinBox(QWidget *parent) : QDoubleSpinBox(parent) 12 { 13 m_Values << 0.01 << 0.02 << 0.05 << 0.1 << 0.2 << 0.25 << 0.5 << 1 << 1.5 << 2 << 2.5 << 3 << 5 << 6 << 7 << 8 << 9 << 10 << 20 << 30 << 40 << 50 << 60 << 120 << 180 << 300 << 600 << 900; 14 setRange(m_Values.first() , m_Values.last()); 15 16 //This will update the _idx variable to the index of the new value. It will give -1 if not in the list, and the index if it is in the list. 17 connect(this, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), 18 [=](double d){ m_idx = m_Values.indexOf(d); }); 19 } 20 stepBy(int steps)21void NonLinearDoubleSpinBox::stepBy(int steps) 22 { 23 // If the current value is not currently in the list, it will find where the value falls in the list and set it to the 24 // appropriate one whether going up or down. 25 if(m_idx == -1) 26 { 27 int i = 0; 28 while(value() > m_Values.at(i)) 29 i++; 30 if(steps > 0 ) 31 m_idx = i; 32 else 33 m_idx = i - 1; 34 } 35 else 36 m_idx += steps; 37 38 //This makes sure that it doesn't go past the ends of the list. 39 if(m_idx<0) 40 m_idx=0; 41 else if(m_idx >= m_Values.count()) 42 m_idx = m_Values.count()-1; 43 44 //This sets the value to the value at that index in the list. 45 setValue( m_Values.at(m_idx) ); 46 } 47 setRecommendedValues(QList<double> values)48void NonLinearDoubleSpinBox::setRecommendedValues(QList<double> values) 49 { 50 m_Values = values; 51 updateRecommendedValues(); 52 } 53 addRecommendedValue(double v)54void NonLinearDoubleSpinBox::addRecommendedValue(double v) 55 { 56 m_Values.append(v); //This will be sorted into place in the next command. 57 updateRecommendedValues(); 58 } 59 updateRecommendedValues()60void NonLinearDoubleSpinBox::updateRecommendedValues() 61 { 62 std::sort(m_Values.begin(), m_Values.end()); //This will make sure they are all in order. 63 m_idx = m_Values.indexOf(value()); //This will update the _idx variable to the index of the new value. It will search for current value in the new list or set it to negative 1 if it isn't in the list. 64 setRange(m_Values.first() , m_Values.last()); 65 //This makes sure all the values are in the range. The range is expanded if necessary. 66 if(m_Values.first() < minimum()) 67 setMinimum(m_Values.first()); 68 if(m_Values.last() > maximum()) 69 setMaximum(m_Values.last()); 70 } 71 getRecommendedValues()72QList<double> NonLinearDoubleSpinBox::getRecommendedValues() 73 { 74 return m_Values; 75 } 76 getRecommendedValuesString()77QString NonLinearDoubleSpinBox::getRecommendedValuesString() 78 { 79 QString returnString; 80 for(int i=0; i < m_Values.size() - 1; i++) 81 returnString += QString::number(m_Values.at(i)) + ", "; 82 returnString += QString::number(m_Values.last()); 83 return returnString; 84 } 85