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 demonstration applications 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 "view.h"
52
53#if defined(QT_PRINTSUPPORT_LIB)
54#include <QtPrintSupport/qtprintsupportglobal.h>
55#if QT_CONFIG(printdialog)
56#include <QPrinter>
57#include <QPrintDialog>
58#endif
59#endif
60#ifndef QT_NO_OPENGL
61#include <QtOpenGL>
62#else
63#include <QtWidgets>
64#endif
65#include <QtMath>
66
67#if QT_CONFIG(wheelevent)
68void GraphicsView::wheelEvent(QWheelEvent *e)
69{
70 if (e->modifiers() & Qt::ControlModifier) {
71 if (e->angleDelta().y() > 0)
72 view->zoomIn(level: 6);
73 else
74 view->zoomOut(level: 6);
75 e->accept();
76 } else {
77 QGraphicsView::wheelEvent(event: e);
78 }
79}
80#endif
81
82View::View(const QString &name, QWidget *parent)
83 : QFrame(parent)
84{
85 setFrameStyle(Sunken | StyledPanel);
86 graphicsView = new GraphicsView(this);
87 graphicsView->setRenderHint(hint: QPainter::Antialiasing, enabled: false);
88 graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
89 graphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
90 graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
91 graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
92
93 int size = style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize);
94 QSize iconSize(size, size);
95
96 QToolButton *zoomInIcon = new QToolButton;
97 zoomInIcon->setAutoRepeat(true);
98 zoomInIcon->setAutoRepeatInterval(33);
99 zoomInIcon->setAutoRepeatDelay(0);
100 zoomInIcon->setIcon(QPixmap(":/zoomin.png"));
101 zoomInIcon->setIconSize(iconSize);
102 QToolButton *zoomOutIcon = new QToolButton;
103 zoomOutIcon->setAutoRepeat(true);
104 zoomOutIcon->setAutoRepeatInterval(33);
105 zoomOutIcon->setAutoRepeatDelay(0);
106 zoomOutIcon->setIcon(QPixmap(":/zoomout.png"));
107 zoomOutIcon->setIconSize(iconSize);
108 zoomSlider = new QSlider;
109 zoomSlider->setMinimum(0);
110 zoomSlider->setMaximum(500);
111 zoomSlider->setValue(250);
112 zoomSlider->setTickPosition(QSlider::TicksRight);
113
114 // Zoom slider layout
115 QVBoxLayout *zoomSliderLayout = new QVBoxLayout;
116 zoomSliderLayout->addWidget(zoomInIcon);
117 zoomSliderLayout->addWidget(zoomSlider);
118 zoomSliderLayout->addWidget(zoomOutIcon);
119
120 QToolButton *rotateLeftIcon = new QToolButton;
121 rotateLeftIcon->setIcon(QPixmap(":/rotateleft.png"));
122 rotateLeftIcon->setIconSize(iconSize);
123 QToolButton *rotateRightIcon = new QToolButton;
124 rotateRightIcon->setIcon(QPixmap(":/rotateright.png"));
125 rotateRightIcon->setIconSize(iconSize);
126 rotateSlider = new QSlider;
127 rotateSlider->setOrientation(Qt::Horizontal);
128 rotateSlider->setMinimum(-360);
129 rotateSlider->setMaximum(360);
130 rotateSlider->setValue(0);
131 rotateSlider->setTickPosition(QSlider::TicksBelow);
132
133 // Rotate slider layout
134 QHBoxLayout *rotateSliderLayout = new QHBoxLayout;
135 rotateSliderLayout->addWidget(rotateLeftIcon);
136 rotateSliderLayout->addWidget(rotateSlider);
137 rotateSliderLayout->addWidget(rotateRightIcon);
138
139 resetButton = new QToolButton;
140 resetButton->setText(tr(s: "0"));
141 resetButton->setEnabled(false);
142
143 // Label layout
144 QHBoxLayout *labelLayout = new QHBoxLayout;
145 label = new QLabel(name);
146 label2 = new QLabel(tr(s: "Pointer Mode"));
147 selectModeButton = new QToolButton;
148 selectModeButton->setText(tr(s: "Select"));
149 selectModeButton->setCheckable(true);
150 selectModeButton->setChecked(true);
151 dragModeButton = new QToolButton;
152 dragModeButton->setText(tr(s: "Drag"));
153 dragModeButton->setCheckable(true);
154 dragModeButton->setChecked(false);
155 antialiasButton = new QToolButton;
156 antialiasButton->setText(tr(s: "Antialiasing"));
157 antialiasButton->setCheckable(true);
158 antialiasButton->setChecked(false);
159 openGlButton = new QToolButton;
160 openGlButton->setText(tr(s: "OpenGL"));
161 openGlButton->setCheckable(true);
162#ifndef QT_NO_OPENGL
163 openGlButton->setEnabled(QGLFormat::hasOpenGL());
164#else
165 openGlButton->setEnabled(false);
166#endif
167 printButton = new QToolButton;
168 printButton->setIcon(QIcon(QPixmap(":/fileprint.png")));
169
170 QButtonGroup *pointerModeGroup = new QButtonGroup(this);
171 pointerModeGroup->setExclusive(true);
172 pointerModeGroup->addButton(selectModeButton);
173 pointerModeGroup->addButton(dragModeButton);
174
175 labelLayout->addWidget(label);
176 labelLayout->addStretch();
177 labelLayout->addWidget(label2);
178 labelLayout->addWidget(selectModeButton);
179 labelLayout->addWidget(dragModeButton);
180 labelLayout->addStretch();
181 labelLayout->addWidget(antialiasButton);
182 labelLayout->addWidget(openGlButton);
183 labelLayout->addWidget(printButton);
184
185 QGridLayout *topLayout = new QGridLayout;
186 topLayout->addLayout(labelLayout, row: 0, column: 0);
187 topLayout->addWidget(graphicsView, row: 1, column: 0);
188 topLayout->addLayout(zoomSliderLayout, row: 1, column: 1);
189 topLayout->addLayout(rotateSliderLayout, row: 2, column: 0);
190 topLayout->addWidget(resetButton, row: 2, column: 1);
191 setLayout(topLayout);
192
193 connect(sender: resetButton, signal: &QAbstractButton::clicked, receiver: this, slot: &View::resetView);
194 connect(sender: zoomSlider, signal: &QAbstractSlider::valueChanged, receiver: this, slot: &View::setupMatrix);
195 connect(sender: rotateSlider, signal: &QAbstractSlider::valueChanged, receiver: this, slot: &View::setupMatrix);
196 connect(sender: graphicsView->verticalScrollBar(), signal: &QAbstractSlider::valueChanged,
197 receiver: this, slot: &View::setResetButtonEnabled);
198 connect(sender: graphicsView->horizontalScrollBar(), signal: &QAbstractSlider::valueChanged,
199 receiver: this, slot: &View::setResetButtonEnabled);
200 connect(sender: selectModeButton, signal: &QAbstractButton::toggled, receiver: this, slot: &View::togglePointerMode);
201 connect(sender: dragModeButton, signal: &QAbstractButton::toggled, receiver: this, slot: &View::togglePointerMode);
202 connect(sender: antialiasButton, signal: &QAbstractButton::toggled, receiver: this, slot: &View::toggleAntialiasing);
203 connect(sender: openGlButton, signal: &QAbstractButton::toggled, receiver: this, slot: &View::toggleOpenGL);
204 connect(sender: rotateLeftIcon, signal: &QAbstractButton::clicked, receiver: this, slot: &View::rotateLeft);
205 connect(sender: rotateRightIcon, signal: &QAbstractButton::clicked, receiver: this, slot: &View::rotateRight);
206 connect(sender: zoomInIcon, signal: &QAbstractButton::clicked, receiver: this, slot: &View::zoomIn);
207 connect(sender: zoomOutIcon, signal: &QAbstractButton::clicked, receiver: this, slot: &View::zoomOut);
208 connect(sender: printButton, signal: &QAbstractButton::clicked, receiver: this, slot: &View::print);
209
210 setupMatrix();
211}
212
213QGraphicsView *View::view() const
214{
215 return static_cast<QGraphicsView *>(graphicsView);
216}
217
218void View::resetView()
219{
220 zoomSlider->setValue(250);
221 rotateSlider->setValue(0);
222 setupMatrix();
223 graphicsView->ensureVisible(rect: QRectF(0, 0, 0, 0));
224
225 resetButton->setEnabled(false);
226}
227
228void View::setResetButtonEnabled()
229{
230 resetButton->setEnabled(true);
231}
232
233void View::setupMatrix()
234{
235 qreal scale = qPow(x: qreal(2), y: (zoomSlider->value() - 250) / qreal(50));
236
237 QTransform matrix;
238 matrix.scale(sx: scale, sy: scale);
239 matrix.rotate(a: rotateSlider->value());
240
241 graphicsView->setTransform(matrix);
242 setResetButtonEnabled();
243}
244
245void View::togglePointerMode()
246{
247 graphicsView->setDragMode(selectModeButton->isChecked()
248 ? QGraphicsView::RubberBandDrag
249 : QGraphicsView::ScrollHandDrag);
250 graphicsView->setInteractive(selectModeButton->isChecked());
251}
252
253void View::toggleOpenGL()
254{
255#ifndef QT_NO_OPENGL
256 graphicsView->setViewport(openGlButton->isChecked() ? new QGLWidget(QGLFormat(QGL::SampleBuffers)) : new QWidget);
257#endif
258}
259
260void View::toggleAntialiasing()
261{
262 graphicsView->setRenderHint(hint: QPainter::Antialiasing, enabled: antialiasButton->isChecked());
263}
264
265void View::print()
266{
267#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
268 QPrinter printer;
269 QPrintDialog dialog(&printer, this);
270 if (dialog.exec() == QDialog::Accepted) {
271 QPainter painter(&printer);
272 graphicsView->render(painter: &painter);
273 }
274#endif
275}
276
277void View::zoomIn(int level)
278{
279 zoomSlider->setValue(zoomSlider->value() + level);
280}
281
282void View::zoomOut(int level)
283{
284 zoomSlider->setValue(zoomSlider->value() - level);
285}
286
287void View::rotateLeft()
288{
289 rotateSlider->setValue(rotateSlider->value() - 10);
290}
291
292void View::rotateRight()
293{
294 rotateSlider->setValue(rotateSlider->value() + 10);
295}
296

source code of qtbase/examples/widgets/graphicsview/chip/view.cpp