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] |
59 | Window::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] |
250 | void 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] |
260 | void 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] |
271 | void 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] |
281 | void 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] |
290 | QVariant Window::currentItemData(QComboBox *comboBox) |
291 | { |
292 | return comboBox->itemData(index: comboBox->currentIndex()); |
293 | } |
294 | //! [23] |
295 | |