Krita Source Code Documentation
Loading...
Searching...
No Matches
KoSliderCombo.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 SPDX-FileCopyrightText: 2007 C. Boemann <cbo@boemann.dk>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6#include "KoSliderCombo.h"
7#include "KoSliderCombo_p.h"
8
9#include <QApplication>
10#include <QSize>
11#include <QSlider>
12#include <QStyle>
13#include <QStylePainter>
14#include <QStyleOptionSlider>
15#include <QLineEdit>
16#include <QValidator>
17#include <QHBoxLayout>
18#include <QMouseEvent>
19#include <QDoubleSpinBox>
20#include <QScreen>
21
22
23#include <klocalizedstring.h>
24#include <WidgetsDebug.h>
25
27 : QComboBox(parent)
28 ,d(new KoSliderComboPrivate())
29{
30 d->thePublic = this;
31 d->minimum = 0.0;
32 d->maximum = 100.0;
33 d->decimals = 2;
34 d->container = new KoSliderComboContainer(this);
35 d->container->setAttribute(Qt::WA_WindowPropagation);
36 QStyleOptionComboBox opt;
37 opt.initFrom(this);
38// d->container->setFrameStyle(style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, this));
39
40 d->slider = new QSlider(Qt::Horizontal);
41 d->slider->setMinimum(0);
42 d->slider->setMaximum(256);
43 d->slider->setPageStep(10);
44 d->slider->setValue(0);
45 // When set to true, causes flicker on Qt 4.6. Any reason to keep it?
46 d->firstShowOfSlider = false; //true;
47
48 QHBoxLayout *layout = new QHBoxLayout(d->container);
49 layout->setContentsMargins(2, 2, 2, 2);
50 layout->setSpacing(2);
51 layout->addWidget(d->slider);
52 d->container->resize(200, 30);
53
54 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
55
56 setEditable(true);
57 setEditText(QLocale().toString(0.0, d->decimals));
58
59 connect(d->slider, SIGNAL(valueChanged(int)), SLOT(sliderValueChanged(int)));
60 connect(d->slider, SIGNAL(sliderReleased()), SLOT(sliderReleased()));
61 connect(lineEdit(), SIGNAL(editingFinished()), SLOT(lineEditFinished()));
62}
63
65{
66 delete d;
67}
68
70{
71 return minimumSizeHint();
72}
73
75{
76 QSize sh;
77
78 const QFontMetrics &fm = fontMetrics();
79 sh.setWidth(5 * fm.horizontalAdvance(QLatin1Char('8')));
80 sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
81
82 // add style and strut values
83 QStyleOptionComboBox opt;
84 opt.initFrom(this);
85 opt.subControls = QStyle::SC_All;
86 opt.editable = true;
87 sh = style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, this);
88
89 return sh;
90}
91
92void KoSliderCombo::KoSliderComboPrivate::showPopup()
93{
94 if(firstShowOfSlider) {
95 container->show(); //show container a bit early so the slider can be laid out
96 firstShowOfSlider = false;
97 }
98
99 QStyleOptionSlider opt;
100 opt.initFrom(slider);
101 opt.maximum=256;
102 opt.sliderPosition = opt.sliderValue = slider->value();
103 int hdlPos = thePublic->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle).center().x();
104
105 QStyleOptionComboBox optThis;
106 optThis.initFrom(thePublic);
107 optThis.subControls = QStyle::SC_All;
108 optThis.editable = true;
109 int arrowPos = thePublic->style()->subControlRect(QStyle::CC_ComboBox, &optThis, QStyle::SC_ComboBoxArrow).center().x();
110
111 QSize popSize = container->size();
112 QRect popupRect(thePublic->mapToGlobal(QPoint(arrowPos - hdlPos - slider->x(), thePublic->size().height())), popSize);
113
114 // Make sure the popup is not drawn outside the screen area
115 QRect screenRect = thePublic->screen()->availableGeometry();
116
117 if (popupRect.right() > screenRect.right())
118 popupRect.translate(screenRect.right() - popupRect.right(), 0);
119 if (popupRect.left() < screenRect.left())
120 popupRect.translate(screenRect.left() - popupRect.left(), 0);
121 if (popupRect.bottom() > screenRect.bottom())
122 popupRect.translate(0, -(thePublic->height() + container->height()));
123
124 container->setGeometry(popupRect);
125 container->raise();
126 container->show();
127 slider->setFocus();
128}
129
130void KoSliderCombo::KoSliderComboPrivate::hidePopup()
131{
132 container->hide();
133}
134
135void KoSliderCombo::hideEvent(QHideEvent *)
136{
137 d->hidePopup();
138}
139
141{
142 switch (e->type())
143 {
144 case QEvent::EnabledChange:
145 if (!isEnabled())
146 d->hidePopup();
147 break;
148 case QEvent::PaletteChange:
149 d->container->setPalette(palette());
150 break;
151 default:
152 break;
153 }
154 QComboBox::changeEvent(e);
155}
156
157void KoSliderCombo::paintEvent(QPaintEvent *)
158{
159 QStylePainter gc(this);
160
161 gc.setPen(palette().color(QPalette::Text));
162
163 QStyleOptionComboBox opt;
164 opt.initFrom(this);
165 opt.subControls = QStyle::SC_All;
166 opt.editable = true;
167 gc.drawComplexControl(QStyle::CC_ComboBox, opt);
168 gc.drawControl(QStyle::CE_ComboBoxLabel, opt);
169}
170
172{
173 QStyleOptionComboBox opt;
174 opt.initFrom(this);
175 opt.subControls = QStyle::SC_All;
176 opt.editable = true;
177 QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(),
178 this);
179 if (sc == QStyle::SC_ComboBoxArrow && !d->container->isVisible())
180 {
181 d->showPopup();
182 }
183 else
184 QComboBox::mousePressEvent(e);
185}
186
188{
189 if (e->key() == Qt::Key_Up) setValue(value() + d->slider->singleStep() * (maximum() - minimum()) / 256 + 0.5);
190 else if (e->key() == Qt::Key_Down) setValue(value() - d->slider->singleStep() * (maximum() - minimum()) / 256 - 0.5);
191 else QComboBox::keyPressEvent(e);
192}
193
194void KoSliderCombo::wheelEvent(QWheelEvent *e)
195{
196 if (e->angleDelta().y() > 0) setValue(value() + d->slider->singleStep() * (maximum() - minimum()) / 256 + 0.5);
197 else setValue(value() - d->slider->singleStep() * (maximum() - minimum()) / 256 - 0.5);
198}
199
200void KoSliderCombo::KoSliderComboPrivate::lineEditFinished()
201{
202 qreal value = QLocale().toDouble(thePublic->currentText());
203 slider->blockSignals(true);
204 slider->setValue(int((value - minimum) * 256 / (maximum - minimum) + 0.5));
205 slider->blockSignals(false);
206 Q_EMIT thePublic->valueChanged(value, true);
207}
208
209void KoSliderCombo::KoSliderComboPrivate::sliderValueChanged(int slidervalue)
210{
211 thePublic->setEditText(QLocale().toString(minimum + (maximum - minimum)*slidervalue/256, decimals));
212
213 qreal value = QLocale().toDouble(thePublic->currentText());
214 Q_EMIT thePublic->valueChanged(value, false);
215}
216
217void KoSliderCombo::KoSliderComboPrivate::sliderReleased()
218{
219 qreal value = QLocale().toDouble(thePublic->currentText());
220 Q_EMIT thePublic->valueChanged(value, true);
221}
222
223qreal KoSliderCombo::maximum() const
224{
225 return d->maximum;
226}
227
228qreal KoSliderCombo::minimum() const
229{
230 return d->minimum;
231}
232
233qreal KoSliderCombo::decimals() const
234{
235 return d->decimals;
236}
237
239{
240 return QLocale().toDouble(currentText());
241}
242
244{
245 d->decimals = dec;
246 if (dec == 0) lineEdit()->setValidator(new QIntValidator(this));
247 else lineEdit()->setValidator(new QDoubleValidator(this));
248}
249
251{
252 d->minimum = min;
253}
254
256{
257 d->maximum = max;
258}
259
261{
262 if(value < d->minimum)
263 value = d->minimum;
264 if(value > d->maximum)
265 value = d->maximum;
266 setEditText(QLocale().toString(value, d->decimals));
267 d->slider->blockSignals(true);
268 d->slider->setValue(int((value - d->minimum) * 256 / (d->maximum - d->minimum) + 0.5));
269 d->slider->blockSignals(false);
270 Q_EMIT valueChanged(value, true);
271}
272
273//have to include this because of Q_PRIVATE_SLOT
274#include <moc_KoSliderCombo.cpp>
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void setDecimals(int number)
void setMinimum(qreal min)
void mousePressEvent(QMouseEvent *e) override
reimplemented from QComboBox
void setValue(qreal value)
void wheelEvent(QWheelEvent *e) override
reimplemented from QComboBox
void hideEvent(QHideEvent *) override
reimplemented from QComboBox
QSize sizeHint() const override
reimplemented from QComboBox
KoSliderComboPrivate *const d
void lineEditFinished()
void sliderReleased()
void changeEvent(QEvent *e) override
reimplemented from QComboBox
void setMaximum(qreal max)
~KoSliderCombo() override
qreal value() const
void valueChanged(qreal value, bool final)
KoSliderCombo(QWidget *parent=0)
QSize minimumSizeHint() const override
reimplemented from QComboBox
void sliderValueChanged(int value)
void paintEvent(QPaintEvent *) override
reimplemented from QComboBox
void keyPressEvent(QKeyEvent *e) override
reimplemented from QComboBox
QString toString(const QString &value)
rgba palette[MAX_PALETTE]
Definition palette.c:35