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(x: 20.0, y: 30.0);
63 rectPath.lineTo(x: 80.0, y: 30.0);
64 rectPath.lineTo(x: 80.0, y: 70.0);
65 rectPath.lineTo(x: 20.0, y: 70.0);
66 rectPath.closeSubpath();
67//! [1]
68
69//! [2]
70 QPainterPath roundRectPath;
71 roundRectPath.moveTo(x: 80.0, y: 35.0);
72 roundRectPath.arcTo(x: 70.0, y: 30.0, w: 10.0, h: 10.0, startAngle: 0.0, arcLength: 90.0);
73 roundRectPath.lineTo(x: 25.0, y: 30.0);
74 roundRectPath.arcTo(x: 20.0, y: 30.0, w: 10.0, h: 10.0, startAngle: 90.0, arcLength: 90.0);
75 roundRectPath.lineTo(x: 20.0, y: 65.0);
76 roundRectPath.arcTo(x: 20.0, y: 60.0, w: 10.0, h: 10.0, startAngle: 180.0, arcLength: 90.0);
77 roundRectPath.lineTo(x: 75.0, y: 70.0);
78 roundRectPath.arcTo(x: 70.0, y: 60.0, w: 10.0, h: 10.0, startAngle: 270.0, arcLength: 90.0);
79 roundRectPath.closeSubpath();
80//! [2]
81
82//! [3]
83 QPainterPath ellipsePath;
84 ellipsePath.moveTo(x: 80.0, y: 50.0);
85 ellipsePath.arcTo(x: 20.0, y: 30.0, w: 60.0, h: 40.0, startAngle: 0.0, arcLength: 360.0);
86//! [3]
87
88//! [4]
89 QPainterPath piePath;
90 piePath.moveTo(x: 50.0, y: 50.0);
91 piePath.arcTo(x: 20.0, y: 30.0, w: 60.0, h: 40.0, startAngle: 60.0, arcLength: 240.0);
92 piePath.closeSubpath();
93//! [4]
94
95//! [5]
96 QPainterPath polygonPath;
97 polygonPath.moveTo(x: 10.0, y: 80.0);
98 polygonPath.lineTo(x: 20.0, y: 10.0);
99 polygonPath.lineTo(x: 80.0, y: 30.0);
100 polygonPath.lineTo(x: 90.0, y: 70.0);
101 polygonPath.closeSubpath();
102//! [5]
103
104//! [6]
105 QPainterPath groupPath;
106 groupPath.moveTo(x: 60.0, y: 40.0);
107 groupPath.arcTo(x: 20.0, y: 20.0, w: 40.0, h: 40.0, startAngle: 0.0, arcLength: 360.0);
108 groupPath.moveTo(x: 40.0, y: 40.0);
109 groupPath.lineTo(x: 40.0, y: 80.0);
110 groupPath.lineTo(x: 80.0, y: 80.0);
111 groupPath.lineTo(x: 80.0, y: 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(x: 10, y: 70, f: timesFont, text: tr(s: "Qt"));
120//! [7]
121
122//! [8]
123 QPainterPath bezierPath;
124 bezierPath.moveTo(x: 20, y: 30);
125 bezierPath.cubicTo(ctrlPt1x: 80, ctrlPt1y: 0, ctrlPt2x: 50, ctrlPt2y: 50, endPtx: 80, endPty: 80);
126//! [8]
127
128//! [9]
129 QPainterPath starPath;
130 starPath.moveTo(x: 90, y: 50);
131 for (int i = 1; i < 5; ++i) {
132 starPath.lineTo(x: 50 + 40 * std::cos(x: 0.8 * i * M_PI),
133 y: 50 + 40 * std::sin(x: 0.8 * i * M_PI));
134 }
135 starPath.closeSubpath();
136//! [9]
137
138//! [10]
139 renderAreas.push_back(t: new RenderArea(rectPath));
140 renderAreas.push_back(t: new RenderArea(roundRectPath));
141 renderAreas.push_back(t: new RenderArea(ellipsePath));
142 renderAreas.push_back(t: new RenderArea(piePath));
143 renderAreas.push_back(t: new RenderArea(polygonPath));
144 renderAreas.push_back(t: new RenderArea(groupPath));
145 renderAreas.push_back(t: new RenderArea(textPath));
146 renderAreas.push_back(t: new RenderArea(bezierPath));
147 renderAreas.push_back(t: new RenderArea(starPath));
148//! [10]
149
150//! [11]
151 fillRuleComboBox = new QComboBox;
152 fillRuleComboBox->addItem(atext: tr(s: "Odd Even"), auserData: Qt::OddEvenFill);
153 fillRuleComboBox->addItem(atext: tr(s: "Winding"), auserData: Qt::WindingFill);
154
155 fillRuleLabel = new QLabel(tr(s: "Fill &Rule:"));
156 fillRuleLabel->setBuddy(fillRuleComboBox);
157//! [11]
158
159//! [12]
160 fillColor1ComboBox = new QComboBox;
161 populateWithColors(comboBox: fillColor1ComboBox);
162 fillColor1ComboBox->setCurrentIndex(fillColor1ComboBox->findText(text: "mediumslateblue"));
163
164 fillColor2ComboBox = new QComboBox;
165 populateWithColors(comboBox: fillColor2ComboBox);
166 fillColor2ComboBox->setCurrentIndex(fillColor2ComboBox->findText(text: "cornsilk"));
167
168 fillGradientLabel = new QLabel(tr(s: "&Fill Gradient:"));
169 fillGradientLabel->setBuddy(fillColor1ComboBox);
170
171 fillToLabel = new QLabel(tr(s: "to"));
172 fillToLabel->setSizePolicy(hor: QSizePolicy::Fixed, ver: QSizePolicy::Fixed);
173
174 penWidthSpinBox = new QSpinBox;
175 penWidthSpinBox->setRange(min: 0, max: 20);
176
177 penWidthLabel = new QLabel(tr(s: "&Pen Width:"));
178 penWidthLabel->setBuddy(penWidthSpinBox);
179
180 penColorComboBox = new QComboBox;
181 populateWithColors(comboBox: penColorComboBox);
182 penColorComboBox->setCurrentIndex(penColorComboBox->findText(text: "darkslateblue"));
183
184 penColorLabel = new QLabel(tr(s: "Pen &Color:"));
185 penColorLabel->setBuddy(penColorComboBox);
186
187 rotationAngleSpinBox = new QSpinBox;
188 rotationAngleSpinBox->setRange(min: 0, max: 359);
189 rotationAngleSpinBox->setWrapping(true);
190 rotationAngleSpinBox->setSuffix(QLatin1String("\xB0"));
191
192 rotationAngleLabel = new QLabel(tr(s: "&Rotation Angle:"));
193 rotationAngleLabel->setBuddy(rotationAngleSpinBox);
194//! [12]
195
196//! [16]
197 connect(sender: fillRuleComboBox, signal: QOverload<int>::of(ptr: &QComboBox::activated),
198 receiver: this, slot: &Window::fillRuleChanged);
199 connect(sender: fillColor1ComboBox, signal: QOverload<int>::of(ptr: &QComboBox::activated),
200 receiver: this, slot: &Window::fillGradientChanged);
201 connect(sender: fillColor2ComboBox, signal: QOverload<int>::of(ptr: &QComboBox::activated),
202 receiver: this, slot: &Window::fillGradientChanged);
203 connect(sender: penColorComboBox, signal: QOverload<int>::of(ptr: &QComboBox::activated),
204 receiver: this, slot: &Window::penColorChanged);
205
206 for (RenderArea *area : qAsConst(t&: renderAreas)) {
207 connect(sender: penWidthSpinBox, signal: QOverload<int>::of(ptr: &QSpinBox::valueChanged),
208 receiver: area, slot: &RenderArea::setPenWidth);
209 connect(sender: rotationAngleSpinBox, signal: QOverload<int>::of(ptr: &QSpinBox::valueChanged),
210 receiver: area, slot: &RenderArea::setRotationAngle);
211 }
212
213//! [16] //! [17]
214 QGridLayout *topLayout = new QGridLayout;
215
216 int i = 0;
217 for (RenderArea *area : qAsConst(t&: renderAreas)) {
218 topLayout->addWidget(area, row: i / 3, column: i % 3);
219 ++i;
220 }
221
222 QGridLayout *mainLayout = new QGridLayout;
223 mainLayout->addLayout(topLayout, row: 0, column: 0, rowSpan: 1, columnSpan: 4);
224 mainLayout->addWidget(fillRuleLabel, row: 1, column: 0);
225 mainLayout->addWidget(fillRuleComboBox, row: 1, column: 1, rowSpan: 1, columnSpan: 3);
226 mainLayout->addWidget(fillGradientLabel, row: 2, column: 0);
227 mainLayout->addWidget(fillColor1ComboBox, row: 2, column: 1);
228 mainLayout->addWidget(fillToLabel, row: 2, column: 2);
229 mainLayout->addWidget(fillColor2ComboBox, row: 2, column: 3);
230 mainLayout->addWidget(penWidthLabel, row: 3, column: 0);
231 mainLayout->addWidget(penWidthSpinBox, row: 3, column: 1, rowSpan: 1, columnSpan: 3);
232 mainLayout->addWidget(penColorLabel, row: 4, column: 0);
233 mainLayout->addWidget(penColorComboBox, row: 4, column: 1, rowSpan: 1, columnSpan: 3);
234 mainLayout->addWidget(rotationAngleLabel, row: 5, column: 0);
235 mainLayout->addWidget(rotationAngleSpinBox, row: 5, column: 1, rowSpan: 1, columnSpan: 3);
236 setLayout(mainLayout);
237//! [17]
238
239//! [18]
240 fillRuleChanged();
241 fillGradientChanged();
242 penColorChanged();
243 penWidthSpinBox->setValue(2);
244
245 setWindowTitle(tr(s: "Painter Paths"));
246}
247//! [18]
248
249//! [19]
250void Window::fillRuleChanged()
251{
252 Qt::FillRule rule = (Qt::FillRule)currentItemData(comboBox: fillRuleComboBox).toInt();
253
254 for (RenderArea *area : qAsConst(t&: renderAreas))
255 area->setFillRule(rule);
256}
257//! [19]
258
259//! [20]
260void Window::fillGradientChanged()
261{
262 QColor color1 = qvariant_cast<QColor>(v: currentItemData(comboBox: fillColor1ComboBox));
263 QColor color2 = qvariant_cast<QColor>(v: currentItemData(comboBox: fillColor2ComboBox));
264
265 for (RenderArea *area : qAsConst(t&: renderAreas))
266 area->setFillGradient(color1, color2);
267}
268//! [20]
269
270//! [21]
271void Window::penColorChanged()
272{
273 QColor color = qvariant_cast<QColor>(v: currentItemData(comboBox: penColorComboBox));
274
275 for (RenderArea *area : qAsConst(t&: 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(atext: name, auserData: QColor(name));
286}
287//! [22]
288
289//! [23]
290QVariant Window::currentItemData(QComboBox *comboBox)
291{
292 return comboBox->itemData(index: comboBox->currentIndex());
293}
294//! [23]
295

source code of qtbase/examples/widgets/painting/painterpaths/window.cpp