1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qtgradienteditor.h"
41#include "qtgradientstopscontroller.h"
42#include "ui_qtgradienteditor.h"
43
44#include <QtWidgets/QButtonGroup>
45
46QT_BEGIN_NAMESPACE
47
48class QtGradientEditorPrivate
49{
50 QtGradientEditor *q_ptr;
51 Q_DECLARE_PUBLIC(QtGradientEditor)
52public:
53 QtGradientEditorPrivate() : m_gradient(QLinearGradient()) {}
54
55 void slotGradientStopsChanged(const QGradientStops &stops);
56 void slotTypeChanged(int type);
57 void slotSpreadChanged(int spread);
58 void slotStartLinearXChanged(double value);
59 void slotStartLinearYChanged(double value);
60 void slotEndLinearXChanged(double value);
61 void slotEndLinearYChanged(double value);
62 void slotCentralRadialXChanged(double value);
63 void slotCentralRadialYChanged(double value);
64 void slotFocalRadialXChanged(double value);
65 void slotFocalRadialYChanged(double value);
66 void slotRadiusRadialChanged(double value);
67 void slotCentralConicalXChanged(double value);
68 void slotCentralConicalYChanged(double value);
69 void slotAngleConicalChanged(double value);
70
71 void slotDetailsChanged(bool details);
72
73 void startLinearChanged(const QPointF &point);
74 void endLinearChanged(const QPointF &point);
75 void centralRadialChanged(const QPointF &point);
76 void focalRadialChanged(const QPointF &point);
77 void radiusRadialChanged(qreal radius);
78 void centralConicalChanged(const QPointF &point);
79 void angleConicalChanged(qreal angle);
80
81 void setStartLinear(const QPointF &point);
82 void setEndLinear(const QPointF &point);
83 void setCentralRadial(const QPointF &point);
84 void setFocalRadial(const QPointF &point);
85 void setRadiusRadial(qreal radius);
86 void setCentralConical(const QPointF &point);
87 void setAngleConical(qreal angle);
88
89 void setType(QGradient::Type type);
90 void showDetails(bool details);
91
92 void setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max = 1.0, double step = 0.01, int decimals = 3);
93 void reset();
94 void setLayout(bool details);
95 void layoutDetails(bool details);
96 bool row4Visible() const;
97 bool row5Visible() const;
98 int extensionWidthHint() const;
99
100 void setCombos(bool combos);
101
102 QGradient gradient() const;
103 void updateGradient(bool emitSignal);
104
105 Ui::QtGradientEditor m_ui;
106 QtGradientStopsController *m_gradientStopsController;
107
108 QDoubleSpinBox *startLinearXSpinBox;
109 QDoubleSpinBox *startLinearYSpinBox;
110 QDoubleSpinBox *endLinearXSpinBox;
111 QDoubleSpinBox *endLinearYSpinBox;
112 QDoubleSpinBox *centralRadialXSpinBox;
113 QDoubleSpinBox *centralRadialYSpinBox;
114 QDoubleSpinBox *focalRadialXSpinBox;
115 QDoubleSpinBox *focalRadialYSpinBox;
116 QDoubleSpinBox *radiusRadialSpinBox;
117 QDoubleSpinBox *centralConicalXSpinBox;
118 QDoubleSpinBox *centralConicalYSpinBox;
119 QDoubleSpinBox *angleConicalSpinBox;
120
121 QButtonGroup *m_typeGroup;
122 QButtonGroup *m_spreadGroup;
123
124 QGradient::Type m_type;
125
126 QGridLayout *m_gridLayout;
127 QWidget *m_hiddenWidget;
128 QGridLayout *m_hiddenLayout;
129 bool m_details;
130 bool m_detailsButtonVisible;
131 bool m_backgroundCheckered;
132
133 QGradient m_gradient;
134
135 bool m_combos;
136};
137
138QGradient QtGradientEditorPrivate::gradient() const
139{
140 QGradient *gradient = 0;
141 switch (m_ui.gradientWidget->gradientType()) {
142 case QGradient::LinearGradient:
143 gradient = new QLinearGradient(m_ui.gradientWidget->startLinear(),
144 m_ui.gradientWidget->endLinear());
145 break;
146 case QGradient::RadialGradient:
147 gradient = new QRadialGradient(m_ui.gradientWidget->centralRadial(),
148 m_ui.gradientWidget->radiusRadial(),
149 m_ui.gradientWidget->focalRadial());
150 break;
151 case QGradient::ConicalGradient:
152 gradient = new QConicalGradient(m_ui.gradientWidget->centralConical(),
153 m_ui.gradientWidget->angleConical());
154 break;
155 default:
156 break;
157 }
158 if (!gradient)
159 return QGradient();
160 gradient->setStops(m_ui.gradientWidget->gradientStops());
161 gradient->setSpread(m_ui.gradientWidget->gradientSpread());
162 gradient->setCoordinateMode(QGradient::StretchToDeviceMode);
163 QGradient gr = *gradient;
164 delete gradient;
165 return gr;
166}
167
168void QtGradientEditorPrivate::updateGradient(bool emitSignal)
169{
170 QGradient grad = gradient();
171 if (m_gradient == grad)
172 return;
173
174 m_gradient = grad;
175 if (emitSignal)
176 emit q_ptr->gradientChanged(m_gradient);
177}
178
179void QtGradientEditorPrivate::setCombos(bool combos)
180{
181 if (m_combos == combos)
182 return;
183
184 m_combos = combos;
185 m_ui.linearButton->setVisible(!m_combos);
186 m_ui.radialButton->setVisible(!m_combos);
187 m_ui.conicalButton->setVisible(!m_combos);
188 m_ui.padButton->setVisible(!m_combos);
189 m_ui.repeatButton->setVisible(!m_combos);
190 m_ui.reflectButton->setVisible(!m_combos);
191 m_ui.typeComboBox->setVisible(m_combos);
192 m_ui.spreadComboBox->setVisible(m_combos);
193}
194
195void QtGradientEditorPrivate::setLayout(bool details)
196{
197 QHBoxLayout *hboxLayout = new QHBoxLayout();
198 hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
199 hboxLayout->addWidget(m_ui.typeComboBox);
200 hboxLayout->addWidget(m_ui.spreadComboBox);
201 QHBoxLayout *typeLayout = new QHBoxLayout();
202 typeLayout->setSpacing(0);
203 typeLayout->addWidget(m_ui.linearButton);
204 typeLayout->addWidget(m_ui.radialButton);
205 typeLayout->addWidget(m_ui.conicalButton);
206 hboxLayout->addLayout(typeLayout);
207 QHBoxLayout *spreadLayout = new QHBoxLayout();
208 spreadLayout->setSpacing(0);
209 spreadLayout->addWidget(m_ui.padButton);
210 spreadLayout->addWidget(m_ui.repeatButton);
211 spreadLayout->addWidget(m_ui.reflectButton);
212 hboxLayout->addLayout(spreadLayout);
213 hboxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
214 hboxLayout->addWidget(m_ui.detailsButton);
215 m_gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
216 int span = 1;
217 if (details)
218 span = 7;
219 m_gridLayout->addWidget(m_ui.frame, 1, 0, span, 2);
220 int row = 2;
221 if (details) {
222 row = 8;
223 span = 4;
224 }
225 m_gridLayout->addWidget(m_ui.gradientStopsWidget, row, 0, span, 2);
226 QHBoxLayout *hboxLayout1 = new QHBoxLayout();
227 hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
228 hboxLayout1->addWidget(m_ui.colorLabel);
229 hboxLayout1->addWidget(m_ui.colorButton);
230 hboxLayout1->addWidget(m_ui.hsvRadioButton);
231 hboxLayout1->addWidget(m_ui.rgbRadioButton);
232 hboxLayout1->addItem(new QSpacerItem(16, 23, QSizePolicy::Expanding, QSizePolicy::Minimum));
233 int addRow = 0;
234 if (details)
235 addRow = 9;
236 m_gridLayout->addLayout(hboxLayout1, 3 + addRow, 0, 1, 2);
237 m_gridLayout->addWidget(m_ui.hLabel, 4 + addRow, 0, 1, 1);
238 m_gridLayout->addWidget(m_ui.frame_2, 4 + addRow, 1, 1, 1);
239 m_gridLayout->addWidget(m_ui.sLabel, 5 + addRow, 0, 1, 1);
240 m_gridLayout->addWidget(m_ui.frame_5, 5 + addRow, 1, 1, 1);
241 m_gridLayout->addWidget(m_ui.vLabel, 6 + addRow, 0, 1, 1);
242 m_gridLayout->addWidget(m_ui.frame_3, 6 + addRow, 1, 1, 1);
243 m_gridLayout->addWidget(m_ui.aLabel, 7 + addRow, 0, 1, 1);
244 m_gridLayout->addWidget(m_ui.frame_4, 7 + addRow, 1, 1, 1);
245
246 if (details) {
247 layoutDetails(details);
248 }
249}
250
251void QtGradientEditorPrivate::layoutDetails(bool details)
252{
253 QGridLayout *gridLayout = m_gridLayout;
254 int col = 2;
255 if (!details) {
256 col = 0;
257 if (!m_hiddenWidget) {
258 m_hiddenWidget = new QWidget();
259 m_hiddenLayout = new QGridLayout(m_hiddenWidget);
260 m_hiddenLayout->setContentsMargins(0, 0, 0, 0);
261 m_hiddenLayout->setSizeConstraint(QLayout::SetFixedSize);
262 }
263 gridLayout = m_hiddenLayout;
264 }
265 gridLayout->addWidget(m_ui.label1, 1, col + 0, 1, 1);
266 gridLayout->addWidget(m_ui.spinBox1, 1, col + 1, 1, 1);
267 gridLayout->addWidget(m_ui.label2, 2, col + 0, 1, 1);
268 gridLayout->addWidget(m_ui.spinBox2, 2, col + 1, 1, 1);
269 gridLayout->addWidget(m_ui.label3, 3, col + 0, 1, 1);
270 gridLayout->addWidget(m_ui.spinBox3, 3, col + 1, 1, 1);
271 gridLayout->addWidget(m_ui.label4, 4, col + 0, 1, 1);
272 gridLayout->addWidget(m_ui.spinBox4, 4, col + 1, 1, 1);
273 gridLayout->addWidget(m_ui.label5, 5, col + 0, 1, 1);
274 gridLayout->addWidget(m_ui.spinBox5, 5, col + 1, 1, 1);
275 gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 6, col + 0, 1, 1);
276 gridLayout->addWidget(m_ui.line1Widget, 7, col + 0, 1, 2);
277 gridLayout->addWidget(m_ui.zoomLabel, 8, col + 0, 1, 1);
278 gridLayout->addWidget(m_ui.zoomWidget, 8, col + 1, 1, 1);
279 gridLayout->addWidget(m_ui.zoomButtonsWidget, 9, col + 0, 1, 1);
280 gridLayout->addWidget(m_ui.zoomAllButton, 9, col + 1, 1, 1);
281 gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred), 10, col + 0, 1, 1);
282 gridLayout->addWidget(m_ui.line2Widget, 11, col + 0, 1, 2);
283 gridLayout->addWidget(m_ui.positionLabel, 12, col + 0, 1, 1);
284 gridLayout->addWidget(m_ui.positionWidget, 12, col + 1, 1, 1);
285 gridLayout->addWidget(m_ui.hueLabel, 13, col + 0, 1, 1);
286 gridLayout->addWidget(m_ui.hueWidget, 13, col + 1, 1, 1);
287 gridLayout->addWidget(m_ui.saturationLabel, 14, col + 0, 1, 1);
288 gridLayout->addWidget(m_ui.saturationWidget, 14, col + 1, 1, 1);
289 gridLayout->addWidget(m_ui.valueLabel, 15, col + 0, 1, 1);
290 gridLayout->addWidget(m_ui.valueWidget, 15, col + 1, 1, 1);
291 gridLayout->addWidget(m_ui.alphaLabel, 16, col + 0, 1, 1);
292 gridLayout->addWidget(m_ui.alphaWidget, 16, col + 1, 1, 1);
293
294 if (details) {
295 if (m_hiddenLayout) {
296 delete m_hiddenLayout;
297 m_hiddenLayout = 0;
298 }
299 if (m_hiddenWidget) {
300 delete m_hiddenWidget;
301 m_hiddenWidget = 0;
302 }
303 }
304}
305
306int QtGradientEditorPrivate::extensionWidthHint() const
307{
308 if (m_details)
309 return q_ptr->size().width() - m_ui.gradientStopsWidget->size().width();
310
311 const int space = m_ui.spinBox1->geometry().left() - m_ui.label1->geometry().right();
312
313 return m_hiddenLayout->minimumSize().width() + space;
314}
315
316void QtGradientEditorPrivate::slotDetailsChanged(bool details)
317{
318 showDetails(details);
319}
320
321bool QtGradientEditorPrivate::row4Visible() const
322{
323 if (m_type == QGradient::ConicalGradient)
324 return false;
325 return true;
326}
327
328bool QtGradientEditorPrivate::row5Visible() const
329{
330 if (m_type == QGradient::RadialGradient)
331 return true;
332 return false;
333}
334
335void QtGradientEditorPrivate::showDetails(bool details)
336{
337 if (m_details == details)
338 return;
339
340 bool blocked = m_ui.detailsButton->signalsBlocked();
341 m_ui.detailsButton->blockSignals(true);
342 m_ui.detailsButton->setChecked(details);
343 m_ui.detailsButton->blockSignals(blocked);
344
345 bool updates = q_ptr->updatesEnabled();
346 q_ptr->setUpdatesEnabled(false);
347
348 if (m_gridLayout) {
349 m_gridLayout->setEnabled(false);
350 delete m_gridLayout;
351 m_gridLayout = 0;
352 }
353
354 if (!details) {
355 layoutDetails(details);
356 }
357
358 emit q_ptr->aboutToShowDetails(details, extensionWidthHint());
359 m_details = details;
360
361 m_gridLayout = new QGridLayout(q_ptr);
362 m_gridLayout->setEnabled(false);
363 m_gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
364 m_gridLayout->setContentsMargins(0, 0, 0, 0);
365
366 m_ui.label4->setVisible(row4Visible());
367 m_ui.label5->setVisible(row5Visible());
368 m_ui.spinBox4->setVisible(row4Visible());
369 m_ui.spinBox5->setVisible(row5Visible());
370
371 setLayout(details);
372 m_gridLayout->setEnabled(true);
373
374 q_ptr->setUpdatesEnabled(updates);
375 q_ptr->update();
376}
377
378void QtGradientEditorPrivate::setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max, double step, int decimals)
379{
380 bool blocked = spinBox->signalsBlocked();
381 spinBox->blockSignals(true);
382 spinBox->setDecimals(decimals);
383 spinBox->setMaximum(max);
384 spinBox->setSingleStep(step);
385 spinBox->blockSignals(blocked);
386 QObject::connect(spinBox, SIGNAL(valueChanged(double)), q_ptr, slot);
387}
388
389void QtGradientEditorPrivate::reset()
390{
391 startLinearXSpinBox = 0;
392 startLinearYSpinBox = 0;
393 endLinearXSpinBox = 0;
394 endLinearYSpinBox = 0;
395 centralRadialXSpinBox = 0;
396 centralRadialYSpinBox = 0;
397 focalRadialXSpinBox = 0;
398 focalRadialYSpinBox = 0;
399 radiusRadialSpinBox = 0;
400 centralConicalXSpinBox = 0;
401 centralConicalYSpinBox = 0;
402 angleConicalSpinBox = 0;
403}
404
405void QtGradientEditorPrivate::setType(QGradient::Type type)
406{
407 if (m_type == type)
408 return;
409
410 m_type = type;
411 m_ui.spinBox1->disconnect(SIGNAL(valueChanged(double)));
412 m_ui.spinBox2->disconnect(SIGNAL(valueChanged(double)));
413 m_ui.spinBox3->disconnect(SIGNAL(valueChanged(double)));
414 m_ui.spinBox4->disconnect(SIGNAL(valueChanged(double)));
415 m_ui.spinBox5->disconnect(SIGNAL(valueChanged(double)));
416
417 reset();
418
419 bool ena = true;
420
421 if (m_gridLayout) {
422 ena = m_gridLayout->isEnabled();
423 m_gridLayout->setEnabled(false);
424 }
425
426 bool spreadEnabled = true;
427
428 if (type == QGradient::LinearGradient) {
429 startLinearXSpinBox = m_ui.spinBox1;
430 setSpinBox(startLinearXSpinBox, SLOT(slotStartLinearXChanged(double)));
431 m_ui.label1->setText(QCoreApplication::translate("QtGradientEditor", "Start X"));
432
433 startLinearYSpinBox = m_ui.spinBox2;
434 setSpinBox(startLinearYSpinBox, SLOT(slotStartLinearYChanged(double)));
435 m_ui.label2->setText(QCoreApplication::translate("QtGradientEditor", "Start Y"));
436
437 endLinearXSpinBox = m_ui.spinBox3;
438 setSpinBox(endLinearXSpinBox, SLOT(slotEndLinearXChanged(double)));
439 m_ui.label3->setText(QCoreApplication::translate("QtGradientEditor", "Final X"));
440
441 endLinearYSpinBox = m_ui.spinBox4;
442 setSpinBox(endLinearYSpinBox, SLOT(slotEndLinearYChanged(double)));
443 m_ui.label4->setText(QCoreApplication::translate("QtGradientEditor", "Final Y"));
444
445 setStartLinear(m_ui.gradientWidget->startLinear());
446 setEndLinear(m_ui.gradientWidget->endLinear());
447 } else if (type == QGradient::RadialGradient) {
448 centralRadialXSpinBox = m_ui.spinBox1;
449 setSpinBox(centralRadialXSpinBox, SLOT(slotCentralRadialXChanged(double)));
450 m_ui.label1->setText(QCoreApplication::translate("QtGradientEditor", "Central X"));
451
452 centralRadialYSpinBox = m_ui.spinBox2;
453 setSpinBox(centralRadialYSpinBox, SLOT(slotCentralRadialYChanged(double)));
454 m_ui.label2->setText(QCoreApplication::translate("QtGradientEditor", "Central Y"));
455
456 focalRadialXSpinBox = m_ui.spinBox3;
457 setSpinBox(focalRadialXSpinBox, SLOT(slotFocalRadialXChanged(double)));
458 m_ui.label3->setText(QCoreApplication::translate("QtGradientEditor", "Focal X"));
459
460 focalRadialYSpinBox = m_ui.spinBox4;
461 setSpinBox(focalRadialYSpinBox, SLOT(slotFocalRadialYChanged(double)));
462 m_ui.label4->setText(QCoreApplication::translate("QtGradientEditor", "Focal Y"));
463
464 radiusRadialSpinBox = m_ui.spinBox5;
465 setSpinBox(radiusRadialSpinBox, SLOT(slotRadiusRadialChanged(double)), 2.0);
466 m_ui.label5->setText(QCoreApplication::translate("QtGradientEditor", "Radius"));
467
468 setCentralRadial(m_ui.gradientWidget->centralRadial());
469 setFocalRadial(m_ui.gradientWidget->focalRadial());
470 setRadiusRadial(m_ui.gradientWidget->radiusRadial());
471 } else if (type == QGradient::ConicalGradient) {
472 centralConicalXSpinBox = m_ui.spinBox1;
473 setSpinBox(centralConicalXSpinBox, SLOT(slotCentralConicalXChanged(double)));
474 m_ui.label1->setText(QCoreApplication::translate("QtGradientEditor", "Central X"));
475
476 centralConicalYSpinBox = m_ui.spinBox2;
477 setSpinBox(centralConicalYSpinBox, SLOT(slotCentralConicalYChanged(double)));
478 m_ui.label2->setText(QCoreApplication::translate("QtGradientEditor", "Central Y"));
479
480 angleConicalSpinBox = m_ui.spinBox3;
481 setSpinBox(angleConicalSpinBox, SLOT(slotAngleConicalChanged(double)), 360.0, 1.0, 1);
482 m_ui.label3->setText(QCoreApplication::translate("QtGradientEditor", "Angle"));
483
484 setCentralConical(m_ui.gradientWidget->centralConical());
485 setAngleConical(m_ui.gradientWidget->angleConical());
486
487 spreadEnabled = false;
488 }
489 m_ui.spreadComboBox->setEnabled(spreadEnabled);
490 m_ui.padButton->setEnabled(spreadEnabled);
491 m_ui.repeatButton->setEnabled(spreadEnabled);
492 m_ui.reflectButton->setEnabled(spreadEnabled);
493
494 m_ui.label4->setVisible(row4Visible());
495 m_ui.spinBox4->setVisible(row4Visible());
496 m_ui.label5->setVisible(row5Visible());
497 m_ui.spinBox5->setVisible(row5Visible());
498
499 if (m_gridLayout) {
500 m_gridLayout->setEnabled(ena);
501 }
502}
503
504void QtGradientEditorPrivate::slotGradientStopsChanged(const QGradientStops &stops)
505{
506 m_ui.gradientWidget->setGradientStops(stops);
507 updateGradient(true);
508}
509
510void QtGradientEditorPrivate::slotTypeChanged(int idx)
511{
512 QGradient::Type type = QGradient::NoGradient;
513 if (idx == 0)
514 type = QGradient::LinearGradient;
515 else if (idx == 1)
516 type = QGradient::RadialGradient;
517 else if (idx == 2)
518 type = QGradient::ConicalGradient;
519 setType(type);
520 m_ui.typeComboBox->setCurrentIndex(idx);
521 m_typeGroup->button(idx)->setChecked(true);
522 m_ui.gradientWidget->setGradientType(type);
523 updateGradient(true);
524}
525
526void QtGradientEditorPrivate::slotSpreadChanged(int spread)
527{
528 if (spread == 0) {
529 m_ui.gradientWidget->setGradientSpread(QGradient::PadSpread);
530 } else if (spread == 1) {
531 m_ui.gradientWidget->setGradientSpread(QGradient::RepeatSpread);
532 } else if (spread == 2) {
533 m_ui.gradientWidget->setGradientSpread(QGradient::ReflectSpread);
534 }
535 m_ui.spreadComboBox->setCurrentIndex(spread);
536 updateGradient(true);
537}
538
539void QtGradientEditorPrivate::slotStartLinearXChanged(double value)
540{
541 QPointF point = m_ui.gradientWidget->startLinear();
542 point.setX(value);
543 m_ui.gradientWidget->setStartLinear(point);
544 updateGradient(true);
545}
546
547void QtGradientEditorPrivate::slotStartLinearYChanged(double value)
548{
549 QPointF point = m_ui.gradientWidget->startLinear();
550 point.setY(value);
551 m_ui.gradientWidget->setStartLinear(point);
552 updateGradient(true);
553}
554
555void QtGradientEditorPrivate::slotEndLinearXChanged(double value)
556{
557 QPointF point = m_ui.gradientWidget->endLinear();
558 point.setX(value);
559 m_ui.gradientWidget->setEndLinear(point);
560 updateGradient(true);
561}
562
563void QtGradientEditorPrivate::slotEndLinearYChanged(double value)
564{
565 QPointF point = m_ui.gradientWidget->endLinear();
566 point.setY(value);
567 m_ui.gradientWidget->setEndLinear(point);
568 updateGradient(true);
569}
570
571void QtGradientEditorPrivate::slotCentralRadialXChanged(double value)
572{
573 QPointF point = m_ui.gradientWidget->centralRadial();
574 point.setX(value);
575 m_ui.gradientWidget->setCentralRadial(point);
576 updateGradient(true);
577}
578
579void QtGradientEditorPrivate::slotCentralRadialYChanged(double value)
580{
581 QPointF point = m_ui.gradientWidget->centralRadial();
582 point.setY(value);
583 m_ui.gradientWidget->setCentralRadial(point);
584 updateGradient(true);
585}
586
587void QtGradientEditorPrivate::slotFocalRadialXChanged(double value)
588{
589 QPointF point = m_ui.gradientWidget->focalRadial();
590 point.setX(value);
591 m_ui.gradientWidget->setFocalRadial(point);
592 updateGradient(true);
593}
594
595void QtGradientEditorPrivate::slotFocalRadialYChanged(double value)
596{
597 QPointF point = m_ui.gradientWidget->focalRadial();
598 point.setY(value);
599 m_ui.gradientWidget->setFocalRadial(point);
600 updateGradient(true);
601}
602
603void QtGradientEditorPrivate::slotRadiusRadialChanged(double value)
604{
605 m_ui.gradientWidget->setRadiusRadial(value);
606 updateGradient(true);
607}
608
609void QtGradientEditorPrivate::slotCentralConicalXChanged(double value)
610{
611 QPointF point = m_ui.gradientWidget->centralConical();
612 point.setX(value);
613 m_ui.gradientWidget->setCentralConical(point);
614 updateGradient(true);
615}
616
617void QtGradientEditorPrivate::slotCentralConicalYChanged(double value)
618{
619 QPointF point = m_ui.gradientWidget->centralConical();
620 point.setY(value);
621 m_ui.gradientWidget->setCentralConical(point);
622 updateGradient(true);
623}
624
625void QtGradientEditorPrivate::slotAngleConicalChanged(double value)
626{
627 m_ui.gradientWidget->setAngleConical(value);
628 updateGradient(true);
629}
630
631void QtGradientEditorPrivate::startLinearChanged(const QPointF &point)
632{
633 setStartLinear(point);
634 updateGradient(true);
635}
636
637void QtGradientEditorPrivate::endLinearChanged(const QPointF &point)
638{
639 setEndLinear(point);
640 updateGradient(true);
641}
642
643void QtGradientEditorPrivate::centralRadialChanged(const QPointF &point)
644{
645 setCentralRadial(point);
646 updateGradient(true);
647}
648
649void QtGradientEditorPrivate::focalRadialChanged(const QPointF &point)
650{
651 setFocalRadial(point);
652 updateGradient(true);
653}
654
655void QtGradientEditorPrivate::radiusRadialChanged(qreal radius)
656{
657 setRadiusRadial(radius);
658 updateGradient(true);
659}
660
661void QtGradientEditorPrivate::centralConicalChanged(const QPointF &point)
662{
663 setCentralConical(point);
664 updateGradient(true);
665}
666
667void QtGradientEditorPrivate::angleConicalChanged(qreal angle)
668{
669 setAngleConical(angle);
670 updateGradient(true);
671}
672
673void QtGradientEditorPrivate::setStartLinear(const QPointF &point)
674{
675 if (startLinearXSpinBox)
676 startLinearXSpinBox->setValue(point.x());
677 if (startLinearYSpinBox)
678 startLinearYSpinBox->setValue(point.y());
679}
680
681void QtGradientEditorPrivate::setEndLinear(const QPointF &point)
682{
683 if (endLinearXSpinBox)
684 endLinearXSpinBox->setValue(point.x());
685 if (endLinearYSpinBox)
686 endLinearYSpinBox->setValue(point.y());
687}
688
689void QtGradientEditorPrivate::setCentralRadial(const QPointF &point)
690{
691 if (centralRadialXSpinBox)
692 centralRadialXSpinBox->setValue(point.x());
693 if (centralRadialYSpinBox)
694 centralRadialYSpinBox->setValue(point.y());
695}
696
697void QtGradientEditorPrivate::setFocalRadial(const QPointF &point)
698{
699 if (focalRadialXSpinBox)
700 focalRadialXSpinBox->setValue(point.x());
701 if (focalRadialYSpinBox)
702 focalRadialYSpinBox->setValue(point.y());
703}
704
705void QtGradientEditorPrivate::setRadiusRadial(qreal radius)
706{
707 if (radiusRadialSpinBox)
708 radiusRadialSpinBox->setValue(radius);
709}
710
711void QtGradientEditorPrivate::setCentralConical(const QPointF &point)
712{
713 if (centralConicalXSpinBox)
714 centralConicalXSpinBox->setValue(point.x());
715 if (centralConicalYSpinBox)
716 centralConicalYSpinBox->setValue(point.y());
717}
718
719void QtGradientEditorPrivate::setAngleConical(qreal angle)
720{
721 if (angleConicalSpinBox)
722 angleConicalSpinBox->setValue(angle);
723}
724
725QtGradientEditor::QtGradientEditor(QWidget *parent)
726 : QWidget(parent), d_ptr(new QtGradientEditorPrivate())
727{
728 d_ptr->q_ptr = this;
729 d_ptr->m_type = QGradient::RadialGradient;
730 d_ptr->m_ui.setupUi(this);
731 d_ptr->m_gridLayout = 0;
732 d_ptr->m_hiddenLayout = 0;
733 d_ptr->m_hiddenWidget = 0;
734 bool detailsDefault = false;
735 d_ptr->m_details = !detailsDefault;
736 d_ptr->m_detailsButtonVisible = true;
737 bool checkeredDefault = true;
738 d_ptr->m_backgroundCheckered = !checkeredDefault;
739 d_ptr->m_gradientStopsController = new QtGradientStopsController(this);
740 d_ptr->m_gradientStopsController->setUi(&d_ptr->m_ui);
741 d_ptr->reset();
742 d_ptr->setType(QGradient::LinearGradient);
743 d_ptr->m_combos = true;
744 d_ptr->setCombos(!d_ptr->m_combos);
745
746 d_ptr->showDetails(detailsDefault);
747 setBackgroundCheckered(checkeredDefault);
748
749 d_ptr->setStartLinear(QPointF(0, 0));
750 d_ptr->setEndLinear(QPointF(1, 1));
751 d_ptr->setCentralRadial(QPointF(0.5, 0.5));
752 d_ptr->setFocalRadial(QPointF(0.5, 0.5));
753 d_ptr->setRadiusRadial(0.5);
754 d_ptr->setCentralConical(QPointF(0.5, 0.5));
755 d_ptr->setAngleConical(0);
756
757 QIcon icon;
758 icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowRight), QIcon::Normal, QIcon::Off);
759 icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowLeft), QIcon::Normal, QIcon::On);
760 d_ptr->m_ui.detailsButton->setIcon(icon);
761
762 connect(d_ptr->m_ui.detailsButton, SIGNAL(clicked(bool)), this, SLOT(slotDetailsChanged(bool)));
763 connect(d_ptr->m_gradientStopsController, SIGNAL(gradientStopsChanged(QGradientStops)),
764 this, SLOT(slotGradientStopsChanged(QGradientStops)));
765
766 QIcon iconLinear(QLatin1String(":/qt-project.org/qtgradienteditor/images/typelinear.png"));
767 QIcon iconRadial(QLatin1String(":/qt-project.org/qtgradienteditor/images/typeradial.png"));
768 QIcon iconConical(QLatin1String(":/qt-project.org/qtgradienteditor/images/typeconical.png"));
769
770 d_ptr->m_ui.typeComboBox->addItem(iconLinear, tr("Linear"));
771 d_ptr->m_ui.typeComboBox->addItem(iconRadial, tr("Radial"));
772 d_ptr->m_ui.typeComboBox->addItem(iconConical, tr("Conical"));
773
774 d_ptr->m_ui.linearButton->setIcon(iconLinear);
775 d_ptr->m_ui.radialButton->setIcon(iconRadial);
776 d_ptr->m_ui.conicalButton->setIcon(iconConical);
777
778 d_ptr->m_typeGroup = new QButtonGroup(this);
779 d_ptr->m_typeGroup->addButton(d_ptr->m_ui.linearButton, 0);
780 d_ptr->m_typeGroup->addButton(d_ptr->m_ui.radialButton, 1);
781 d_ptr->m_typeGroup->addButton(d_ptr->m_ui.conicalButton, 2);
782
783 connect(d_ptr->m_typeGroup, SIGNAL(buttonClicked(int)),
784 this, SLOT(slotTypeChanged(int)));
785 connect(d_ptr->m_ui.typeComboBox, SIGNAL(activated(int)),
786 this, SLOT(slotTypeChanged(int)));
787
788 QIcon iconPad(QLatin1String(":/qt-project.org/qtgradienteditor/images/spreadpad.png"));
789 QIcon iconRepeat(QLatin1String(":/qt-project.org/qtgradienteditor/images/spreadrepeat.png"));
790 QIcon iconReflect(QLatin1String(":/qt-project.org/qtgradienteditor/images/spreadreflect.png"));
791
792 d_ptr->m_ui.spreadComboBox->addItem(iconPad, tr("Pad"));
793 d_ptr->m_ui.spreadComboBox->addItem(iconRepeat, tr("Repeat"));
794 d_ptr->m_ui.spreadComboBox->addItem(iconReflect, tr("Reflect"));
795
796 d_ptr->m_ui.padButton->setIcon(iconPad);
797 d_ptr->m_ui.repeatButton->setIcon(iconRepeat);
798 d_ptr->m_ui.reflectButton->setIcon(iconReflect);
799
800 d_ptr->m_spreadGroup = new QButtonGroup(this);
801 d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.padButton, 0);
802 d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.repeatButton, 1);
803 d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.reflectButton, 2);
804 connect(d_ptr->m_spreadGroup, SIGNAL(buttonClicked(int)),
805 this, SLOT(slotSpreadChanged(int)));
806 connect(d_ptr->m_ui.spreadComboBox, SIGNAL(activated(int)),
807 this, SLOT(slotSpreadChanged(int)));
808
809 connect(d_ptr->m_ui.gradientWidget, SIGNAL(startLinearChanged(QPointF)),
810 this, SLOT(startLinearChanged(QPointF)));
811 connect(d_ptr->m_ui.gradientWidget, SIGNAL(endLinearChanged(QPointF)),
812 this, SLOT(endLinearChanged(QPointF)));
813 connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralRadialChanged(QPointF)),
814 this, SLOT(centralRadialChanged(QPointF)));
815 connect(d_ptr->m_ui.gradientWidget, SIGNAL(focalRadialChanged(QPointF)),
816 this, SLOT(focalRadialChanged(QPointF)));
817 connect(d_ptr->m_ui.gradientWidget, SIGNAL(radiusRadialChanged(qreal)),
818 this, SLOT(radiusRadialChanged(qreal)));
819 connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralConicalChanged(QPointF)),
820 this, SLOT(centralConicalChanged(QPointF)));
821 connect(d_ptr->m_ui.gradientWidget, SIGNAL(angleConicalChanged(qreal)),
822 this, SLOT(angleConicalChanged(qreal)));
823
824 QGradientStops stops = gradient().stops();
825 d_ptr->m_gradientStopsController->setGradientStops(stops);
826 d_ptr->m_ui.gradientWidget->setGradientStops(stops);
827}
828
829QtGradientEditor::~QtGradientEditor()
830{
831 if (d_ptr->m_hiddenWidget)
832 delete d_ptr->m_hiddenWidget;
833}
834
835void QtGradientEditor::setGradient(const QGradient &grad)
836{
837 if (grad == gradient())
838 return;
839
840 QGradient::Type type = grad.type();
841 int idx = 0;
842 switch (type) {
843 case QGradient::LinearGradient: idx = 0; break;
844 case QGradient::RadialGradient: idx = 1; break;
845 case QGradient::ConicalGradient: idx = 2; break;
846 default: return;
847 }
848 d_ptr->setType(type);
849 d_ptr->m_ui.typeComboBox->setCurrentIndex(idx);
850 d_ptr->m_ui.gradientWidget->setGradientType(type);
851 d_ptr->m_typeGroup->button(idx)->setChecked(true);
852
853 QGradient::Spread spread = grad.spread();
854 switch (spread) {
855 case QGradient::PadSpread: idx = 0; break;
856 case QGradient::RepeatSpread: idx = 1; break;
857 case QGradient::ReflectSpread: idx = 2; break;
858 default: idx = 0; break;
859 }
860 d_ptr->m_ui.spreadComboBox->setCurrentIndex(idx);
861 d_ptr->m_ui.gradientWidget->setGradientSpread(spread);
862 d_ptr->m_spreadGroup->button(idx)->setChecked(true);
863
864 if (type == QGradient::LinearGradient) {
865 const QLinearGradient *gr = static_cast<const QLinearGradient *>(&grad);
866 d_ptr->setStartLinear(gr->start());
867 d_ptr->setEndLinear(gr->finalStop());
868 d_ptr->m_ui.gradientWidget->setStartLinear(gr->start());
869 d_ptr->m_ui.gradientWidget->setEndLinear(gr->finalStop());
870 } else if (type == QGradient::RadialGradient) {
871 const QRadialGradient *gr = static_cast<const QRadialGradient *>(&grad);
872 d_ptr->setCentralRadial(gr->center());
873 d_ptr->setFocalRadial(gr->focalPoint());
874 d_ptr->setRadiusRadial(gr->radius());
875 d_ptr->m_ui.gradientWidget->setCentralRadial(gr->center());
876 d_ptr->m_ui.gradientWidget->setFocalRadial(gr->focalPoint());
877 d_ptr->m_ui.gradientWidget->setRadiusRadial(gr->radius());
878 } else if (type == QGradient::ConicalGradient) {
879 const QConicalGradient *gr = static_cast<const QConicalGradient *>(&grad);
880 d_ptr->setCentralConical(gr->center());
881 d_ptr->setAngleConical(gr->angle());
882 d_ptr->m_ui.gradientWidget->setCentralConical(gr->center());
883 d_ptr->m_ui.gradientWidget->setAngleConical(gr->angle());
884 }
885
886 d_ptr->m_gradientStopsController->setGradientStops(grad.stops());
887 d_ptr->m_ui.gradientWidget->setGradientStops(grad.stops());
888 d_ptr->updateGradient(false);
889}
890
891QGradient QtGradientEditor::gradient() const
892{
893 return d_ptr->m_gradient;
894}
895
896bool QtGradientEditor::isBackgroundCheckered() const
897{
898 return d_ptr->m_backgroundCheckered;
899}
900
901void QtGradientEditor::setBackgroundCheckered(bool checkered)
902{
903 if (d_ptr->m_backgroundCheckered == checkered)
904 return;
905
906 d_ptr->m_backgroundCheckered = checkered;
907 d_ptr->m_ui.hueColorLine->setBackgroundCheckered(checkered);
908 d_ptr->m_ui.saturationColorLine->setBackgroundCheckered(checkered);
909 d_ptr->m_ui.valueColorLine->setBackgroundCheckered(checkered);
910 d_ptr->m_ui.alphaColorLine->setBackgroundCheckered(checkered);
911 d_ptr->m_ui.gradientWidget->setBackgroundCheckered(checkered);
912 d_ptr->m_ui.gradientStopsWidget->setBackgroundCheckered(checkered);
913 d_ptr->m_ui.colorButton->setBackgroundCheckered(checkered);
914}
915
916bool QtGradientEditor::detailsVisible() const
917{
918 return d_ptr->m_details;
919}
920
921void QtGradientEditor::setDetailsVisible(bool visible)
922{
923 d_ptr->showDetails(visible);
924}
925
926bool QtGradientEditor::isDetailsButtonVisible() const
927{
928 return d_ptr->m_detailsButtonVisible;
929}
930
931void QtGradientEditor::setDetailsButtonVisible(bool visible)
932{
933 if (d_ptr->m_detailsButtonVisible == visible)
934 return;
935
936 d_ptr->m_detailsButtonVisible = visible;
937 d_ptr->m_ui.detailsButton->setVisible(visible);
938}
939
940QColor::Spec QtGradientEditor::spec() const
941{
942 return d_ptr->m_gradientStopsController->spec();
943}
944
945void QtGradientEditor::setSpec(QColor::Spec spec)
946{
947 d_ptr->m_gradientStopsController->setSpec(spec);
948}
949
950QT_END_NAMESPACE
951
952#include "moc_qtgradienteditor.cpp"
953