File indexing completed on 2024-05-12 04:33:22
0001 /* 0002 * SPDX-FileCopyrightText: 2007-2011 Kare Sars <kare.sars@iki .fi> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 // Local includes 0008 #include "labeledfslider.h" 0009 0010 //KDE includes 0011 0012 #include <KLocalizedString> 0013 0014 #define FLOAT_MULTIP 32768.0 0015 #define TO_DOUBLE(v) (static_cast<double>(v) / FLOAT_MULTIP) 0016 #define TO_FIX(v) (static_cast<int>(v * FLOAT_MULTIP)) 0017 0018 namespace KSaneIface 0019 { 0020 0021 LabeledFSlider::LabeledFSlider(QWidget *parent, const QString <ext, 0022 double min, double max, double step) 0023 : KSaneOptionWidget(parent, ltext) 0024 { 0025 initFSlider(min, max, step); 0026 } 0027 0028 LabeledFSlider::LabeledFSlider(QWidget *parent, KSaneCore::Option *option) 0029 : KSaneOptionWidget(parent, option) 0030 { 0031 double maxValue = option->maximumValue().toDouble(); 0032 double minValue = option->minimumValue().toDouble(); 0033 double stepValue = option->stepValue().toDouble(); 0034 initFSlider(minValue, maxValue , stepValue); 0035 0036 QString unitSuffix; 0037 KSaneCore::Option::OptionUnit unit = option->valueUnit(); 0038 switch (unit) { 0039 case KSaneCore::Option::UnitPixel: 0040 unitSuffix = i18nc("Double numbers. SpinBox parameter unit", " Pixels"); 0041 break; 0042 case KSaneCore::Option::UnitBit: 0043 unitSuffix = i18nc("Double numbers. SpinBox parameter unit", " Bits"); 0044 break; 0045 case KSaneCore::Option::UnitMilliMeter: 0046 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Millimeter)", " mm"); 0047 break; 0048 case KSaneCore::Option::UnitDPI: 0049 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Dots Per Inch)", " DPI"); 0050 break; 0051 case KSaneCore::Option::UnitPercent: 0052 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Percentage)", " %"); 0053 break; 0054 case KSaneCore::Option::UnitMicroSecond: 0055 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Microseconds)", " µs"); 0056 break; 0057 case KSaneCore::Option::UnitSecond: 0058 unitSuffix = i18nc("SpinBox parameter unit (seconds), float", " s"); 0059 break; 0060 default: 0061 unitSuffix = QString(); 0062 break; 0063 } 0064 setSuffix(unitSuffix); 0065 0066 setLabelText(option->title()); 0067 setToolTip(option->description()); 0068 connect(this, &LabeledFSlider::valueChanged, option, &KSaneCore::Option::setValue); 0069 connect(option, &KSaneCore::Option::valueChanged, this, &LabeledFSlider::setValue); 0070 double value = option->value().toDouble(); 0071 setValue(value); 0072 } 0073 0074 void LabeledFSlider::initFSlider(double minValue, double maxValue, double stepValue) 0075 { 0076 int imin = TO_FIX(minValue); 0077 int imax = TO_FIX(maxValue); 0078 m_istep = TO_FIX(stepValue); 0079 m_fstep = stepValue; 0080 if (m_istep == 0) { 0081 m_istep = 1; 0082 m_fstep = TO_DOUBLE(m_istep); 0083 } 0084 0085 //std::cout << "min=" << min << ", max=" << max << ", m_fstep="<<m_fstep<<std::endl; 0086 //std::cout << "imin=" << imin << ", imax=" << imax << ", m_istep="<<m_istep<<std::endl; 0087 m_slider = new QSlider(this); 0088 m_slider->setOrientation(Qt::Horizontal); 0089 m_slider->setMinimum(imin); 0090 m_slider->setMaximum(imax); 0091 m_slider->setSingleStep(m_istep); 0092 m_slider->setValue(imin); 0093 0094 m_spinb = new QDoubleSpinBox(this); 0095 m_spinb->setMinimum(minValue); 0096 m_spinb->setMaximum(maxValue); 0097 m_spinb->setSingleStep(m_fstep); 0098 int decimals = 0; 0099 double tmp_step = m_fstep; 0100 while (tmp_step < 1) { 0101 tmp_step *= 10; 0102 decimals++; 0103 if (decimals > 5) { 0104 break; 0105 } 0106 } 0107 m_spinb->setDecimals(decimals); 0108 m_spinb->setValue(maxValue); 0109 //m_spinb->setMinimumWidth(m_spinb->sizeHint().width()+35); 0110 m_spinb->setMinimumWidth(m_spinb->sizeHint().width()); 0111 m_spinb->setAlignment(Qt::AlignRight); 0112 m_spinb->setValue(minValue); 0113 0114 m_label->setBuddy(m_spinb); 0115 0116 connect(m_spinb, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, QOverload<double>::of(&LabeledFSlider::syncValues)); 0117 connect(m_slider, QOverload<int>::of(&QSlider::valueChanged), this, QOverload<int>::of(&LabeledFSlider::syncValues)); 0118 connect(m_slider, &QSlider::sliderReleased, this, &LabeledFSlider::fixValue); 0119 0120 m_layout->addWidget(m_slider, 0, 2); 0121 m_layout->addWidget(m_spinb, 0, 1); 0122 m_layout->setColumnStretch(1, 0); 0123 m_layout->setColumnStretch(2, 50); 0124 m_layout->activate(); 0125 } 0126 0127 LabeledFSlider::~LabeledFSlider() 0128 { 0129 } 0130 0131 double LabeledFSlider::value() const 0132 { 0133 return m_spinb->value(); 0134 } 0135 0136 double LabeledFSlider::step() const 0137 { 0138 return m_fstep; 0139 } 0140 0141 void LabeledFSlider::setSuffix(const QString &text) 0142 { 0143 m_spinb->setSuffix(text); 0144 } 0145 0146 void LabeledFSlider::setRange(double min, double max) 0147 { 0148 //qCDebug(KSANE_LOG) << "min,max(" << m_spinb->minimum() << " - " << m_spinb->maximum(); 0149 //qCDebug(KSANE_LOG) << ") -> (" << min << " - " << max << ")" << std::endl; 0150 int imin = TO_FIX(min); 0151 int imax = TO_FIX(max); 0152 m_slider->setRange(imin, imax); 0153 //std::cout << "fixedmin=" << imin << " fixedmax=" << imax << std::endl; 0154 0155 m_spinb->setRange(min, max); 0156 } 0157 0158 void LabeledFSlider::setStep(double step) 0159 { 0160 m_istep = TO_FIX(step); 0161 m_fstep = step; 0162 if (m_istep == 0) { 0163 m_istep = 1; 0164 m_fstep = TO_DOUBLE(m_istep); 0165 } 0166 m_slider->setSingleStep(m_istep); 0167 m_spinb->setSingleStep(m_fstep); 0168 0169 int decimals = 0; 0170 double tmp_step = m_fstep; 0171 while (tmp_step < 1) { 0172 tmp_step *= 10; 0173 decimals++; 0174 if (decimals > 5) { 0175 break; 0176 } 0177 } 0178 m_spinb->setDecimals(decimals); 0179 } 0180 0181 void LabeledFSlider::setValue(const QVariant &value) 0182 { 0183 bool ok; 0184 double newValue = value.toDouble(&ok); 0185 if (!ok) { 0186 return; 0187 } 0188 int ivalue = TO_FIX(newValue); 0189 0190 if (((newValue - m_spinb->value()) > m_fstep) || ((m_spinb->value() - newValue) > m_fstep)) { 0191 m_spinb->setValue(newValue); 0192 } else if (ivalue != m_slider->value()) { 0193 m_slider->setValue(ivalue); 0194 } 0195 } 0196 0197 void LabeledFSlider::syncValues(int ivalue) 0198 { 0199 double value = TO_DOUBLE(ivalue); 0200 if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) { 0201 m_spinb->setValue(value); 0202 } else if (ivalue != m_slider->value()) { 0203 m_slider->setValue(ivalue); 0204 } else { 0205 Q_EMIT valueChanged(value); 0206 } 0207 } 0208 0209 void LabeledFSlider::syncValues(double value) 0210 { 0211 int ivalue = TO_FIX(value); 0212 if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) { 0213 m_spinb->setValue(value); 0214 } else if (ivalue != m_slider->value()) { 0215 m_slider->setValue(ivalue); 0216 } else { 0217 Q_EMIT valueChanged((float)value); 0218 } 0219 } 0220 0221 void LabeledFSlider::fixValue() 0222 { 0223 //ensure that the value step is followed also for the m_slider 0224 int rest = (m_slider->value() - m_slider->minimum()) % m_istep; 0225 0226 if (rest != 0) { 0227 if (rest > (m_istep / 2)) { 0228 m_slider->setValue(m_slider->value() + (m_istep - rest)); 0229 } else { 0230 m_slider->setValue(m_slider->value() - rest); 0231 } 0232 m_spinb->setValue(TO_DOUBLE(m_slider->value())); 0233 } 0234 } 0235 0236 } // NameSpace KSaneIface 0237 0238 #include "moc_labeledfslider.cpp"