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 examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
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** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include "renderarea.h"
52#include "window.h"
53
54#include <QtWidgets>
55
56#include <qmath.h>
57
58//! [1]
59Window::Window()
60{
61 QPainterPath rectPath;
62 rectPath.moveTo(20.0, 30.0);
63 rectPath.lineTo(80.0, 30.0);
64 rectPath.lineTo(80.0, 70.0);
65 rectPath.lineTo(20.0, 70.0);
66 rectPath.closeSubpath();
67//! [1]
68
69//! [2]
70 QPainterPath roundRectPath;
71 roundRectPath.moveTo(80.0, 35.0);
72 roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0);
73 roundRectPath.lineTo(25.0, 30.0);
74 roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0);
75 roundRectPath.lineTo(20.0, 65.0);
76 roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0);
77 roundRectPath.lineTo(75.0, 70.0);
78 roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0);
79 roundRectPath.closeSubpath();
80//! [2]
81
82//! [3]
83 QPainterPath ellipsePath;
84 ellipsePath.moveTo(80.0, 50.0);
85 ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0);
86//! [3]
87
88//! [4]
89 QPainterPath piePath;
90 piePath.moveTo(50.0, 50.0);
91 piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0);
92 piePath.closeSubpath();
93//! [4]
94
95//! [5]
96 QPainterPath polygonPath;
97 polygonPath.moveTo(10.0, 80.0);
98 polygonPath.lineTo(20.0, 10.0);
99 polygonPath.lineTo(80.0, 30.0);
100 polygonPath.lineTo(90.0, 70.0);
101 polygonPath.closeSubpath();
102//! [5]
103
104//! [6]
105 QPainterPath groupPath;
106 groupPath.moveTo(60.0, 40.0);
107 groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0);
108 groupPath.moveTo(40.0, 40.0);
109 groupPath.lineTo(40.0, 80.0);
110 groupPath.lineTo(80.0, 80.0);
111 groupPath.lineTo(80.0, 40.0);
112 groupPath.closeSubpath();
113//! [6]
114
115//! [7]
116 QPainterPath textPath;
117 QFont timesFont("Times", 50);
118 timesFont.setStyleStrategy(QFont::ForceOutline);
119 textPath.addText(10, 70, timesFont, tr("Qt"));
120//! [7]
121
122//! [8]
123 QPainterPath bezierPath;
124 bezierPath.moveTo(20, 30);
125 bezierPath.cubicTo(80, 0, 50, 50, 80, 80);
126//! [8]
127
128//! [9]
129 QPainterPath starPath;
130 starPath.moveTo(90, 50);
131 for (int i = 1; i < 5; ++i) {
132 starPath.lineTo(50 + 40 * std::cos(0.8 * i * M_PI),
133 50 + 40 * std::sin(0.8 * i * M_PI));
134 }
135 starPath.closeSubpath();
136//! [9]
137
138//! [10]
139 renderAreas.push_back(new RenderArea(rectPath));
140 renderAreas.push_back(new RenderArea(roundRectPath));
141 renderAreas.push_back(new RenderArea(ellipsePath));
142 renderAreas.push_back(new RenderArea(piePath));
143 renderAreas.push_back(new RenderArea(polygonPath));
144 renderAreas.push_back(new RenderArea(groupPath));
145 renderAreas.push_back(new RenderArea(textPath));
146 renderAreas.push_back(new RenderArea(bezierPath));
147 renderAreas.push_back(new RenderArea(starPath));
148//! [10]
149
150//! [11]
151 fillRuleComboBox = new QComboBox;
152 fillRuleComboBox->addItem(tr("Odd Even"), Qt::OddEvenFill);
153 fillRuleComboBox->addItem(tr("Winding"), Qt::WindingFill);
154
155 fillRuleLabel = new QLabel(tr("Fill &Rule:"));
156 fillRuleLabel->setBuddy(fillRuleComboBox);
157//! [11]
158
159//! [12]
160 fillColor1ComboBox = new QComboBox;
161 populateWithColors(fillColor1ComboBox);
162 fillColor1ComboBox->setCurrentIndex(fillColor1ComboBox->findText("mediumslateblue"));
163
164 fillColor2ComboBox = new QComboBox;
165 populateWithColors(fillColor2ComboBox);
166 fillColor2ComboBox->setCurrentIndex(fillColor2ComboBox->findText("cornsilk"));
167
168 fillGradientLabel = new QLabel(tr("&Fill Gradient:"));
169 fillGradientLabel->setBuddy(fillColor1ComboBox);
170
171 fillToLabel = new QLabel(tr("to"));
172 fillToLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
173
174 penWidthSpinBox = new QSpinBox;
175 penWidthSpinBox->setRange(0, 20);
176
177 penWidthLabel = new QLabel(tr("&Pen Width:"));
178 penWidthLabel->setBuddy(penWidthSpinBox);
179
180 penColorComboBox = new QComboBox;
181 populateWithColors(penColorComboBox);
182 penColorComboBox->setCurrentIndex(penColorComboBox->findText("darkslateblue"));
183
184 penColorLabel = new QLabel(tr("Pen &Color:"));
185 penColorLabel->setBuddy(penColorComboBox);
186
187 rotationAngleSpinBox = new QSpinBox;
188 rotationAngleSpinBox->setRange(0, 359);
189 rotationAngleSpinBox->setWrapping(true);
190 rotationAngleSpinBox->setSuffix(QLatin1String("\xB0"));
191
192 rotationAngleLabel = new QLabel(tr("&Rotation Angle:"));
193 rotationAngleLabel->setBuddy(rotationAngleSpinBox);
194//! [12]
195
196//! [16]
197 connect(fillRuleComboBox, &QComboBox::activated,
198 this, &Window::fillRuleChanged);
199 connect(fillColor1ComboBox, &QComboBox::activated,
200 this, &Window::fillGradientChanged);
201 connect(fillColor2ComboBox, &QComboBox::activated,
202 this, &Window::fillGradientChanged);
203 connect(penColorComboBox, &QComboBox::activated,
204 this, &Window::penColorChanged);
205
206 for (RenderArea *area : qAsConst(renderAreas)) {
207 connect(penWidthSpinBox, &QSpinBox::valueChanged,
208 area, &RenderArea::setPenWidth);
209 connect(rotationAngleSpinBox, &QSpinBox::valueChanged,
210 area, &RenderArea::setRotationAngle);
211 }
212
213//! [16] //! [17]
214 QGridLayout *topLayout = new QGridLayout;
215
216 int i = 0;
217 for (RenderArea *area : qAsConst(renderAreas)) {
218 topLayout->addWidget(area, i / 3, i % 3);
219 ++i;
220 }
221
222 QGridLayout *mainLayout = new QGridLayout;
223 mainLayout->addLayout(topLayout, 0, 0, 1, 4);
224 mainLayout->addWidget(fillRuleLabel, 1, 0);
225 mainLayout->addWidget(fillRuleComboBox, 1, 1, 1, 3);
226 mainLayout->addWidget(fillGradientLabel, 2, 0);
227 mainLayout->addWidget(fillColor1ComboBox, 2, 1);
228 mainLayout->addWidget(fillToLabel, 2, 2);
229 mainLayout->addWidget(fillColor2ComboBox, 2, 3);
230 mainLayout->addWidget(penWidthLabel, 3, 0);
231 mainLayout->addWidget(penWidthSpinBox, 3, 1, 1, 3);
232 mainLayout->addWidget(penColorLabel, 4, 0);
233 mainLayout->addWidget(penColorComboBox, 4, 1, 1, 3);
234 mainLayout->addWidget(rotationAngleLabel, 5, 0);
235 mainLayout->addWidget(rotationAngleSpinBox, 5, 1, 1, 3);
236 setLayout(mainLayout);
237//! [17]
238
239//! [18]
240 fillRuleChanged();
241 fillGradientChanged();
242 penColorChanged();
243 penWidthSpinBox->setValue(2);
244
245 setWindowTitle(tr("Painter Paths"));
246}
247//! [18]
248
249//! [19]
250void Window::fillRuleChanged()
251{
252 Qt::FillRule rule = (Qt::FillRule)currentItemData(fillRuleComboBox).toInt();
253
254 for (RenderArea *area : qAsConst(renderAreas))
255 area->setFillRule(rule);
256}
257//! [19]
258
259//! [20]
260void Window::fillGradientChanged()
261{
262 QColor color1 = qvariant_cast<QColor>(currentItemData(fillColor1ComboBox));
263 QColor color2 = qvariant_cast<QColor>(currentItemData(fillColor2ComboBox));
264
265 for (RenderArea *area : qAsConst(renderAreas))
266 area->setFillGradient(color1, color2);
267}
268//! [20]
269
270//! [21]
271void Window::penColorChanged()
272{
273 QColor color = qvariant_cast<QColor>(currentItemData(penColorComboBox));
274
275 for (RenderArea *area : qAsConst(renderAreas))
276 area->setPenColor(color);
277}
278//! [21]
279
280//! [22]
281void Window::populateWithColors(QComboBox *comboBox)
282{
283 const QStringList colorNames = QColor::colorNames();
284 for (const QString &name : colorNames)
285 comboBox->addItem(name, QColor(name));
286}
287//! [22]
288
289//! [23]
290QVariant Window::currentItemData(QComboBox *comboBox)
291{
292 return comboBox->itemData(comboBox->currentIndex());
293}
294//! [23]
295