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 <QPainter> |
52 | #include <QApplication> |
53 | |
54 | #include "embeddedsvgviewer.h" |
55 | |
56 | |
57 | |
58 | EmbeddedSvgViewer::EmbeddedSvgViewer(const QString &filePath) |
59 | { |
60 | qApp->setStyleSheet(" QSlider:vertical { width: 50px; } \ |
61 | QSlider::groove:vertical { border: 1px solid black; border-radius: 3px; width: 6px; } \ |
62 | QSlider::handle:vertical { height: 25px; margin: 0 -22px; image: url(':/files/v-slider-handle.svg'); } \ |
63 | " ); |
64 | |
65 | m_renderer = new QSvgRenderer(filePath); |
66 | m_imageSize = m_renderer->viewBox().size(); |
67 | |
68 | m_viewBoxCenter = (QPointF(m_imageSize.width() / qreal(2.0), m_imageSize.height() / qreal(2.0))); |
69 | |
70 | m_zoomSlider = new QSlider(Qt::Vertical, this); |
71 | m_zoomSlider->setMaximum(150); |
72 | m_zoomSlider->setMinimum(1); |
73 | |
74 | connect(sender: m_zoomSlider, SIGNAL(valueChanged(int)), receiver: this, SLOT(setZoom(int))); |
75 | m_zoomSlider->setValue(100); |
76 | |
77 | m_quitButton = new QPushButton("Quit" , this); |
78 | |
79 | connect(sender: m_quitButton, SIGNAL(pressed()), receiver: QApplication::instance(), SLOT(quit())); |
80 | |
81 | if (m_renderer->animated()) |
82 | connect(sender: m_renderer, SIGNAL(repaintNeeded()), receiver: this, SLOT(update())); |
83 | |
84 | } |
85 | |
86 | void EmbeddedSvgViewer::paintEvent(QPaintEvent *event) |
87 | { |
88 | Q_UNUSED(event) |
89 | QPainter painter(this); |
90 | m_renderer->setViewBox(m_viewBox); |
91 | m_renderer->render(p: &painter); |
92 | } |
93 | |
94 | |
95 | void EmbeddedSvgViewer::mouseMoveEvent ( QMouseEvent * event ) |
96 | { |
97 | int incX = int((event->globalX() - m_mousePress.x()) * m_imageScale); |
98 | int incY = int((event->globalY() - m_mousePress.y()) * m_imageScale); |
99 | |
100 | QPointF newCenter; |
101 | newCenter.setX(m_viewBoxCenterOnMousePress.x() - incX); |
102 | newCenter.setY(m_viewBoxCenterOnMousePress.y() - incY); |
103 | |
104 | QRectF newViewBox = getViewBox(viewBoxCenter: newCenter); |
105 | |
106 | |
107 | // Do a bounded move on the horizontal: |
108 | if ( (newViewBox.left() >= m_viewBoxBounds.left()) && |
109 | (newViewBox.right() <= m_viewBoxBounds.right()) ) |
110 | { |
111 | m_viewBoxCenter.setX(newCenter.x()); |
112 | m_viewBox.setLeft(newViewBox.left()); |
113 | m_viewBox.setRight(newViewBox.right()); |
114 | } |
115 | |
116 | // do a bounded move on the vertical: |
117 | if ( (newViewBox.top() >= m_viewBoxBounds.top()) && |
118 | (newViewBox.bottom() <= m_viewBoxBounds.bottom()) ) |
119 | { |
120 | m_viewBoxCenter.setY(newCenter.y()); |
121 | m_viewBox.setTop(newViewBox.top()); |
122 | m_viewBox.setBottom(newViewBox.bottom()); |
123 | } |
124 | |
125 | update(); |
126 | } |
127 | |
128 | void EmbeddedSvgViewer::mousePressEvent ( QMouseEvent * event ) |
129 | { |
130 | m_viewBoxCenterOnMousePress = m_viewBoxCenter; |
131 | m_mousePress = event->globalPos(); |
132 | } |
133 | |
134 | |
135 | QRectF EmbeddedSvgViewer::getViewBox(QPointF viewBoxCenter) |
136 | { |
137 | QRectF result; |
138 | result.setLeft(viewBoxCenter.x() - (m_viewBoxSize.width() / 2)); |
139 | result.setTop(viewBoxCenter.y() - (m_viewBoxSize.height() / 2)); |
140 | result.setRight(viewBoxCenter.x() + (m_viewBoxSize.width() / 2)); |
141 | result.setBottom(viewBoxCenter.y() + (m_viewBoxSize.height() / 2)); |
142 | return result; |
143 | } |
144 | |
145 | void EmbeddedSvgViewer::updateImageScale() |
146 | { |
147 | m_imageScale = qMax( a: (qreal)m_imageSize.width() / (qreal)width(), |
148 | b: (qreal)m_imageSize.height() / (qreal)height())*m_zoomLevel; |
149 | |
150 | m_viewBoxSize.setWidth((qreal)width() * m_imageScale); |
151 | m_viewBoxSize.setHeight((qreal)height() * m_imageScale); |
152 | } |
153 | |
154 | |
155 | void EmbeddedSvgViewer::resizeEvent ( QResizeEvent * /* event */ ) |
156 | { |
157 | qreal origZoom = m_zoomLevel; |
158 | |
159 | // Get the new bounds: |
160 | m_zoomLevel = 1.0; |
161 | updateImageScale(); |
162 | m_viewBoxBounds = getViewBox(viewBoxCenter: QPointF(m_imageSize.width() / 2.0, m_imageSize.height() / 2.0)); |
163 | |
164 | m_zoomLevel = origZoom; |
165 | updateImageScale(); |
166 | m_viewBox = getViewBox(viewBoxCenter: m_viewBoxCenter); |
167 | |
168 | QRect sliderRect; |
169 | sliderRect.setLeft(width() - m_zoomSlider->sizeHint().width()); |
170 | sliderRect.setRight(width()); |
171 | sliderRect.setTop(height()/4); |
172 | sliderRect.setBottom(height() - (height()/4)); |
173 | m_zoomSlider->setGeometry(sliderRect); |
174 | } |
175 | |
176 | |
177 | void EmbeddedSvgViewer::setZoom(int newZoom) |
178 | { |
179 | m_zoomLevel = qreal(newZoom) / qreal(100); |
180 | |
181 | updateImageScale(); |
182 | m_viewBox = getViewBox(viewBoxCenter: m_viewBoxCenter); |
183 | |
184 | update(); |
185 | } |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |