1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qtgradientstopscontroller.h" |
5 | #include "ui_qtgradienteditor.h" |
6 | #include "qtgradientstopsmodel.h" |
7 | |
8 | #include <QtCore/QTimer> |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | using namespace Qt::StringLiterals; |
13 | |
14 | class QtGradientStopsControllerPrivate : public QObject |
15 | { |
16 | Q_OBJECT |
17 | QtGradientStopsController *q_ptr; |
18 | Q_DECLARE_PUBLIC(QtGradientStopsController) |
19 | public: |
20 | using PositionColorMap = QMap<qreal, QColor>; |
21 | using PositionStopMap = QMap<qreal, QtGradientStop *>; |
22 | |
23 | void setUi(Ui::QtGradientEditor *ui); |
24 | |
25 | void slotHsvClicked(); |
26 | void slotRgbClicked(); |
27 | |
28 | void slotCurrentStopChanged(QtGradientStop *stop); |
29 | void slotStopMoved(QtGradientStop *stop, qreal newPos); |
30 | void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2); |
31 | void slotStopChanged(QtGradientStop *stop, const QColor &newColor); |
32 | void slotStopSelected(QtGradientStop *stop, bool selected); |
33 | void slotStopAdded(QtGradientStop *stop); |
34 | void slotStopRemoved(QtGradientStop *stop); |
35 | void slotUpdatePositionSpinBox(); |
36 | |
37 | void slotChangeColor(const QColor &color); |
38 | void slotChangeHueColor(const QColor &color); |
39 | void slotChangeSaturationColor(const QColor &color); |
40 | void slotChangeValueColor(const QColor &color); |
41 | void slotChangeAlphaColor(const QColor &color); |
42 | void slotChangeHue(int color); |
43 | void slotChangeSaturation(int color); |
44 | void slotChangeValue(int color); |
45 | void slotChangeAlpha(int color); |
46 | void slotChangePosition(double value); |
47 | |
48 | void slotChangeZoom(int value); |
49 | void slotZoomIn(); |
50 | void slotZoomOut(); |
51 | void slotZoomAll(); |
52 | void slotZoomChanged(double zoom); |
53 | |
54 | void enableCurrent(bool enable); |
55 | void setColorSpinBoxes(const QColor &color); |
56 | PositionColorMap stopsData(const PositionStopMap &stops) const; |
57 | QGradientStops makeGradientStops(const PositionColorMap &data) const; |
58 | void updateZoom(double zoom); |
59 | |
60 | QtGradientStopsModel *m_model = nullptr; |
61 | QColor::Spec m_spec = QColor::Hsv; |
62 | |
63 | Ui::QtGradientEditor *m_ui; |
64 | }; |
65 | |
66 | void QtGradientStopsControllerPrivate::setUi(Ui::QtGradientEditor *ui) |
67 | { |
68 | m_ui = ui; |
69 | |
70 | m_ui->hueColorLine->setColorComponent(QtColorLine::Hue); |
71 | m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation); |
72 | m_ui->valueColorLine->setColorComponent(QtColorLine::Value); |
73 | m_ui->alphaColorLine->setColorComponent(QtColorLine::Alpha); |
74 | |
75 | m_model = new QtGradientStopsModel(this); |
76 | m_ui->gradientStopsWidget->setGradientStopsModel(m_model); |
77 | connect(sender: m_model, signal: &QtGradientStopsModel::currentStopChanged, |
78 | context: this, slot: &QtGradientStopsControllerPrivate::slotCurrentStopChanged); |
79 | connect(sender: m_model, signal: &QtGradientStopsModel::stopMoved, |
80 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopMoved); |
81 | connect(sender: m_model, signal: &QtGradientStopsModel::stopsSwapped, |
82 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopsSwapped); |
83 | connect(sender: m_model, signal: &QtGradientStopsModel::stopChanged, |
84 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopChanged); |
85 | connect(sender: m_model, signal: &QtGradientStopsModel::stopSelected, |
86 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopSelected); |
87 | connect(sender: m_model, signal: &QtGradientStopsModel::stopAdded, |
88 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopAdded); |
89 | connect(sender: m_model, signal: &QtGradientStopsModel::stopRemoved, |
90 | context: this, slot: &QtGradientStopsControllerPrivate::slotStopRemoved); |
91 | |
92 | connect(m_ui->hueColorLine, &QtColorLine::colorChanged, |
93 | this, &QtGradientStopsControllerPrivate::slotChangeHueColor); |
94 | connect(m_ui->saturationColorLine, &QtColorLine::colorChanged, |
95 | this, &QtGradientStopsControllerPrivate::slotChangeSaturationColor); |
96 | connect(m_ui->valueColorLine, &QtColorLine::colorChanged, |
97 | this, &QtGradientStopsControllerPrivate::slotChangeValueColor); |
98 | connect(m_ui->alphaColorLine, &QtColorLine::colorChanged, |
99 | this, &QtGradientStopsControllerPrivate::slotChangeAlphaColor); |
100 | connect(m_ui->colorButton, &QtColorButton::colorChanged, |
101 | this, &QtGradientStopsControllerPrivate::slotChangeColor); |
102 | |
103 | connect(m_ui->hueSpinBox, &QSpinBox::valueChanged, |
104 | this, &QtGradientStopsControllerPrivate::slotChangeHue); |
105 | connect(m_ui->saturationSpinBox, &QSpinBox::valueChanged, |
106 | this, &QtGradientStopsControllerPrivate::slotChangeSaturation); |
107 | connect(m_ui->valueSpinBox, &QSpinBox::valueChanged, |
108 | this, &QtGradientStopsControllerPrivate::slotChangeValue); |
109 | connect(m_ui->alphaSpinBox, &QSpinBox::valueChanged, |
110 | this, &QtGradientStopsControllerPrivate::slotChangeAlpha); |
111 | |
112 | connect(m_ui->positionSpinBox, &QDoubleSpinBox::valueChanged, |
113 | this, &QtGradientStopsControllerPrivate::slotChangePosition); |
114 | |
115 | connect(m_ui->zoomSpinBox, &QSpinBox::valueChanged, |
116 | this, &QtGradientStopsControllerPrivate::slotChangeZoom); |
117 | connect(m_ui->zoomInButton, &QToolButton::clicked, |
118 | this, &QtGradientStopsControllerPrivate::slotZoomIn); |
119 | connect(m_ui->zoomOutButton, &QToolButton::clicked, |
120 | this, &QtGradientStopsControllerPrivate::slotZoomOut); |
121 | connect(m_ui->zoomAllButton, &QToolButton::clicked, |
122 | this, &QtGradientStopsControllerPrivate::slotZoomAll); |
123 | connect(m_ui->gradientStopsWidget, &QtGradientStopsWidget::zoomChanged, |
124 | this, &QtGradientStopsControllerPrivate::slotZoomChanged); |
125 | |
126 | connect(m_ui->hsvRadioButton, &QRadioButton::clicked, |
127 | this, &QtGradientStopsControllerPrivate::slotHsvClicked); |
128 | connect(m_ui->rgbRadioButton, &QRadioButton::clicked, |
129 | this, &QtGradientStopsControllerPrivate::slotRgbClicked); |
130 | |
131 | enableCurrent(enable: false); |
132 | m_ui->zoomInButton->setIcon(QIcon(":/qt-project.org/qtgradienteditor/images/zoomin.png"_L1 )); |
133 | m_ui->zoomOutButton->setIcon(QIcon(":/qt-project.org/qtgradienteditor/images/zoomout.png"_L1 )); |
134 | updateZoom(zoom: 1); |
135 | } |
136 | |
137 | void QtGradientStopsControllerPrivate::enableCurrent(bool enable) |
138 | { |
139 | m_ui->positionLabel->setEnabled(enable); |
140 | m_ui->colorLabel->setEnabled(enable); |
141 | m_ui->hLabel->setEnabled(enable); |
142 | m_ui->sLabel->setEnabled(enable); |
143 | m_ui->vLabel->setEnabled(enable); |
144 | m_ui->aLabel->setEnabled(enable); |
145 | m_ui->hueLabel->setEnabled(enable); |
146 | m_ui->saturationLabel->setEnabled(enable); |
147 | m_ui->valueLabel->setEnabled(enable); |
148 | m_ui->alphaLabel->setEnabled(enable); |
149 | |
150 | m_ui->positionSpinBox->setEnabled(enable); |
151 | m_ui->colorButton->setEnabled(enable); |
152 | |
153 | m_ui->hueColorLine->setEnabled(enable); |
154 | m_ui->saturationColorLine->setEnabled(enable); |
155 | m_ui->valueColorLine->setEnabled(enable); |
156 | m_ui->alphaColorLine->setEnabled(enable); |
157 | |
158 | m_ui->hueSpinBox->setEnabled(enable); |
159 | m_ui->saturationSpinBox->setEnabled(enable); |
160 | m_ui->valueSpinBox->setEnabled(enable); |
161 | m_ui->alphaSpinBox->setEnabled(enable); |
162 | } |
163 | |
164 | QtGradientStopsControllerPrivate::PositionColorMap QtGradientStopsControllerPrivate::stopsData(const PositionStopMap &stops) const |
165 | { |
166 | PositionColorMap data; |
167 | for (QtGradientStop *stop : stops) |
168 | data[stop->position()] = stop->color(); |
169 | return data; |
170 | } |
171 | |
172 | QGradientStops QtGradientStopsControllerPrivate::makeGradientStops(const PositionColorMap &data) const |
173 | { |
174 | QGradientStops stops; |
175 | for (auto itData = data.cbegin(), cend = data.cend(); itData != cend; ++itData) |
176 | stops << QPair<qreal, QColor>(itData.key(), itData.value()); |
177 | return stops; |
178 | } |
179 | |
180 | void QtGradientStopsControllerPrivate::updateZoom(double zoom) |
181 | { |
182 | m_ui->gradientStopsWidget->setZoom(zoom); |
183 | m_ui->zoomSpinBox->blockSignals(true); |
184 | m_ui->zoomSpinBox->setValue(qRound(d: zoom * 100)); |
185 | m_ui->zoomSpinBox->blockSignals(false); |
186 | bool zoomInEnabled = true; |
187 | bool zoomOutEnabled = true; |
188 | bool zoomAllEnabled = true; |
189 | if (zoom <= 1) { |
190 | zoomAllEnabled = false; |
191 | zoomOutEnabled = false; |
192 | } else if (zoom >= 100) { |
193 | zoomInEnabled = false; |
194 | } |
195 | m_ui->zoomInButton->setEnabled(zoomInEnabled); |
196 | m_ui->zoomOutButton->setEnabled(zoomOutEnabled); |
197 | m_ui->zoomAllButton->setEnabled(zoomAllEnabled); |
198 | } |
199 | |
200 | void QtGradientStopsControllerPrivate::slotHsvClicked() |
201 | { |
202 | QString h = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "H" ); |
203 | QString s = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "S" ); |
204 | QString v = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "V" ); |
205 | |
206 | m_ui->hLabel->setText(h); |
207 | m_ui->sLabel->setText(s); |
208 | m_ui->vLabel->setText(v); |
209 | |
210 | h = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Hue" ); |
211 | s = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Sat" ); |
212 | v = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Val" ); |
213 | |
214 | const QString hue = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Hue" ); |
215 | const QString saturation = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Saturation" ); |
216 | const QString value = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Value" ); |
217 | |
218 | m_ui->hLabel->setToolTip(hue); |
219 | m_ui->hueLabel->setText(h); |
220 | m_ui->hueColorLine->setToolTip(hue); |
221 | m_ui->hueColorLine->setColorComponent(QtColorLine::Hue); |
222 | |
223 | m_ui->sLabel->setToolTip(saturation); |
224 | m_ui->saturationLabel->setText(s); |
225 | m_ui->saturationColorLine->setToolTip(saturation); |
226 | m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation); |
227 | |
228 | m_ui->vLabel->setToolTip(value); |
229 | m_ui->valueLabel->setText(v); |
230 | m_ui->valueColorLine->setToolTip(value); |
231 | m_ui->valueColorLine->setColorComponent(QtColorLine::Value); |
232 | |
233 | setColorSpinBoxes(m_ui->colorButton->color()); |
234 | } |
235 | |
236 | void QtGradientStopsControllerPrivate::slotRgbClicked() |
237 | { |
238 | QString r = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "R" ); |
239 | QString g = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "G" ); |
240 | QString b = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "B" ); |
241 | |
242 | m_ui->hLabel->setText(r); |
243 | m_ui->sLabel->setText(g); |
244 | m_ui->vLabel->setText(b); |
245 | |
246 | QString red = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Red" ); |
247 | QString green = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Green" ); |
248 | QString blue = QCoreApplication::translate("qdesigner_internal::QtGradientStopsController" , "Blue" ); |
249 | |
250 | m_ui->hLabel->setToolTip(red); |
251 | m_ui->hueLabel->setText(red); |
252 | m_ui->hueColorLine->setToolTip(red); |
253 | m_ui->hueColorLine->setColorComponent(QtColorLine::Red); |
254 | |
255 | m_ui->sLabel->setToolTip(green); |
256 | m_ui->saturationLabel->setText(green); |
257 | m_ui->saturationColorLine->setToolTip(green); |
258 | m_ui->saturationColorLine->setColorComponent(QtColorLine::Green); |
259 | |
260 | m_ui->vLabel->setToolTip(blue); |
261 | m_ui->valueLabel->setText(blue); |
262 | m_ui->valueColorLine->setToolTip(blue); |
263 | m_ui->valueColorLine->setColorComponent(QtColorLine::Blue); |
264 | |
265 | setColorSpinBoxes(m_ui->colorButton->color()); |
266 | } |
267 | |
268 | void QtGradientStopsControllerPrivate::setColorSpinBoxes(const QColor &color) |
269 | { |
270 | m_ui->hueSpinBox->blockSignals(true); |
271 | m_ui->saturationSpinBox->blockSignals(true); |
272 | m_ui->valueSpinBox->blockSignals(true); |
273 | m_ui->alphaSpinBox->blockSignals(true); |
274 | if (m_ui->hsvRadioButton->isChecked()) { |
275 | if (m_ui->hueSpinBox->maximum() != 359) |
276 | m_ui->hueSpinBox->setMaximum(359); |
277 | if (m_ui->hueSpinBox->value() != color.hue()) |
278 | m_ui->hueSpinBox->setValue(color.hue()); |
279 | if (m_ui->saturationSpinBox->value() != color.saturation()) |
280 | m_ui->saturationSpinBox->setValue(color.saturation()); |
281 | if (m_ui->valueSpinBox->value() != color.value()) |
282 | m_ui->valueSpinBox->setValue(color.value()); |
283 | } else { |
284 | if (m_ui->hueSpinBox->maximum() != 255) |
285 | m_ui->hueSpinBox->setMaximum(255); |
286 | if (m_ui->hueSpinBox->value() != color.red()) |
287 | m_ui->hueSpinBox->setValue(color.red()); |
288 | if (m_ui->saturationSpinBox->value() != color.green()) |
289 | m_ui->saturationSpinBox->setValue(color.green()); |
290 | if (m_ui->valueSpinBox->value() != color.blue()) |
291 | m_ui->valueSpinBox->setValue(color.blue()); |
292 | } |
293 | m_ui->alphaSpinBox->setValue(color.alpha()); |
294 | m_ui->hueSpinBox->blockSignals(false); |
295 | m_ui->saturationSpinBox->blockSignals(false); |
296 | m_ui->valueSpinBox->blockSignals(false); |
297 | m_ui->alphaSpinBox->blockSignals(false); |
298 | } |
299 | |
300 | void QtGradientStopsControllerPrivate::slotCurrentStopChanged(QtGradientStop *stop) |
301 | { |
302 | if (!stop) { |
303 | enableCurrent(enable: false); |
304 | return; |
305 | } |
306 | enableCurrent(enable: true); |
307 | |
308 | QTimer::singleShot(interval: 0, receiver: this, slot: &QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox); |
309 | |
310 | m_ui->colorButton->setColor(stop->color()); |
311 | m_ui->hueColorLine->setColor(stop->color()); |
312 | m_ui->saturationColorLine->setColor(stop->color()); |
313 | m_ui->valueColorLine->setColor(stop->color()); |
314 | m_ui->alphaColorLine->setColor(stop->color()); |
315 | setColorSpinBoxes(stop->color()); |
316 | } |
317 | |
318 | void QtGradientStopsControllerPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos) |
319 | { |
320 | QTimer::singleShot(interval: 0, receiver: this, slot: &QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox); |
321 | |
322 | PositionColorMap stops = stopsData(stops: m_model->stops()); |
323 | stops.remove(key: stop->position()); |
324 | stops[newPos] = stop->color(); |
325 | |
326 | QGradientStops gradStops = makeGradientStops(data: stops); |
327 | emit q_ptr->gradientStopsChanged(stops: gradStops); |
328 | } |
329 | |
330 | void QtGradientStopsControllerPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2) |
331 | { |
332 | QTimer::singleShot(interval: 0, receiver: this, slot: &QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox); |
333 | |
334 | PositionColorMap stops = stopsData(stops: m_model->stops()); |
335 | const qreal pos1 = stop1->position(); |
336 | const qreal pos2 = stop2->position(); |
337 | stops[pos1] = stop2->color(); |
338 | stops[pos2] = stop1->color(); |
339 | |
340 | QGradientStops gradStops = makeGradientStops(data: stops); |
341 | emit q_ptr->gradientStopsChanged(stops: gradStops); |
342 | } |
343 | |
344 | void QtGradientStopsControllerPrivate::slotStopAdded(QtGradientStop *stop) |
345 | { |
346 | PositionColorMap stops = stopsData(stops: m_model->stops()); |
347 | stops[stop->position()] = stop->color(); |
348 | |
349 | QGradientStops gradStops = makeGradientStops(data: stops); |
350 | emit q_ptr->gradientStopsChanged(stops: gradStops); |
351 | } |
352 | |
353 | void QtGradientStopsControllerPrivate::slotStopRemoved(QtGradientStop *stop) |
354 | { |
355 | PositionColorMap stops = stopsData(stops: m_model->stops()); |
356 | stops.remove(key: stop->position()); |
357 | |
358 | QGradientStops gradStops = makeGradientStops(data: stops); |
359 | emit q_ptr->gradientStopsChanged(stops: gradStops); |
360 | } |
361 | |
362 | void QtGradientStopsControllerPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor) |
363 | { |
364 | if (m_model->currentStop() == stop) { |
365 | m_ui->colorButton->setColor(newColor); |
366 | m_ui->hueColorLine->setColor(newColor); |
367 | m_ui->saturationColorLine->setColor(newColor); |
368 | m_ui->valueColorLine->setColor(newColor); |
369 | m_ui->alphaColorLine->setColor(newColor); |
370 | setColorSpinBoxes(newColor); |
371 | } |
372 | |
373 | PositionColorMap stops = stopsData(stops: m_model->stops()); |
374 | stops[stop->position()] = newColor; |
375 | |
376 | QGradientStops gradStops = makeGradientStops(data: stops); |
377 | emit q_ptr->gradientStopsChanged(stops: gradStops); |
378 | } |
379 | |
380 | void QtGradientStopsControllerPrivate::slotStopSelected(QtGradientStop *stop, bool selected) |
381 | { |
382 | Q_UNUSED(stop); |
383 | Q_UNUSED(selected); |
384 | QTimer::singleShot(interval: 0, receiver: this, slot: &QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox); |
385 | } |
386 | |
387 | void QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox() |
388 | { |
389 | QtGradientStop *current = m_model->currentStop(); |
390 | if (!current) |
391 | return; |
392 | |
393 | qreal min = 0.0; |
394 | qreal max = 1.0; |
395 | const qreal pos = current->position(); |
396 | |
397 | QtGradientStop *first = m_model->firstSelected(); |
398 | QtGradientStop *last = m_model->lastSelected(); |
399 | |
400 | if (first && last) { |
401 | const qreal minPos = pos - first->position() - 0.0004999; |
402 | const qreal maxPos = pos + 1.0 - last->position() + 0.0004999; |
403 | |
404 | if (max > maxPos) |
405 | max = maxPos; |
406 | if (min < minPos) |
407 | min = minPos; |
408 | |
409 | if (first->position() == 0.0) |
410 | min = pos; |
411 | if (last->position() == 1.0) |
412 | max = pos; |
413 | } |
414 | |
415 | const int spinMin = qRound(m_ui->positionSpinBox->minimum() * 1000); |
416 | const int spinMax = qRound(m_ui->positionSpinBox->maximum() * 1000); |
417 | |
418 | const int newMin = qRound(d: min * 1000); |
419 | const int newMax = qRound(d: max * 1000); |
420 | |
421 | m_ui->positionSpinBox->blockSignals(true); |
422 | if (spinMin != newMin || spinMax != newMax) { |
423 | m_ui->positionSpinBox->setRange(double(newMin) / 1000, double(newMax) / 1000); |
424 | } |
425 | if (m_ui->positionSpinBox->value() != pos) |
426 | m_ui->positionSpinBox->setValue(pos); |
427 | m_ui->positionSpinBox->blockSignals(false); |
428 | } |
429 | |
430 | void QtGradientStopsControllerPrivate::slotChangeColor(const QColor &color) |
431 | { |
432 | QtGradientStop *stop = m_model->currentStop(); |
433 | if (!stop) |
434 | return; |
435 | m_model->changeStop(stop, newColor: color); |
436 | const auto stops = m_model->selectedStops(); |
437 | for (QtGradientStop *s : stops) { |
438 | if (s != stop) |
439 | m_model->changeStop(stop: s, newColor: color); |
440 | } |
441 | } |
442 | |
443 | void QtGradientStopsControllerPrivate::slotChangeHueColor(const QColor &color) |
444 | { |
445 | QtGradientStop *stop = m_model->currentStop(); |
446 | if (!stop) |
447 | return; |
448 | m_model->changeStop(stop, newColor: color); |
449 | const auto stops = m_model->selectedStops(); |
450 | for (QtGradientStop *s : stops) { |
451 | if (s != stop) { |
452 | QColor c = s->color(); |
453 | if (m_ui->hsvRadioButton->isChecked()) |
454 | c.setHsvF(h: color.hueF(), s: c.saturationF(), v: c.valueF(), a: c.alphaF()); |
455 | else |
456 | c.setRgbF(r: color.redF(), g: c.greenF(), b: c.blueF(), a: c.alphaF()); |
457 | m_model->changeStop(stop: s, newColor: c); |
458 | } |
459 | } |
460 | } |
461 | |
462 | void QtGradientStopsControllerPrivate::slotChangeHue(int color) |
463 | { |
464 | QColor c = m_ui->hueColorLine->color(); |
465 | if (m_ui->hsvRadioButton->isChecked()) |
466 | c.setHsvF(h: qreal(color) / 360.0, s: c.saturationF(), v: c.valueF(), a: c.alphaF()); |
467 | else |
468 | c.setRed(color); |
469 | slotChangeHueColor(color: c); |
470 | } |
471 | |
472 | void QtGradientStopsControllerPrivate::slotChangeSaturationColor(const QColor &color) |
473 | { |
474 | QtGradientStop *stop = m_model->currentStop(); |
475 | if (!stop) |
476 | return; |
477 | m_model->changeStop(stop, newColor: color); |
478 | const auto stops = m_model->selectedStops(); |
479 | for (QtGradientStop *s : stops) { |
480 | if (s != stop) { |
481 | QColor c = s->color(); |
482 | if (m_ui->hsvRadioButton->isChecked()) { |
483 | c.setHsvF(h: c.hueF(), s: color.saturationF(), v: c.valueF(), a: c.alphaF()); |
484 | int hue = c.hue(); |
485 | if (hue == 360 || hue == -1) |
486 | c.setHsvF(h: 0.0, s: c.saturationF(), v: c.valueF(), a: c.alphaF()); |
487 | } else { |
488 | c.setRgbF(r: c.redF(), g: color.greenF(), b: c.blueF(), a: c.alphaF()); |
489 | } |
490 | m_model->changeStop(stop: s, newColor: c); |
491 | } |
492 | } |
493 | } |
494 | |
495 | void QtGradientStopsControllerPrivate::slotChangeSaturation(int color) |
496 | { |
497 | QColor c = m_ui->saturationColorLine->color(); |
498 | if (m_ui->hsvRadioButton->isChecked()) |
499 | c.setHsvF(h: c.hueF(), s: qreal(color) / 255, v: c.valueF(), a: c.alphaF()); |
500 | else |
501 | c.setGreen(color); |
502 | slotChangeSaturationColor(color: c); |
503 | } |
504 | |
505 | void QtGradientStopsControllerPrivate::slotChangeValueColor(const QColor &color) |
506 | { |
507 | QtGradientStop *stop = m_model->currentStop(); |
508 | if (!stop) |
509 | return; |
510 | m_model->changeStop(stop, newColor: color); |
511 | const auto stops = m_model->selectedStops(); |
512 | for (QtGradientStop *s : stops) { |
513 | if (s != stop) { |
514 | QColor c = s->color(); |
515 | if (m_ui->hsvRadioButton->isChecked()) { |
516 | c.setHsvF(h: c.hueF(), s: c.saturationF(), v: color.valueF(), a: c.alphaF()); |
517 | int hue = c.hue(); |
518 | if (hue == 360 || hue == -1) |
519 | c.setHsvF(h: 0.0, s: c.saturationF(), v: c.valueF(), a: c.alphaF()); |
520 | } else { |
521 | c.setRgbF(r: c.redF(), g: c.greenF(), b: color.blueF(), a: c.alphaF()); |
522 | } |
523 | m_model->changeStop(stop: s, newColor: c); |
524 | } |
525 | } |
526 | } |
527 | |
528 | void QtGradientStopsControllerPrivate::slotChangeValue(int color) |
529 | { |
530 | QColor c = m_ui->valueColorLine->color(); |
531 | if (m_ui->hsvRadioButton->isChecked()) |
532 | c.setHsvF(h: c.hueF(), s: c.saturationF(), v: qreal(color) / 255, a: c.alphaF()); |
533 | else |
534 | c.setBlue(color); |
535 | slotChangeValueColor(color: c); |
536 | } |
537 | |
538 | void QtGradientStopsControllerPrivate::slotChangeAlphaColor(const QColor &color) |
539 | { |
540 | QtGradientStop *stop = m_model->currentStop(); |
541 | if (!stop) |
542 | return; |
543 | m_model->changeStop(stop, newColor: color); |
544 | const auto stops = m_model->selectedStops(); |
545 | for (QtGradientStop *s : stops) { |
546 | if (s != stop) { |
547 | QColor c = s->color(); |
548 | if (m_ui->hsvRadioButton->isChecked()) { |
549 | c.setHsvF(h: c.hueF(), s: c.saturationF(), v: c.valueF(), a: color.alphaF()); |
550 | int hue = c.hue(); |
551 | if (hue == 360 || hue == -1) |
552 | c.setHsvF(h: 0.0, s: c.saturationF(), v: c.valueF(), a: c.alphaF()); |
553 | } else { |
554 | c.setRgbF(r: c.redF(), g: c.greenF(), b: c.blueF(), a: color.alphaF()); |
555 | } |
556 | m_model->changeStop(stop: s, newColor: c); |
557 | } |
558 | } |
559 | } |
560 | |
561 | void QtGradientStopsControllerPrivate::slotChangeAlpha(int color) |
562 | { |
563 | QColor c = m_ui->alphaColorLine->color(); |
564 | if (m_ui->hsvRadioButton->isChecked()) |
565 | c.setHsvF(h: c.hueF(), s: c.saturationF(), v: c.valueF(), a: qreal(color) / 255); |
566 | else |
567 | c.setAlpha(color); |
568 | slotChangeAlphaColor(color: c); |
569 | } |
570 | |
571 | void QtGradientStopsControllerPrivate::slotChangePosition(double value) |
572 | { |
573 | QtGradientStop *stop = m_model->currentStop(); |
574 | if (!stop) |
575 | return; |
576 | |
577 | m_model->moveStops(newPosition: value); |
578 | } |
579 | |
580 | void QtGradientStopsControllerPrivate::slotChangeZoom(int value) |
581 | { |
582 | updateZoom(zoom: value / 100.0); |
583 | } |
584 | |
585 | void QtGradientStopsControllerPrivate::slotZoomIn() |
586 | { |
587 | double newZoom = m_ui->gradientStopsWidget->zoom() * 2; |
588 | if (newZoom > 100) |
589 | newZoom = 100; |
590 | updateZoom(zoom: newZoom); |
591 | } |
592 | |
593 | void QtGradientStopsControllerPrivate::slotZoomOut() |
594 | { |
595 | double newZoom = m_ui->gradientStopsWidget->zoom() / 2; |
596 | if (newZoom < 1) |
597 | newZoom = 1; |
598 | updateZoom(zoom: newZoom); |
599 | } |
600 | |
601 | void QtGradientStopsControllerPrivate::slotZoomAll() |
602 | { |
603 | updateZoom(zoom: 1); |
604 | } |
605 | |
606 | void QtGradientStopsControllerPrivate::slotZoomChanged(double zoom) |
607 | { |
608 | updateZoom(zoom); |
609 | } |
610 | |
611 | QtGradientStopsController::QtGradientStopsController(QObject *parent) |
612 | : QObject(parent), d_ptr(new QtGradientStopsControllerPrivate()) |
613 | { |
614 | d_ptr->q_ptr = this; |
615 | } |
616 | |
617 | void QtGradientStopsController::setUi(Ui::QtGradientEditor *ui) |
618 | { |
619 | d_ptr->setUi(ui); |
620 | } |
621 | |
622 | QtGradientStopsController::~QtGradientStopsController() |
623 | { |
624 | } |
625 | |
626 | void QtGradientStopsController::setGradientStops(const QGradientStops &stops) |
627 | { |
628 | d_ptr->m_model->clear(); |
629 | QtGradientStop *first = nullptr; |
630 | for (const QPair<qreal, QColor> &pair : stops) { |
631 | QtGradientStop *stop = d_ptr->m_model->addStop(pos: pair.first, color: pair.second); |
632 | if (!first) |
633 | first = stop; |
634 | } |
635 | if (first) |
636 | d_ptr->m_model->setCurrentStop(first); |
637 | } |
638 | |
639 | QGradientStops QtGradientStopsController::gradientStops() const |
640 | { |
641 | QGradientStops stops; |
642 | const auto stopsList = d_ptr->m_model->stops().values(); |
643 | for (const QtGradientStop *stop : stopsList) |
644 | stops << QPair<qreal, QColor>(stop->position(), stop->color()); |
645 | return stops; |
646 | } |
647 | |
648 | QColor::Spec QtGradientStopsController::spec() const |
649 | { |
650 | return d_ptr->m_spec; |
651 | } |
652 | |
653 | void QtGradientStopsController::setSpec(QColor::Spec spec) |
654 | { |
655 | if (d_ptr->m_spec == spec) |
656 | return; |
657 | |
658 | d_ptr->m_spec = spec; |
659 | if (d_ptr->m_spec == QColor::Rgb) { |
660 | d_ptr->m_ui->rgbRadioButton->setChecked(true); |
661 | d_ptr->slotRgbClicked(); |
662 | } else { |
663 | d_ptr->m_ui->hsvRadioButton->setChecked(true); |
664 | d_ptr->slotHsvClicked(); |
665 | } |
666 | } |
667 | |
668 | QT_END_NAMESPACE |
669 | |
670 | #include "qtgradientstopscontroller.moc" |
671 | |