KSane

labeledfslider.cpp
1/*
2 * SPDX-FileCopyrightText: 2007-2011 Kare Sars <kare.sars@iki .fi>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7// Local includes
8#include "labeledfslider.h"
9
10//KDE includes
11
12#include <KLocalizedString>
13
14#define FLOAT_MULTIP 32768.0
15#define TO_DOUBLE(v) (static_cast<double>(v) / FLOAT_MULTIP)
16#define TO_FIX(v) (static_cast<int>(v * FLOAT_MULTIP))
17
18namespace KSaneIface
19{
20
22 double min, double max, double step)
23 : KSaneOptionWidget(parent, ltext)
24{
25 initFSlider(min, max, step);
26}
27
29 : KSaneOptionWidget(parent, option)
30{
31 double maxValue = option->maximumValue().toDouble();
32 double minValue = option->minimumValue().toDouble();
33 double stepValue = option->stepValue().toDouble();
34 initFSlider(minValue, maxValue , stepValue);
35
36 QString unitSuffix;
38 switch (unit) {
39 case KSaneCore::Option::UnitPixel:
40 unitSuffix = i18nc("Double numbers. SpinBox parameter unit", " Pixels");
41 break;
42 case KSaneCore::Option::UnitBit:
43 unitSuffix = i18nc("Double numbers. SpinBox parameter unit", " Bits");
44 break;
45 case KSaneCore::Option::UnitMilliMeter:
46 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Millimeter)", " mm");
47 break;
48 case KSaneCore::Option::UnitDPI:
49 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Dots Per Inch)", " DPI");
50 break;
51 case KSaneCore::Option::UnitPercent:
52 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Percentage)", " %");
53 break;
54 case KSaneCore::Option::UnitMicroSecond:
55 unitSuffix = i18nc("Double numbers. SpinBox parameter unit (Microseconds)", " µs");
56 break;
57 case KSaneCore::Option::UnitSecond:
58 unitSuffix = i18nc("SpinBox parameter unit (seconds), float", " s");
59 break;
60 default:
61 unitSuffix = QString();
62 break;
63 }
64 setSuffix(unitSuffix);
65
66 setLabelText(option->title());
67 setToolTip(option->description());
70 double value = option->value().toDouble();
72}
73
74void LabeledFSlider::initFSlider(double minValue, double maxValue, double stepValue)
75{
76 int imin = TO_FIX(minValue);
77 int imax = TO_FIX(maxValue);
78 m_istep = TO_FIX(stepValue);
79 m_fstep = stepValue;
80 if (m_istep == 0) {
81 m_istep = 1;
82 m_fstep = TO_DOUBLE(m_istep);
83 }
84
85 //std::cout << "min=" << min << ", max=" << max << ", m_fstep="<<m_fstep<<std::endl;
86 //std::cout << "imin=" << imin << ", imax=" << imax << ", m_istep="<<m_istep<<std::endl;
87 m_slider = new QSlider(this);
89 m_slider->setMinimum(imin);
90 m_slider->setMaximum(imax);
91 m_slider->setSingleStep(m_istep);
92 m_slider->setValue(imin);
93
94 m_spinb = new QDoubleSpinBox(this);
95 m_spinb->setMinimum(minValue);
96 m_spinb->setMaximum(maxValue);
97 m_spinb->setSingleStep(m_fstep);
98 int decimals = 0;
99 double tmp_step = m_fstep;
100 while (tmp_step < 1) {
101 tmp_step *= 10;
102 decimals++;
103 if (decimals > 5) {
104 break;
105 }
106 }
107 m_spinb->setDecimals(decimals);
108 m_spinb->setValue(maxValue);
109 //m_spinb->setMinimumWidth(m_spinb->sizeHint().width()+35);
110 m_spinb->setMinimumWidth(m_spinb->sizeHint().width());
112 m_spinb->setValue(minValue);
113
114 m_label->setBuddy(m_spinb);
115
116 connect(m_spinb, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, QOverload<double>::of(&LabeledFSlider::syncValues));
117 connect(m_slider, QOverload<int>::of(&QSlider::valueChanged), this, QOverload<int>::of(&LabeledFSlider::syncValues));
118 connect(m_slider, &QSlider::sliderReleased, this, &LabeledFSlider::fixValue);
119
120 m_layout->addWidget(m_slider, 0, 2);
121 m_layout->addWidget(m_spinb, 0, 1);
122 m_layout->setColumnStretch(1, 0);
123 m_layout->setColumnStretch(2, 50);
124 m_layout->activate();
125}
126
127LabeledFSlider::~LabeledFSlider()
128{
129}
130
132{
133 return m_spinb->value();
134}
135
136double LabeledFSlider::step() const
137{
138 return m_fstep;
139}
140
142{
143 m_spinb->setSuffix(text);
144}
145
146void LabeledFSlider::setRange(double min, double max)
147{
148 //qCDebug(KSANE_LOG) << "min,max(" << m_spinb->minimum() << " - " << m_spinb->maximum();
149 //qCDebug(KSANE_LOG) << ") -> (" << min << " - " << max << ")" << std::endl;
150 int imin = TO_FIX(min);
151 int imax = TO_FIX(max);
152 m_slider->setRange(imin, imax);
153 //std::cout << "fixedmin=" << imin << " fixedmax=" << imax << std::endl;
154
155 m_spinb->setRange(min, max);
156}
157
158void LabeledFSlider::setStep(double step)
159{
160 m_istep = TO_FIX(step);
161 m_fstep = step;
162 if (m_istep == 0) {
163 m_istep = 1;
164 m_fstep = TO_DOUBLE(m_istep);
165 }
166 m_slider->setSingleStep(m_istep);
167 m_spinb->setSingleStep(m_fstep);
168
169 int decimals = 0;
170 double tmp_step = m_fstep;
171 while (tmp_step < 1) {
172 tmp_step *= 10;
173 decimals++;
174 if (decimals > 5) {
175 break;
176 }
177 }
178 m_spinb->setDecimals(decimals);
179}
180
182{
183 bool ok;
184 double newValue = value.toDouble(&ok);
185 if (!ok) {
186 return;
187 }
188 int ivalue = TO_FIX(newValue);
189
190 if (((newValue - m_spinb->value()) > m_fstep) || ((m_spinb->value() - newValue) > m_fstep)) {
191 m_spinb->setValue(newValue);
192 } else if (ivalue != m_slider->value()) {
193 m_slider->setValue(ivalue);
194 }
195}
196
197void LabeledFSlider::syncValues(int ivalue)
198{
199 double value = TO_DOUBLE(ivalue);
200 if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) {
201 m_spinb->setValue(value);
202 } else if (ivalue != m_slider->value()) {
203 m_slider->setValue(ivalue);
204 } else {
206 }
207}
208
209void LabeledFSlider::syncValues(double value)
210{
211 int ivalue = TO_FIX(value);
212 if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) {
213 m_spinb->setValue(value);
214 } else if (ivalue != m_slider->value()) {
215 m_slider->setValue(ivalue);
216 } else {
217 Q_EMIT valueChanged((float)value);
218 }
219}
220
221void LabeledFSlider::fixValue()
222{
223 //ensure that the value step is followed also for the m_slider
224 int rest = (m_slider->value() - m_slider->minimum()) % m_istep;
225
226 if (rest != 0) {
227 if (rest > (m_istep / 2)) {
228 m_slider->setValue(m_slider->value() + (m_istep - rest));
229 } else {
230 m_slider->setValue(m_slider->value() - rest);
231 }
232 m_spinb->setValue(TO_DOUBLE(m_slider->value()));
233 }
234}
235
236} // NameSpace KSaneIface
237
238#include "moc_labeledfslider.cpp"
void valueChanged(const QVariant &value)
OptionUnit valueUnit() const
QVariant minimumValue() const
bool setValue(const QVariant &value)
QVariant stepValue() const
QString title() const
QVariant value() const
QString description() const
QVariant maximumValue() const
Base class for option widgets.
LabeledFSlider(QWidget *parent, const QString &text, double min, double max, double step)
Create the slider.
void valueChanged(const QVariant &val)
Emit the slider value changes.
void setValue(const QVariant &value)
Set the slider/spinbox value.
void setSuffix(const QString &text)
Set the unit.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setMaximum(int)
void setMinimum(int)
void setOrientation(Qt::Orientation)
void setRange(int min, int max)
void setSingleStep(int)
void sliderReleased()
void setValue(int)
void valueChanged(int value)
void setAlignment(Qt::Alignment flag)
virtual QSize sizeHint() const const override
void setDecimals(int prec)
void setMaximum(double max)
void setMinimum(double min)
void setRange(double minimum, double maximum)
void setSingleStep(double val)
void setSuffix(const QString &suffix)
void setValue(double val)
void valueChanged(double d)
void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment)
void setColumnStretch(int column, int stretch)
void setBuddy(QWidget *buddy)
bool activate()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
int width() const const
AlignRight
Horizontal
double toDouble(bool *ok) const const
void setMinimumWidth(int minw)
void setToolTip(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.