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