summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp')
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp b/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp
new file mode 100644
index 00000000..035e242c
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecamerascrollarea.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "scenecamerascrollarea.h"
+#include "scenecameraglwidget.h"
+#include "Core.h"
+
+#include <QtWidgets/qscrollbar.h>
+#include <QtGui/qevent.h>
+
+SceneCameraScrollArea::SceneCameraScrollArea(QWidget *parent)
+ : QAbstractScrollArea(parent)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ m_glWidget = new SceneCameraGlWidget(this);
+}
+
+SceneCameraScrollArea::~SceneCameraScrollArea()
+{
+}
+
+void SceneCameraScrollArea::setZoom(qreal zoom, const QPoint &zoomPoint)
+{
+ // Calculate the actual presentation point
+ qreal oldH = (horizontalScrollBar()->value() + zoomPoint.x()) / m_zoom;
+ qreal oldV = (verticalScrollBar()->value() + zoomPoint.y()) / m_zoom;
+
+ m_zoom = zoom;
+
+ recalculateScrollRanges();
+
+ // Move the scrollbars so that the actual presentation point stays in the same location
+ horizontalScrollBar()->setValue(qRound(oldH * m_zoom - zoomPoint.x()));
+ verticalScrollBar()->setValue(qRound(oldV * m_zoom - zoomPoint.y()));
+
+ recalculateOffsets();
+
+ Q_EMIT needUpdate();
+}
+
+void SceneCameraScrollArea::setPresentationSize(const QSize &size)
+{
+ if (m_presentationSize != size) {
+ m_presentationSize = size;
+ recalculateScrollRanges();
+ recalculateOffsets();
+ }
+}
+
+void SceneCameraScrollArea::recalculateScrollRanges()
+{
+ const QSizeF presSize = zoomedPresentationSize();
+
+ const QSize viewSize = viewport()->size();
+ horizontalScrollBar()->setRange(0, int(presSize.width() - viewSize.width()));
+ verticalScrollBar()->setRange(0, int(presSize.height() - viewSize.height()));
+ horizontalScrollBar()->setPageStep(viewSize.width());
+ verticalScrollBar()->setPageStep(viewSize.height());
+}
+
+void SceneCameraScrollArea::recalculateOffsets()
+{
+ // Texture offset vector contains normalized rect of the viewable area of the texture
+ const QSize viewSize = viewport()->size();
+ const qreal fullWidth = qreal(horizontalScrollBar()->maximum() + viewSize.width());
+ const qreal fullHeight = qreal(verticalScrollBar()->maximum() + viewSize.height());
+ QVector4D textureOffset(
+ float(horizontalScrollBar()->value() / fullWidth),
+ float((verticalScrollBar()->maximum() - verticalScrollBar()->value()) / fullHeight),
+ float(viewSize.width() / fullWidth), float(viewSize.height() / fullHeight));
+
+ m_glWidget->setTextureOffset(textureOffset);
+
+ // The geometry offset is adjusted to keep aspect ratio when view area is larger than
+ // zoomed width/height. Since the geometry of the quad is in range [-1, 1], the width/height of
+ // the offset is just a direct multiplier to the coordinate.
+ // XY contain the subpixel offset to ensure we don't get artifacts depending on pixel alignment.
+ const QSizeF presSize = zoomedPresentationSize();
+ float subPixelX = 0.0f;
+ float subPixelY = 0.0f;
+ qreal normWidth = 1.0;
+ qreal normHeight = 1.0;
+ if (presSize.width() < fullWidth) {
+ qreal diffX = (fullWidth - qRound(presSize.width())) / 2.0;
+ subPixelX = float((diffX - qRound(diffX)) / fullWidth);
+ normWidth = presSize.width() / fullWidth;
+ }
+ if (presSize.height() < fullHeight) {
+ qreal diffY = (fullHeight - qRound(presSize.height())) / 2.0;
+ subPixelY = float((diffY - qRound(diffY)) / fullHeight);
+ normHeight = presSize.height() / fullHeight;
+ }
+
+ QVector4D geometryOffset(subPixelX, subPixelY, float(normWidth), float(normHeight));
+ m_glWidget->setGeometryOffset(geometryOffset);
+}
+
+void SceneCameraScrollArea::scrollContentsBy(int, int)
+{
+ recalculateOffsets();
+ Q_EMIT needUpdate();
+}
+
+void SceneCameraScrollArea::showEvent(QShowEvent *event)
+{
+ QAbstractScrollArea::showEvent(event);
+
+ recalculateScrollRanges();
+ recalculateOffsets();
+ resizeGlWidget();
+}
+
+void SceneCameraScrollArea::resizeGlWidget()
+{
+ m_glWidget->resize(viewport()->size());
+}
+
+QSizeF SceneCameraScrollArea::zoomedPresentationSize()
+{
+ // Multiply QSize components separately to avoid rounding to integers
+ QSizeF size = QSizeF(m_presentationSize.width() * m_zoom,
+ m_presentationSize.height() * m_zoom);
+ return size;
+}
+
+void SceneCameraScrollArea::resizeEvent(QResizeEvent *event)
+{
+ QAbstractScrollArea::resizeEvent(event);
+
+ recalculateScrollRanges();
+ recalculateOffsets();
+ resizeGlWidget();
+}