summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/UI
diff options
context:
space:
mode:
authorTomi Korpipaa <tomi.korpipaa@qt.io>2018-05-09 13:28:05 +0300
committerTomi Korpipää <tomi.korpipaa@qt.io>2018-05-09 10:39:19 +0000
commit420966b831116634ef2d2443191aa6d451710b4f (patch)
tree5d8b4a4c5f9b3f616327e9b6abeefebeb70be097 /src/Authoring/Studio/UI
parentab509c2e63de9d04b5767cbb353a9a2acb96ebf0 (diff)
Re-organize folder structure to remove obsolete _Win folder
Task-number: QT3DS-1594 Change-Id: I2f4b1b5b7b38e56c38f7ed9bb7f2081924db660b Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Authoring/Studio/UI')
-rw-r--r--src/Authoring/Studio/UI/EditCameraBar.cpp238
-rw-r--r--src/Authoring/Studio/UI/EditCameraBar.h94
-rw-r--r--src/Authoring/Studio/UI/EditorPane.cpp90
-rw-r--r--src/Authoring/Studio/UI/EditorPane.h65
-rw-r--r--src/Authoring/Studio/UI/GLVersionDlg.cpp68
-rw-r--r--src/Authoring/Studio/UI/GLVersionDlg.h72
-rw-r--r--src/Authoring/Studio/UI/GLVersionDlg.ui100
-rw-r--r--src/Authoring/Studio/UI/InterpolationDlg.cpp78
-rw-r--r--src/Authoring/Studio/UI/InterpolationDlg.h68
-rw-r--r--src/Authoring/Studio/UI/InterpolationDlg.ui305
-rw-r--r--src/Authoring/Studio/UI/PlayerContainerWnd.cpp310
-rw-r--r--src/Authoring/Studio/UI/PlayerContainerWnd.h91
-rw-r--r--src/Authoring/Studio/UI/PlayerWnd.cpp262
-rw-r--r--src/Authoring/Studio/UI/PlayerWnd.h86
-rw-r--r--src/Authoring/Studio/UI/RecentItems.cpp145
-rw-r--r--src/Authoring/Studio/UI/RecentItems.h86
-rw-r--r--src/Authoring/Studio/UI/ResetKeyframeValuesDlg.cpp54
-rw-r--r--src/Authoring/Studio/UI/ResetKeyframeValuesDlg.h53
-rw-r--r--src/Authoring/Studio/UI/ResetKeyframeValuesDlg.ui90
-rw-r--r--src/Authoring/Studio/UI/SceneView.cpp363
-rw-r--r--src/Authoring/Studio/UI/SceneView.h105
-rw-r--r--src/Authoring/Studio/UI/StartupDlg.cpp192
-rw-r--r--src/Authoring/Studio/UI/StartupDlg.h115
-rw-r--r--src/Authoring/Studio/UI/StartupDlg.ui244
-rw-r--r--src/Authoring/Studio/UI/StudioAppPrefsPage.cpp559
-rw-r--r--src/Authoring/Studio/UI/StudioAppPrefsPage.h107
-rw-r--r--src/Authoring/Studio/UI/StudioAppPrefsPage.ui300
-rw-r--r--src/Authoring/Studio/UI/StudioPreferencesPropSheet.cpp123
-rw-r--r--src/Authoring/Studio/UI/StudioPreferencesPropSheet.h89
-rw-r--r--src/Authoring/Studio/UI/StudioPreferencesPropSheet.ui105
-rw-r--r--src/Authoring/Studio/UI/StudioProjectSettingsPage.cpp384
-rw-r--r--src/Authoring/Studio/UI/StudioProjectSettingsPage.h103
-rw-r--r--src/Authoring/Studio/UI/StudioProjectSettingsPage.ui125
33 files changed, 5269 insertions, 0 deletions
diff --git a/src/Authoring/Studio/UI/EditCameraBar.cpp b/src/Authoring/Studio/UI/EditCameraBar.cpp
new file mode 100644
index 00000000..8705e96f
--- /dev/null
+++ b/src/Authoring/Studio/UI/EditCameraBar.cpp
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#include "stdafx.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "EditCameraBar.h"
+#include "MainFrm.h"
+#include "SceneView.h"
+#include "StudioPreferences.h"
+#include "StudioApp.h"
+#include "IStudioRenderer.h"
+
+#include <QtWidgets/qcombobox.h>
+#include <QtWidgets/qlabel.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qlistview.h>
+
+//==============================================================================
+/**
+ * Constructor
+ */
+CEditCameraBar::CEditCameraBar(QWidget* parent)
+ : QToolBar(parent)
+ , m_SceneView(nullptr)
+ , m_ActiveCameraIndex(-1)
+{
+ OnCustomizeToolbar();
+ auto activated = static_cast<void(QComboBox::*)(int)>(&QComboBox::activated);
+ connect(m_CameraSelector, activated, this, &CEditCameraBar::OnCameraChanged);
+}
+
+//==============================================================================
+/**
+ * Destructor
+ */
+CEditCameraBar::~CEditCameraBar()
+{
+ delete m_CameraSelector;
+}
+
+//==============================================================================
+/**
+ * Setup the list of edit cameras into the camera combo box
+ * @param inCameras the container that holds the edit cameras
+ */
+void CEditCameraBar::SetupCameras()
+{
+ m_CameraSelector->clear();
+ Q3DStudio::IStudioRenderer &theRenderer = g_StudioApp.getRenderer();
+ QStringList theCameraNames;
+ theRenderer.GetEditCameraList(theCameraNames);
+ int idx = 1;
+ for (const QString &str : qAsConst(theCameraNames)) {
+ m_CameraSelector->addItem(str, QVariant((int)idx));
+ idx++;
+ }
+
+ m_CameraSelector->addItem(tr("Scene Camera View"));
+ m_CameraSelector->setItemData(m_CameraSelector->count() - 1, 0);
+
+ m_CameraSelector->insertSeparator(m_CameraSelector->count() - 1);
+ // adding a 1px spacing, else the separator will disappear sometimes (QComboBox bug)
+ qobject_cast<QListView*>(m_CameraSelector->view())->setSpacing(1);
+
+ long thePreferredView = CStudioPreferences::GetPreferredStartupView();
+ long theNumItems = m_CameraSelector->count();
+ if (thePreferredView == -1) {
+ // deployment view
+ m_CameraSelector->setCurrentIndex(theNumItems - 1);
+ HandleCameraChanged(theNumItems - 1); // set to the last one
+ } else {
+ int theIndex;
+ if (thePreferredView < theNumItems - 2)
+ theIndex = thePreferredView;
+ else // possibly from old content where cameras are removed
+ theIndex = 0;
+ m_CameraSelector->setCurrentIndex(theIndex);
+ HandleCameraChanged(theIndex);
+ }
+}
+
+//==============================================================================
+/**
+ * Callback method when the camera is changed from the camera selection combo box
+ */
+void CEditCameraBar::OnCameraChanged()
+{
+ HandleCameraChanged(m_CameraSelector->currentIndex());
+}
+
+void CEditCameraBar::setCameraIndex(int inIndex)
+{
+ m_CameraSelector->setCurrentIndex(inIndex);
+ OnCameraChanged();
+}
+
+//==============================================================================
+/**
+ * Handle the switching of the current edit camera
+ * @param inIndex the index of the to-be-activated camera in the combo box
+ */
+void CEditCameraBar::HandleCameraChanged(int inIndex)
+{
+ Q3DStudio::IStudioRenderer &theRenderer = g_StudioApp.getRenderer();
+ QStringList theCameraNames;
+ theRenderer.GetEditCameraList(theCameraNames);
+ int theNumCameras = theCameraNames.size();
+ if (inIndex < theNumCameras) {
+ theRenderer.SetEditCamera(inIndex);
+ m_ActiveCameraIndex = inIndex;
+ if (m_SceneView)
+ m_SceneView->setViewMode(CPlayerContainerWnd::VIEW_EDIT);
+ } else if (inIndex > theNumCameras) {
+ theRenderer.SetEditCamera(-1);
+ m_ActiveCameraIndex = inIndex;
+ if (m_SceneView)
+ m_SceneView->setViewMode(CPlayerContainerWnd::VIEW_SCENE);
+ } else {
+ m_CameraSelector->setCurrentIndex(m_ActiveCameraIndex);
+ }
+ if (m_SceneView)
+ m_SceneView->onEditCameraChanged();
+
+ CMainFrame *theMainFrame = g_StudioApp.m_pMainWnd;
+ ASSERT(theMainFrame != nullptr);
+
+ // if the current tool is camera rotate and has been switch to 2d camera
+ // set the tool to camera pan
+ if (theMainFrame != nullptr) {
+ long theToolMode = g_StudioApp.GetToolMode();
+ if (!theRenderer.DoesEditCameraSupportRotation(theRenderer.GetEditCamera())
+ && theToolMode == STUDIO_TOOLMODE_CAMERA_ROTATE) {
+ g_StudioApp.SetToolMode(STUDIO_TOOLMODE_CAMERA_PAN);
+ m_SceneView->setViewCursor(); // Just set cursor, we don't want to update previous tool
+ }
+
+ // Trigger for tool changed. Changing between deployment/edit camera can change the tool
+ theMainFrame->OnUpdateToolChange();
+ }
+}
+
+//==============================================================================
+/**
+ * Set the current scene view. This scene view is notified when there is a camera
+ * changed.
+ * @param inSceneView the scene view object
+ */
+void CEditCameraBar::SetSceneView(CSceneView *inSceneView)
+{
+ m_SceneView = inSceneView;
+}
+
+//==============================================================================
+/**
+ * Enable/Disable the edit camera selector combo box.
+ * @param inFlag true to enable the camera selector combo box, false to disable
+ */
+void CEditCameraBar::Enable(bool inFlag)
+{
+ m_CameraSelector->setEnabled(inFlag);
+}
+
+//==============================================================================
+/**
+ * When the active camera is changed, the display string needs to be changed. Hence
+ * find which entry is the one which is modified and update with the new string
+ * @param inCamera the camera that has been modified
+ */
+void CEditCameraBar::onEditCameraChanged()
+{
+ using qt3ds::QT3DSI32;
+ QT3DSI32 cameraIndex = g_StudioApp.getRenderer().GetEditCamera();
+ long theNumEntry = m_CameraSelector->count();
+ for (long theIndex = 0; theIndex < theNumEntry; ++theIndex) {
+ if (m_CameraSelector->itemData(theIndex).toInt() == cameraIndex) {
+ if (theIndex != m_CameraSelector->currentIndex()) {
+ m_CameraSelector->setCurrentIndex(theIndex);
+ HandleCameraChanged(theIndex);
+ }
+ break;
+ }
+ }
+}
+
+//==============================================================================
+/**
+ * Callback while creating the toolbar in MainFrm. This allows the toolbar to add
+ * other controls to it. For this toolbar, we want to add a descriptor and a camera
+ * selector dropdown combobox.
+ */
+//==============================================================================
+void CEditCameraBar::OnCustomizeToolbar()
+{
+ // Create the combo box
+ addWidget(m_CameraSelector = new QComboBox);
+#if (defined Q_OS_MACOS)
+ // There is a "selected" icon in the popup, and automatic scaling does not work for some reason
+ m_CameraSelector->setMinimumContentsLength(tr("Scene Camera View").length() + 1);
+#else
+ m_CameraSelector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+#endif
+ // We need to specify accessibleName and objectName for the combobox, as it's in the toolbar,
+ // and we want to use a different style for it.
+ m_CameraSelector->setAccessibleName(QStringLiteral("cameraSelector"));
+ m_CameraSelector->setObjectName(QStringLiteral("cameraSelector"));
+}
diff --git a/src/Authoring/Studio/UI/EditCameraBar.h b/src/Authoring/Studio/UI/EditCameraBar.h
new file mode 100644
index 00000000..929a0dc8
--- /dev/null
+++ b/src/Authoring/Studio/UI/EditCameraBar.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_EDIT_CAMERA_BAR
+#define INCLUDED_EDIT_CAMERA_BAR 1
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "DispatchListeners.h"
+#include <vector>
+
+#include <QtWidgets/qtoolbar.h>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QLabel;
+QT_END_NAMESPACE
+
+//==============================================================================
+// Forwards
+//==============================================================================
+class CSceneView;
+
+//==============================================================================
+/**
+ * @class CEditCameraBar
+ */
+class CEditCameraBar : public QToolBar, public CEditCameraChangeListener
+{
+ Q_OBJECT
+public:
+ CEditCameraBar(QWidget* parent = nullptr); // standard constructor
+ virtual ~CEditCameraBar();
+
+ // Implementation
+ // Generated message map functions
+ void OnCameraChanged();
+ void OnCustomizeToolbar();
+
+public:
+ void SetupCameras();
+ void SetSceneView(CSceneView *inSceneView);
+ void Enable(bool inFlag);
+ void setCameraIndex(int inIndex);
+ void HandleCameraChanged(int inIndex);
+
+ // CEditCameraChangeListener
+ void onEditCameraChanged() override;
+ void onEditCamerasTransformed() override {}
+ void onAuthorZoomChanged() override {}
+
+protected:
+ CSceneView *m_SceneView; ///< The scene view object
+ long m_ActiveCameraIndex; ///< The index of the active camera in the list
+
+ // UI Controls definition
+ QComboBox* m_CameraSelector; ///< Combo box for selecting edit camera
+};
+
+#endif
diff --git a/src/Authoring/Studio/UI/EditorPane.cpp b/src/Authoring/Studio/UI/EditorPane.cpp
new file mode 100644
index 00000000..ef274392
--- /dev/null
+++ b/src/Authoring/Studio/UI/EditorPane.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#include "stdafx.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "EditorPane.h"
+
+//==============================================================================
+/**
+ * Constructor: Creates a CEditorPane
+ */
+CEditorPane::CEditorPane()
+ : m_EditObject(nullptr)
+{
+}
+
+//==============================================================================
+/**
+ * Destructor: Releases the CEditorPane
+ */
+CEditorPane::~CEditorPane()
+{
+}
+
+//==============================================================================
+/**
+ * Set the object that this window will edit.
+ * Recieve and keep the CAsset to be edited. You can override this method
+ * for each specific editor view class.
+ * @param inEditObject The CAsset to be represented and edited in this view.
+ */
+void CEditorPane::SetEditObject(CAsset *inEditObject)
+{
+ // Retain this object
+ m_EditObject = inEditObject;
+}
+
+//==============================================================================
+/**
+ * Get the object that this window is editing.
+ * return The CAsset that is associated with this window
+ */
+CAsset *CEditorPane::GetEditObject()
+{
+ // Return the asset
+ return m_EditObject;
+}
+
+//==============================================================================
+/**
+ * CloseEditor: Close the editor.
+ * Override to close each individual editor.
+ * @return false
+ */
+bool CEditorPane::CloseEditor()
+{
+ return false;
+} \ No newline at end of file
diff --git a/src/Authoring/Studio/UI/EditorPane.h b/src/Authoring/Studio/UI/EditorPane.h
new file mode 100644
index 00000000..9bc91694
--- /dev/null
+++ b/src/Authoring/Studio/UI/EditorPane.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_EDITOR_PANE
+#define INCLUDED_EDITOR_PANE 1
+
+#pragma once
+
+//==============================================================================
+// Forwards
+//==============================================================================
+class CAsset;
+
+//==============================================================================
+/**
+ * @class CEditorPane
+ * @brief Abstract base class for various editor views.
+ *
+ * A base class for universally accessing information from editor views.
+ */
+class CEditorPane
+{
+ // Fields
+protected:
+ CAsset *m_EditObject; ///< object being edited by this window.
+
+ // Methods
+public:
+ CEditorPane();
+ virtual ~CEditorPane();
+ virtual void SetEditObject(CAsset *inEditObject);
+ CAsset *GetEditObject();
+ virtual bool CloseEditor();
+};
+
+#endif // INCLUDED_EDITOR_PANE \ No newline at end of file
diff --git a/src/Authoring/Studio/UI/GLVersionDlg.cpp b/src/Authoring/Studio/UI/GLVersionDlg.cpp
new file mode 100644
index 00000000..e7cc3b92
--- /dev/null
+++ b/src/Authoring/Studio/UI/GLVersionDlg.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "stdafx.h"
+#include "GLVersionDlg.h"
+#include "ui_GLVersionDlg.h"
+
+#include <QtWidgets/qstyle.h>
+
+CGLVersionDlg::CGLVersionDlg(QWidget *pParent)
+ : QDialog(pParent)
+ , m_ui(new Ui::GLVersionDlg)
+{
+ m_ui->setupUi(this);
+ setFixedSize(size());
+}
+
+CGLVersionDlg::~CGLVersionDlg()
+{
+}
+
+void CGLVersionDlg::Initialize(const QString &inTitle, const QString &inMessage, bool inErrorIcon)
+{
+ // Set title and message
+ setWindowTitle(inTitle);
+ m_ui->m_Message->setText(inMessage);
+
+ // Set which icon to load
+ const int size = style()->pixelMetric(QStyle::PM_LargeIconSize);
+ m_ui->m_WarningIcon->setPixmap(style()->standardIcon(inErrorIcon
+ ? QStyle::SP_MessageBoxCritical
+ : QStyle::SP_MessageBoxWarning).pixmap(
+ size, size));
+}
+
+bool CGLVersionDlg::GetDontShowAgain()
+{
+ return m_ui->m_DontShowAgain->isChecked();
+}
diff --git a/src/Authoring/Studio/UI/GLVersionDlg.h b/src/Authoring/Studio/UI/GLVersionDlg.h
new file mode 100644
index 00000000..588d62aa
--- /dev/null
+++ b/src/Authoring/Studio/UI/GLVersionDlg.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+
+#ifndef INCLUDED_GL_VERSION_DLG
+#define INCLUDED_GL_VERSION_DLG 1
+
+#pragma once
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "Qt3DSString.h"
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_NAMESPACE
+namespace Ui
+{
+ class GLVersionDlg;
+}
+QT_END_NAMESPACE
+
+//==============================================================================
+/**
+ * CGLVersionDlg: Dialog class for showing Open GL Version Warning
+ */
+//==============================================================================
+class CGLVersionDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ CGLVersionDlg(QWidget *pParent = nullptr); // standard constructor
+ ~CGLVersionDlg();
+
+ void Initialize(const QString &inTitle, const QString &inMessage, bool inErrorIcon);
+ bool GetDontShowAgain();
+
+private:
+ QScopedPointer<QT_PREPEND_NAMESPACE(Ui::GLVersionDlg)> m_ui;
+};
+
+#endif // INCLUDED_GL_VERSION_DLG
diff --git a/src/Authoring/Studio/UI/GLVersionDlg.ui b/src/Authoring/Studio/UI/GLVersionDlg.ui
new file mode 100644
index 00000000..3b17f560
--- /dev/null
+++ b/src/Authoring/Studio/UI/GLVersionDlg.ui
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GLVersionDlg</class>
+ <widget class="QDialog" name="GLVersionDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>557</width>
+ <height>146</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="m_WarningIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_Message">
+ <property name="text">
+ <string>OpenGL version X.X.X detected.
+A video card with an updated driver capable of OpenGL X.X.X is recommended or there may be rendering errors.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="m_DontShowAgain">
+ <property name="text">
+ <string>Don't show this dialog again</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>GLVersionDlg</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>GLVersionDlg</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/Authoring/Studio/UI/InterpolationDlg.cpp b/src/Authoring/Studio/UI/InterpolationDlg.cpp
new file mode 100644
index 00000000..57d6ae1d
--- /dev/null
+++ b/src/Authoring/Studio/UI/InterpolationDlg.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix / Includes
+//==============================================================================
+
+#include "stdafx.h"
+#include "InterpolationDlg.h"
+#include "ui_InterpolationDlg.h"
+
+//==============================================================================
+/**
+ * Constructor: Creates a CInterpolationDlg.
+ *
+ * @param parent Pointer to the parent of this dialog (defaults to NULL)
+ */
+//==============================================================================
+CInterpolationDlg::CInterpolationDlg(QWidget *parent)
+ : QDialog(parent)
+ , m_ui(new Ui::InterpolationDlg)
+{
+ m_ui->setupUi(this);
+}
+
+CInterpolationDlg::~CInterpolationDlg()
+{
+ delete m_ui;
+ m_ui = nullptr;
+}
+
+void CInterpolationDlg::setEaseIn(uint value)
+{
+ m_ui->easeInSlider->setValue(value);
+}
+
+void CInterpolationDlg::setEaseOut(uint value)
+{
+ m_ui->easeOutSlider->setValue(value);
+}
+
+int CInterpolationDlg::easeIn() const
+{
+ return m_ui->easeInSlider->value();
+}
+
+int CInterpolationDlg::easeOut() const
+{
+ return m_ui->easeOutSlider->value();
+}
+
+
diff --git a/src/Authoring/Studio/UI/InterpolationDlg.h b/src/Authoring/Studio/UI/InterpolationDlg.h
new file mode 100644
index 00000000..0b324bd3
--- /dev/null
+++ b/src/Authoring/Studio/UI/InterpolationDlg.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+
+#ifndef INCLUDED_INTERPOLATION_DLG
+#define INCLUDED_INTERPOLATION_DLG 1
+
+#pragma once
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class InterpolationDlg;
+}
+QT_END_NAMESPACE
+
+//==============================================================================
+/**
+ * CInterpolationDlg: Dialog class for editing the ease-in/ease-out values of keyframes.
+ */
+//==============================================================================
+class CInterpolationDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit CInterpolationDlg(QWidget *parent = nullptr); // standard constructor
+ ~CInterpolationDlg();
+
+ void setEaseIn(uint value);
+ void setEaseOut(uint value);
+ int easeIn() const;
+ int easeOut() const;
+
+protected:
+ QT_PREPEND_NAMESPACE(Ui::InterpolationDlg) *m_ui = nullptr;
+};
+
+#endif // INCLUDED_INTERPOLATION_DLG
diff --git a/src/Authoring/Studio/UI/InterpolationDlg.ui b/src/Authoring/Studio/UI/InterpolationDlg.ui
new file mode 100644
index 00000000..f0a0a759
--- /dev/null
+++ b/src/Authoring/Studio/UI/InterpolationDlg.ui
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>InterpolationDlg</class>
+ <widget class="QDialog" name="InterpolationDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>425</width>
+ <height>195</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Set Keyframe Interpolation</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1" colspan="2">
+ <widget class="QSlider" name="easeOutSlider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Ease In:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Smooth</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QSlider" name="easeInSlider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Linear</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Linear</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Smooth</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Ease Out:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QSpinBox" name="easeInSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QSpinBox" name="easeOutSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>InterpolationDlg</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>224</x>
+ <y>272</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>InterpolationDlg</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>easeInSlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>easeInSpinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>331</x>
+ <y>21</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>542</x>
+ <y>35</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>easeOutSlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>easeOutSpinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>210</x>
+ <y>93</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>545</x>
+ <y>93</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>easeInSpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>easeInSlider</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>533</x>
+ <y>24</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>408</x>
+ <y>18</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>easeOutSpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>easeOutSlider</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>546</x>
+ <y>98</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>338</x>
+ <y>84</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/Authoring/Studio/UI/PlayerContainerWnd.cpp b/src/Authoring/Studio/UI/PlayerContainerWnd.cpp
new file mode 100644
index 00000000..a5ae75b0
--- /dev/null
+++ b/src/Authoring/Studio/UI/PlayerContainerWnd.cpp
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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 "stdafx.h"
+#include "SceneView.h"
+#include "Doc.h"
+#include "StudioProjectSettings.h"
+#include "Dispatch.h"
+#include "HotKeys.h"
+#include "MasterP.h"
+#include "StudioApp.h"
+#include "IStudioRenderer.h"
+#include "PlatformStrings.h"
+#include "PlayerContainerWnd.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Core.h"
+#include "MainFrm.h"
+#include "StudioUtils.h"
+
+#include <QtWidgets/qscrollbar.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qscreen.h>
+
+CPlayerContainerWnd::CPlayerContainerWnd(CSceneView *inSceneView)
+ : QScrollArea(inSceneView)
+ , m_SceneView(inSceneView)
+ , m_PlayerWnd(NULL)
+ , m_ViewMode(VIEW_SCENE)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+
+CPlayerContainerWnd::~CPlayerContainerWnd()
+{
+}
+
+bool CPlayerContainerWnd::ShouldHideScrollBars()
+{
+ return m_ViewMode == VIEW_EDIT || g_StudioApp.IsAuthorZoom();
+}
+
+//==============================================================================
+/**
+ * SetPlayerWndPosition: Sets the position of the child player window
+ *
+ * Called when the view is scrolled to position the child player window
+ * @param outLeftPresentationEdge the left edge of the presentation, with the scroll position
+ * taken into consideration
+ * @param outTopPresentionEdge the top edge of the presentation, with the scroll
+ * position taken into consideration
+ *
+ */
+//==============================================================================
+void CPlayerContainerWnd::SetPlayerWndPosition(long &outLeftPresentationEdge,
+ long &outTopPresentionEdge)
+{
+ long theHScrollPosition, theVScrollPosition;
+ // Negate to adjust actual client positions
+ theHScrollPosition = -horizontalScrollBar()->value();
+ theVScrollPosition = -verticalScrollBar()->value();
+
+ QRect theClientRect = rect();
+
+ // Horizontal scrollbar does not exist
+ if (m_ClientRect.width() < theClientRect.width()) {
+ theHScrollPosition =
+ theClientRect.left() + (theClientRect.width() / 2) - (m_ClientRect.width() / 2);
+ outLeftPresentationEdge = theHScrollPosition;
+ } else {
+ // This stays a negated value
+ outLeftPresentationEdge = theHScrollPosition;
+ }
+
+ // Vertical scrollbar does not exist
+ if (m_ClientRect.height() < theClientRect.height()) {
+ theVScrollPosition =
+ theClientRect.top() + (theClientRect.height() / 2) - (m_ClientRect.height() / 2);
+ outTopPresentionEdge = theVScrollPosition;
+ } else {
+ // This stays a negated value
+ outTopPresentionEdge = theVScrollPosition;
+ }
+
+ // Move the child player window
+ m_PlayerWnd->setGeometry(QRect(QPoint(theHScrollPosition, theVScrollPosition),
+ m_ClientRect.size()));
+}
+
+//==============================================================================
+/**
+ * SetScrollRanges: Sets the scroll ranges when the view is being resized
+ */
+//==============================================================================
+void CPlayerContainerWnd::SetScrollRanges()
+{
+
+ long theScrollWidth = 0;
+ long theScrollHeight = 0;
+
+ if (ShouldHideScrollBars()) {
+ horizontalScrollBar()->setRange(0, 0);
+ verticalScrollBar()->setRange(0, 0);
+ horizontalScrollBar()->setValue(0);
+ verticalScrollBar()->setValue(0);
+ } else {
+ QSize theSize = GetEffectivePresentationSize();
+
+ theScrollWidth = theSize.width();
+ theScrollHeight = theSize.height();
+
+ // Set scrollbar ranges
+ horizontalScrollBar()->setRange(0, theScrollWidth - width());
+ verticalScrollBar()->setRange(0, theScrollHeight - height());
+ horizontalScrollBar()->setPageStep(width());
+ verticalScrollBar()->setPageStep(height());
+ horizontalScrollBar()->setVisible(true);
+ verticalScrollBar()->setVisible(true);
+ }
+}
+
+//==============================================================================
+/**
+ * OnRulerGuideToggled:
+ * Handle scrollbar position when ruler, guide has been toggled
+ */
+//==============================================================================
+void CPlayerContainerWnd::OnRulerGuideToggled()
+{
+ int scrollAmount = g_StudioApp.getRenderer().AreGuidesEnabled() ? 16 : -16;
+ bool hasHorz = horizontalScrollBar()->isVisible();
+ bool hasVert = verticalScrollBar()->isVisible();
+ int hscrollPos = 0, vscrollPos = 0;
+ if (hasHorz)
+ hscrollPos = qMax(horizontalScrollBar()->value() + scrollAmount, 0);
+ if (hasVert)
+ vscrollPos = qMax(verticalScrollBar()->value() + scrollAmount, 0);
+ horizontalScrollBar()->setValue(hscrollPos);
+ verticalScrollBar()->setValue(vscrollPos);
+ m_PlayerWnd->update();
+}
+
+qreal CPlayerContainerWnd::fixedDevicePixelRatio() const
+{
+ // Fix a problem on X11: https://bugreports.qt.io/browse/QTBUG-65570
+ qreal ratio = devicePixelRatio();
+ if (QWindow *w = window()->windowHandle()) {
+ if (QScreen *s = w->screen())
+ ratio = s->devicePixelRatio();
+ }
+ return ratio;
+}
+
+//==============================================================================
+/**
+ * RecenterClient: Recenters the Client rect in the View's client area.
+ */
+//==============================================================================
+void CPlayerContainerWnd::RecenterClient()
+{
+ QRect theViewClientRect = rect();
+ QSize theClientSize;
+ m_ClientRect = theViewClientRect;
+
+ if (!ShouldHideScrollBars()) {
+ theClientSize = GetEffectivePresentationSize();
+
+ // Only center if we need to scroll
+ if (theClientSize.width() > theViewClientRect.width()) {
+ // compute the size of the client rectangle to display
+ m_ClientRect.setLeft(
+ (theViewClientRect.width() / 2) - (theClientSize.width() / 2)
+ - (theClientSize.width() % 2));
+ m_ClientRect.setRight((theViewClientRect.width() / 2) + (theClientSize.width() / 2));
+ }
+
+ if (theClientSize.height() > theViewClientRect.height()) {
+ m_ClientRect.setTop(
+ (theViewClientRect.height() / 2) - (theClientSize.height() / 2)
+ - (theClientSize.height() % 2));
+ m_ClientRect.setBottom((theViewClientRect.height() / 2) + (theClientSize.height() / 2));
+ }
+ }
+
+ QRect glRect = m_ClientRect;
+ glRect.setWidth(int(fixedDevicePixelRatio() * m_ClientRect.width()));
+ glRect.setHeight(int(fixedDevicePixelRatio() * m_ClientRect.height()));
+ g_StudioApp.getRenderer().SetViewRect(glRect);
+}
+
+void CPlayerContainerWnd::wheelEvent(QWheelEvent* event)
+{
+ const bool theCtrlKeyIsDown = event->modifiers() & Qt::ControlModifier;
+
+ if (!theCtrlKeyIsDown && !IsDeploymentView()) {
+ // Zoom when in edit camera view
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseWheel(
+ SceneDragSenderType::Matte, event->delta(), STUDIO_TOOLMODE_CAMERA_ZOOM);
+ } else {
+ // Otherwise, scroll the view
+ QScrollArea::wheelEvent(event);
+ }
+}
+
+void CPlayerContainerWnd::scrollContentsBy(int, int)
+{
+ long x, y;
+ SetPlayerWndPosition(x, y);
+}
+
+//==============================================================================
+/**
+ * Set the view mode of the current scene view, whether we are in editing mode
+ * or deployment mode. For editing mode, we want to use the full scene area without
+ * any matte area.
+ * @param inViewMode the view mode of this scene
+ */
+void CPlayerContainerWnd::SetViewMode(EViewMode inViewMode)
+{
+ m_ViewMode = inViewMode;
+ m_SceneView->recheckSizingMode();
+}
+
+//==============================================================================
+/**
+ * return the view mode of the current scene view, whether we are in editing mode
+ * or deployment mode. For editing mode, we want to use the full scene area without
+ * any matte area.
+ * @return the current view mode
+ */
+CPlayerContainerWnd::EViewMode CPlayerContainerWnd::GetViewMode()
+{
+ return m_ViewMode;
+}
+
+//==============================================================================
+/**
+ * Checks whether we are in deployment view mode.
+ * @return true if is in deployment view mode, else false
+ */
+bool CPlayerContainerWnd::IsDeploymentView()
+{
+ return m_ViewMode == VIEW_SCENE ? true : false;
+}
+
+void CPlayerContainerWnd::setToolMode(long inMode)
+{
+ if (m_PlayerWnd)
+ m_PlayerWnd->setToolMode(inMode);
+}
+
+QSize CPlayerContainerWnd::GetEffectivePresentationSize() const
+{
+ CPt cSize = g_StudioApp.GetCore()->GetStudioProjectSettings()->GetPresentationSize();
+ QSize theSize(cSize.x, cSize.y);
+
+ // If we have guides, resize the window with enough space for the guides as well as the
+ // presentation
+ // This is a very dirty hack because we are of course hardcoding the size of the guides.
+ // If the size of the guides never changes, the bet paid off.
+ if (g_StudioApp.getRenderer().AreGuidesEnabled())
+ theSize += QSize(32, 32);
+
+ return theSize / fixedDevicePixelRatio();
+}
+
+//==============================================================================
+
+void CPlayerContainerWnd::SetPlayerWnd(CPlayerWnd *inPlayerWnd)
+{
+ m_PlayerWnd = inPlayerWnd;
+ viewport()->setBackgroundRole(QPalette::Dark);
+ m_PlayerWnd->setContainerWnd(this);
+ m_PlayerWnd->setParent(viewport());
+ m_PlayerWnd->setVisible(true);
+ m_PlayerWnd->resize(m_PlayerWnd->sizeHint());
+}
+
+void CPlayerContainerWnd::resizeEvent(QResizeEvent* event)
+{
+ QAbstractScrollArea::resizeEvent(event);
+
+ SetScrollRanges();
+}
diff --git a/src/Authoring/Studio/UI/PlayerContainerWnd.h b/src/Authoring/Studio/UI/PlayerContainerWnd.h
new file mode 100644
index 00000000..4ef40b90
--- /dev/null
+++ b/src/Authoring/Studio/UI/PlayerContainerWnd.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_PLAYER_CONTAINER_WND_H
+#define INCLUDED_PLAYER_CONTAINER_WND_H 1
+
+#pragma once
+
+#include <QtWidgets/qscrollarea.h>
+
+class CSceneView;
+class CStudioApp;
+class CPlayerWnd;
+class CWGLRenderContext;
+
+class CPlayerContainerWnd : public QScrollArea
+{
+ Q_OBJECT
+public:
+ typedef enum {
+ VIEW_EDIT = 0, ///< Edit View
+ VIEW_SCENE, ///< Scene View
+ } EViewMode;
+
+public:
+ CPlayerContainerWnd(CSceneView *inSceneView);
+ virtual ~CPlayerContainerWnd();
+
+ void SetPlayerWnd(CPlayerWnd *inPlayerWnd);
+ void SetPlayerWndPosition(long &outLeftPresentationEdge, long &outTopPresentionEdge);
+ void SetScrollRanges();
+ void RecenterClient();
+ void OnRulerGuideToggled();
+
+ void SetViewMode(EViewMode inViewMode);
+ EViewMode GetViewMode();
+ bool IsDeploymentView();
+ void setToolMode(long inMode);
+
+ QRect GetDisplayedClientRect() const { return m_ClientRect; }
+
+ QSize GetEffectivePresentationSize() const;
+
+ qreal fixedDevicePixelRatio() const;
+
+Q_SIGNALS:
+ void toolChanged();
+
+protected:
+ void resizeEvent(QResizeEvent *) override;
+ void wheelEvent(QWheelEvent *) override;
+ void scrollContentsBy(int, int) override;
+
+private:
+ CPlayerContainerWnd() {}
+ bool ShouldHideScrollBars();
+
+protected:
+ CSceneView *m_SceneView; ///< Pointer to the SceneView for rulers manipulation
+ CPlayerWnd *m_PlayerWnd; ///< Pointer to the window control that contains client
+ QRect m_ClientRect; ///< The rect where the client is drawn
+ EViewMode m_ViewMode;
+};
+
+#endif // INCLUDED_PLAYER_CONTAINER_WND_H
diff --git a/src/Authoring/Studio/UI/PlayerWnd.cpp b/src/Authoring/Studio/UI/PlayerWnd.cpp
new file mode 100644
index 00000000..ba8c25d6
--- /dev/null
+++ b/src/Authoring/Studio/UI/PlayerWnd.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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 "stdafx.h"
+#include "PlayerWnd.h"
+#include "MainFrm.h"
+#include "SceneView.h"
+#include "Dispatch.h"
+#include "MasterP.h"
+#include "HotKeys.h"
+#include "StudioApp.h"
+#include "Doc.h"
+#include "Dispatch.h"
+#include "HotKeys.h"
+#include "MouseCursor.h"
+#include "ResourceCache.h"
+#include "SceneDropTarget.h"
+#include "Core.h"
+#include "IDragable.h"
+#include "WGLRenderContext.h"
+#include "IStudioRenderer.h"
+
+#include <QtWidgets/qmessagebox.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qscreen.h>
+
+CPlayerWnd::CPlayerWnd(QWidget *parent)
+ : QOpenGLWidget(parent)
+ , m_containerWnd(nullptr)
+ , m_mouseDown(false)
+{
+ setAcceptDrops(true);
+ RegisterForDnd(this);
+ AddMainFlavor(QT3DS_FLAVOR_FILE);
+ AddMainFlavor(QT3DS_FLAVOR_ASSET_UICFILE);
+ AddMainFlavor(QT3DS_FLAVOR_ASSET_LIB);
+ AddMainFlavor(QT3DS_FLAVOR_BASIC_OBJECTS);
+
+ setFormat(CWGLRenderContext::selectSurfaceFormat(this));
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ m_previousToolMode = g_StudioApp.GetToolMode();
+}
+
+CPlayerWnd::~CPlayerWnd()
+{
+}
+
+void CPlayerWnd::resizeEvent(QResizeEvent *event)
+{
+ QOpenGLWidget::resizeEvent(event);
+ update();
+}
+
+void CPlayerWnd::mouseMoveEvent(QMouseEvent *event)
+{
+ if (m_mouseDown) {
+ long theModifierKeys = 0;
+ if (event->buttons() & Qt::LeftButton
+ || (!g_StudioApp.GetCore()->GetDoc()->GetSelectedInstance().Valid())
+ && !m_containerWnd->IsDeploymentView()) {
+ // When in edit camera view and nothing is selected, all buttons are mapped
+ // as left button. That is how camera control tools work, they are all
+ // assuming left button.
+ theModifierKeys = CHotKeys::MOUSE_LBUTTON | CHotKeys::GetCurrentKeyModifiers();
+ } else if (event->buttons() & Qt::RightButton) {
+ theModifierKeys = CHotKeys::MOUSE_RBUTTON | CHotKeys::GetCurrentKeyModifiers();
+ } else if (event->buttons() & Qt::MiddleButton) {
+ theModifierKeys = CHotKeys::MOUSE_MBUTTON | CHotKeys::GetCurrentKeyModifiers();
+ }
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseDrag(
+ SceneDragSenderType::Matte, event->pos(), g_StudioApp.GetToolMode(),
+ theModifierKeys);
+ } else {
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseMove(
+ SceneDragSenderType::SceneWindow, event->pos());
+ }
+}
+
+void CPlayerWnd::mousePressEvent(QMouseEvent *event)
+{
+ long toolMode = g_StudioApp.GetToolMode();
+ const Qt::MouseButton btn = event->button();
+ bool toolChanged = false;
+
+ if (!m_containerWnd->IsDeploymentView() && (event->modifiers() & Qt::AltModifier)) {
+ // We are in edit camera view, so we are in Alt-click camera tool
+ // controlling mode
+ m_mouseDown = true;
+ if (btn == Qt::MiddleButton) {
+ // Alt + Wheel Click
+ toolMode = STUDIO_TOOLMODE_CAMERA_PAN;
+ toolChanged = true;
+ } else if (btn == Qt::LeftButton) {
+ // Alt + Left Click
+ if (g_StudioApp.getRenderer().DoesEditCameraSupportRotation(
+ g_StudioApp.getRenderer().GetEditCamera())) {
+ toolMode = STUDIO_TOOLMODE_CAMERA_ROTATE;
+ toolChanged = true;
+ }
+ } else if (btn == Qt::RightButton) {
+ // Alt + Right Click
+ toolMode = STUDIO_TOOLMODE_CAMERA_ZOOM;
+ toolChanged = true;
+ }
+
+ if (toolChanged) {
+ g_StudioApp.SetToolMode(toolMode);
+ Q_EMIT m_containerWnd->toolChanged();
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseDown(SceneDragSenderType::Matte,
+ event->pos(), toolMode);
+ }
+ } else {
+ if (btn == Qt::LeftButton || btn == Qt::RightButton) {
+ // Pause playback for the duration of the mouse click
+ if (g_StudioApp.IsPlaying()) {
+ g_StudioApp.PlaybackStopNoRestore();
+ m_resumePlayOnMouseRelease = true;
+ } else {
+ m_resumePlayOnMouseRelease = false;
+ }
+
+ toolMode = g_StudioApp.GetToolMode();
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseDown(
+ SceneDragSenderType::SceneWindow, event->pos(), toolMode);
+ m_mouseDown = true;
+ } else if (btn == Qt::MiddleButton) {
+ event->ignore();
+ }
+ }
+}
+
+void CPlayerWnd::mouseReleaseEvent(QMouseEvent *event)
+{
+ const Qt::MouseButton btn = event->button();
+
+ if (!m_containerWnd->IsDeploymentView()) {
+ // We are in edit camera view
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseUp(SceneDragSenderType::Matte);
+ g_StudioApp.GetCore()->CommitCurrentCommand();
+ m_mouseDown = false;
+ // Restore normal tool mode
+ g_StudioApp.SetToolMode(m_previousToolMode);
+ Q_EMIT m_containerWnd->toolChanged();
+ } else {
+ if (btn == Qt::LeftButton || btn == Qt::RightButton) {
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseUp(
+ SceneDragSenderType::SceneWindow);
+ g_StudioApp.GetCore()->CommitCurrentCommand();
+ m_mouseDown = false;
+ if (m_resumePlayOnMouseRelease) {
+ m_resumePlayOnMouseRelease = false;
+ g_StudioApp.PlaybackPlay();
+ }
+ } else if (btn == Qt::MiddleButton) {
+ event->ignore();
+ }
+ }
+}
+
+void CPlayerWnd::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ g_StudioApp.GetCore()->GetDispatch()->FireSceneMouseDblClick(
+ SceneDragSenderType::SceneWindow, event->pos());
+}
+
+bool CPlayerWnd::OnDragWithin(CDropSource &inSource)
+{
+ CSceneViewDropTarget theTarget;
+ return theTarget.Accept(inSource);
+}
+
+bool CPlayerWnd::OnDragReceive(CDropSource &inSource)
+{
+ CSceneViewDropTarget theTarget;
+ Q_EMIT dropReceived();
+ return theTarget.Drop(inSource);
+}
+
+void CPlayerWnd::setContainerWnd(CPlayerContainerWnd *inContainerWnd)
+{
+ m_containerWnd = inContainerWnd;
+ updateGeometry();
+}
+
+QSize CPlayerWnd::sizeHint() const
+{
+ if (m_containerWnd)
+ return m_containerWnd->GetEffectivePresentationSize();
+ else
+ return QOpenGLWidget::sizeHint();
+}
+
+void CPlayerWnd::initializeGL()
+{
+ Q3DStudio::IStudioRenderer &theRenderer(g_StudioApp.getRenderer());
+ if (theRenderer.IsInitialized() == false) {
+ try {
+ theRenderer.Initialize(this);
+ } catch (...) {
+ QMessageBox::critical(this, tr("Fatal Error"),
+ tr("Unable to initialize OpenGL.\nThis may be because your "
+ "graphic device is not sufficient, or simply because your "
+ "driver is too old.\n\nPlease try upgrading your graphics "
+ "driver and try again."));
+ exit(1);
+ }
+ }
+}
+
+void CPlayerWnd::paintGL()
+{
+ Q3DStudio::IStudioRenderer &theRenderer(g_StudioApp.getRenderer());
+ // Don't use request render here, this has to be synchronous inside paintGL
+ theRenderer.RenderNow();
+}
+
+qreal CPlayerWnd::fixedDevicePixelRatio() const
+{
+ // Fix a problem on X11: https://bugreports.qt.io/browse/QTBUG-65570
+ qreal ratio = devicePixelRatio();
+ if (QWindow *w = window()->windowHandle()) {
+ if (QScreen *s = w->screen())
+ ratio = s->devicePixelRatio();
+ }
+ return ratio;
+}
+
+void CPlayerWnd::resizeGL(int width, int height)
+{
+ // This also passes the new FBO to the OpenGLContext
+ Q3DStudio::IStudioRenderer &theRenderer(g_StudioApp.getRenderer());
+ theRenderer.SetViewRect(QRect(0, 0, width * fixedDevicePixelRatio(),
+ height * fixedDevicePixelRatio()));
+}
diff --git a/src/Authoring/Studio/UI/PlayerWnd.h b/src/Authoring/Studio/UI/PlayerWnd.h
new file mode 100644
index 00000000..81eec6bc
--- /dev/null
+++ b/src/Authoring/Studio/UI/PlayerWnd.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_PLAYERWND_H
+#define INCLUDED_PLAYERWND_H 1
+
+#pragma once
+
+#include "DropContainer.h"
+#include "PlayerContainerWnd.h"
+
+#include <QtWidgets/qopenglwidget.h>
+
+class CPlayerContainerWnd;
+class CStudioApp;
+class CMouseCursor;
+class CHotkeys;
+
+class CPlayerWnd : public QOpenGLWidget, public CWinDropContainer
+{
+ Q_OBJECT
+public:
+ explicit CPlayerWnd(QWidget *parent = nullptr);
+ ~CPlayerWnd();
+
+ void setContainerWnd(CPlayerContainerWnd *inSceneView);
+
+ QSize sizeHint() const override;
+
+ bool OnDragWithin(CDropSource &inSource) override;
+ bool OnDragReceive(CDropSource &inSource) override;
+ void OnDragLeave() override {}
+ void OnReflectMouse(CPt &, Qt::KeyboardModifiers) override {}
+
+ qreal fixedDevicePixelRatio() const;
+ void setToolMode(long toolMode) { m_previousToolMode = toolMode; }
+
+protected:
+
+ CPlayerContainerWnd *m_containerWnd;
+ bool m_mouseDown;
+ bool m_resumePlayOnMouseRelease = false;
+ long m_previousToolMode;
+
+Q_SIGNALS:
+ void dropReceived();
+
+protected:
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
+ void initializeGL() override;
+ void paintGL() override;
+ void resizeGL(int width, int height) override;
+};
+
+#endif // INCLUDED_PLAYERWND_H
diff --git a/src/Authoring/Studio/UI/RecentItems.cpp b/src/Authoring/Studio/UI/RecentItems.cpp
new file mode 100644
index 00000000..e7497d40
--- /dev/null
+++ b/src/Authoring/Studio/UI/RecentItems.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 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 "stdafx.h"
+
+#include "RecentItems.h"
+#include "Preferences.h"
+
+#include <QMenu>
+
+// using namespace Q3DStudio; <-- Do not do this here because it will conflict with CList and make
+// the template generator go blah
+
+const Q3DStudio::CString CRecentItems::RECENTITEM_KEY = "RecentItem";
+const Q3DStudio::CString CRecentItems::RECENTIMPORT_KEY = "RecentImport";
+const Q3DStudio::CString CRecentItems::RECENTITEM_VALID = "RecentValid";
+
+CRecentItems::CRecentItems(QMenu *inMenuID, long inCommandID, Q3DStudio::CString inPreferenceKey)
+{
+ Q_UNUSED(inCommandID)
+
+ m_Menu = inMenuID;
+ m_ValidItems = 10;
+ m_PreferenceKey = inPreferenceKey;
+
+ ReconstructList();
+}
+
+CRecentItems::~CRecentItems()
+{
+}
+
+void CRecentItems::AddRecentItem(const Qt3DSFile &inItem)
+{
+ RemoveRecentItem(inItem);
+
+ m_RecentItems.insert(m_RecentItems.begin(), inItem);
+
+ while (m_RecentItems.size() > 10)
+ m_RecentItems.pop_back();
+
+ RebuildList();
+}
+
+void CRecentItems::RemoveRecentItem(const Qt3DSFile &inItem)
+{
+ TFileList::iterator thePos = m_RecentItems.begin();
+ for (; thePos != m_RecentItems.end(); ++thePos) {
+ if ((*thePos) == inItem) {
+ m_RecentItems.erase(thePos);
+ break;
+ }
+ }
+
+ RebuildList();
+}
+
+void CRecentItems::ReconstructList()
+{
+ ClearMenu();
+ m_RecentItems.clear();
+
+ CPreferences thePrefs = CPreferences::GetUserPreferences();
+
+ m_ValidItems = thePrefs.GetLongValue(RECENTITEM_VALID, m_ValidItems);
+
+ for (long theIndex = 0; theIndex < (m_ValidItems > 10 ? 10 : m_ValidItems); ++theIndex) {
+ Q3DStudio::CString theKey;
+ theKey.Format(_LSTR("%ls%d"), static_cast<const wchar_t *>(m_PreferenceKey), theIndex);
+
+ Q3DStudio::CString theFilename = thePrefs.GetStringValue(theKey, "");
+ if (theFilename != "") {
+ Qt3DSFile theFile(theFilename);
+
+ QAction *act = m_Menu->addAction(theFile.GetName().toQString(),
+ this, &CRecentItems::onTriggerRecent);
+ act->setData(static_cast<int>(m_RecentItems.size()));
+ m_RecentItems.push_back(theFile);
+ }
+ }
+}
+
+void CRecentItems::RebuildList()
+{
+ ClearMenu();
+
+ CPreferences thePrefs = CPreferences::GetUserPreferences();
+ thePrefs.SetLongValue(RECENTITEM_VALID, GetItemCount());
+ TFileList::iterator thePos = m_RecentItems.begin();
+ for (long theIndex = 0; thePos != m_RecentItems.end(); ++thePos, ++theIndex) {
+ Q3DStudio::CString theFilename = (*thePos).GetName();
+
+ QAction *act = m_Menu->addAction(theFilename.toQString(),
+ this, &CRecentItems::onTriggerRecent);
+ act->setData(static_cast<int>(theIndex));
+
+ Q3DStudio::CString theKey;
+ theKey.Format(_LSTR("%ls%d"), static_cast<const wchar_t *>(m_PreferenceKey), theIndex);
+
+ thePrefs.SetStringValue(theKey, (*thePos).GetAbsolutePath());
+ }
+}
+
+void CRecentItems::ClearMenu()
+{
+ m_Menu->clear();
+}
+
+Qt3DSFile CRecentItems::GetItem(long inIndex)
+{
+ return m_RecentItems.at(inIndex);
+}
+
+void CRecentItems::onTriggerRecent()
+{
+ const int index = qobject_cast<QAction *>(sender())->data().toInt();
+ Q_EMIT openRecent(index);
+}
+
diff --git a/src/Authoring/Studio/UI/RecentItems.h b/src/Authoring/Studio/UI/RecentItems.h
new file mode 100644
index 00000000..4173646f
--- /dev/null
+++ b/src/Authoring/Studio/UI/RecentItems.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_RECENT_ITEMS_H
+#define INCLUDED_RECENT_ITEMS_H 1
+
+#pragma once
+
+#include <QObject>
+
+#include "Qt3DSString.h"
+#include "Qt3DSFile.h"
+
+#include <vector>
+
+class Qt3DSFile;
+
+QT_FORWARD_DECLARE_CLASS(QMenu)
+
+class CRecentItems : public QObject
+{
+ Q_OBJECT
+
+ typedef std::vector<Qt3DSFile> TFileList;
+
+public:
+ static const Q3DStudio::CString RECENTITEM_KEY;
+ static const Q3DStudio::CString RECENTIMPORT_KEY;
+ static const Q3DStudio::CString RECENTITEM_VALID;
+
+Q_SIGNALS:
+ void openRecent(int index);
+public:
+ CRecentItems(QMenu *inMenu, long inCommandID,
+ Q3DStudio::CString inPreferenceKey = RECENTITEM_KEY);
+ virtual ~CRecentItems();
+
+ void AddRecentItem(const Qt3DSFile &inItem);
+ void RemoveRecentItem(const Qt3DSFile &inItem);
+
+ Qt3DSFile GetItem(long inIndex);
+ long GetItemCount() const { return (long)m_RecentItems.size(); }
+
+protected:
+ void ClearMenu();
+ void ReconstructList();
+ void RebuildList();
+ void SaveRecentList();
+
+ TFileList m_RecentItems;
+
+ long m_CommandID;
+ long m_ValidItems;
+ QMenu *m_Menu;
+ Q3DStudio::CString m_PreferenceKey;
+
+private Q_SLOTS:
+ void onTriggerRecent();
+};
+#endif // INCLUDED_RECENT_ITEMS_H
diff --git a/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.cpp b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.cpp
new file mode 100644
index 00000000..26204474
--- /dev/null
+++ b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "stdafx.h"
+#include "ResetKeyframeValuesDlg.h"
+#include "ui_ResetKeyframeValuesDlg.h"
+
+#include <QPushButton>
+#include <QStyle>
+
+CResetKeyframeValuesDlg::CResetKeyframeValuesDlg(QWidget *pParent)
+ : QDialog(pParent)
+ , m_ui(new Ui::ResetKeyframeValuesDlg)
+{
+ m_ui->setupUi(this);
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Reset Key"));
+ const int i = style()->pixelMetric(QStyle::PM_LargeIconSize);
+ const QIcon icon = style()->standardIcon(QStyle::SP_MessageBoxWarning);
+ m_ui->m_WarningIcon->setPixmap(icon.pixmap(i, i));
+ setFixedSize(size());
+}
+
+CResetKeyframeValuesDlg::~CResetKeyframeValuesDlg()
+{
+}
diff --git a/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.h b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.h
new file mode 100644
index 00000000..ca5f17f6
--- /dev/null
+++ b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Includes
+//==============================================================================
+#pragma once
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+namespace Ui
+{
+ class ResetKeyframeValuesDlg;
+}
+QT_END_NAMESPACE
+
+class CResetKeyframeValuesDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ CResetKeyframeValuesDlg(QWidget *pParent = nullptr); // standard constructor
+ ~CResetKeyframeValuesDlg();
+
+private:
+ QScopedPointer<QT_PREPEND_NAMESPACE(Ui::ResetKeyframeValuesDlg)> m_ui;
+};
diff --git a/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.ui b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.ui
new file mode 100644
index 00000000..1d7aa670
--- /dev/null
+++ b/src/Authoring/Studio/UI/ResetKeyframeValuesDlg.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ResetKeyframeValuesDlg</class>
+ <widget class="QDialog" name="ResetKeyframeValuesDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>534</width>
+ <height>146</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Reset Keyframe Curves</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="m_WarningIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Warning: You have selected keyframes that were created in an external application. Proceeding with this action will reset all curve values to the defaults.
+
+Are you sure you would like to proceed?</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ResetKeyframeValuesDlg</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ResetKeyframeValuesDlg</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/Authoring/Studio/UI/SceneView.cpp b/src/Authoring/Studio/UI/SceneView.cpp
new file mode 100644
index 00000000..7f9a088d
--- /dev/null
+++ b/src/Authoring/Studio/UI/SceneView.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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 "SceneView.h"
+#include "StudioPreferences.h"
+#include "HotKeys.h"
+#include "StudioApp.h"
+#include "Doc.h"
+#include "Dispatch.h"
+#include "MouseCursor.h"
+#include "ResourceCache.h"
+#include "Core.h"
+#include "IStudioRenderer.h"
+
+#include <QtGui/qevent.h>
+
+CSceneView::CSceneView(QWidget *parent)
+ : QWidget(parent)
+ , m_playerContainerWnd(new CPlayerContainerWnd(this))
+ , m_playerWnd(new CPlayerWnd(m_playerContainerWnd.data()))
+{
+ m_previousSelectMode = g_StudioApp.GetSelectMode();
+
+ connect(m_playerContainerWnd.data(), &CPlayerContainerWnd::toolChanged,
+ this, [=](){ setViewCursor(); Q_EMIT toolChanged(); });
+
+ connect(m_playerWnd.data(), &CPlayerWnd::dropReceived, this, &CSceneView::onDropReceived);
+
+ m_playerContainerWnd->SetPlayerWnd(m_playerWnd.data());
+
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+
+CSceneView::CSceneView()
+{
+ m_previousSelectMode = g_StudioApp.GetSelectMode();
+}
+
+void CSceneView::onDropReceived()
+{
+ setFocus();
+}
+
+CPlayerWnd *CSceneView::getPlayerWnd() const
+{
+ return m_playerWnd.data();
+}
+
+CSceneView::~CSceneView()
+{
+ CDispatch *theDispatch = g_StudioApp.GetCore()->GetDispatch();
+ // Stop listening for selection change events
+ theDispatch->RemoveEditCameraChangeListener(this);
+}
+
+QSize CSceneView::sizeHint() const
+{
+ CPt theSize = CStudioPreferences::GetDefaultClientSize();
+ return QSize(theSize.x, theSize.y);
+}
+
+//==============================================================================
+/**
+ * Called by the framework after the view is first attached
+ * to the document, but before the view is initially displayed.
+ * Notifies the Main Frame that the palettes need to be shown, and destroys the
+ * splash screen.
+ */
+void CSceneView::showEvent(QShowEvent *event)
+{
+ QWidget::showEvent(event);
+
+ m_playerContainerWnd->RecenterClient();
+
+ // Set the scroll information.
+ m_playerContainerWnd->SetScrollRanges();
+
+ // Create the cursors
+ m_arrowCursor = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_ARROW);
+ m_cursorGroupMove = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_GROUP_MOVE);
+ m_cursorGroupRotate =
+ CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_GROUP_ROTATE);
+ m_cursorGroupScale = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_GROUP_SCALE);
+ m_cursorItemMove = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_ITEM_MOVE);
+ m_cursorItemRotate = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_ITEM_ROTATE);
+ m_cursorItemScale = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_ITEM_SCALE);
+ m_cursorEditCameraPan =
+ CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_PAN);
+ m_cursorEditCameraRotate =
+ CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_ROTATE);
+ m_cursorEditCameraZoom =
+ CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_ZOOM);
+
+ g_StudioApp.GetCore()->GetDispatch()->AddEditCameraChangeListener(this);
+
+ // Set the default cursor
+ setViewCursor();
+}
+
+//==============================================================================
+/**
+ * OnToolGroupSelection: Called when the Group Selection button is pressed.
+ * Sets the current tool mode and changes the cursor.
+ */
+void CSceneView::onToolGroupSelection()
+{
+ m_previousSelectMode = g_StudioApp.GetSelectMode();
+ g_StudioApp.SetSelectMode(STUDIO_SELECTMODE_GROUP);
+ setViewCursor();
+ Q_EMIT toolChanged();
+}
+
+//==============================================================================
+/**
+ * OnToolItemSelection: Called when the Item Selection button is pressed.
+ * Sets the current tool mode and changes the cursor.
+ */
+void CSceneView::onToolItemSelection()
+{
+ m_previousSelectMode = g_StudioApp.GetSelectMode();
+ g_StudioApp.SetSelectMode(STUDIO_SELECTMODE_ENTITY);
+ setViewCursor();
+ Q_EMIT toolChanged();
+}
+
+//==============================================================================
+/**
+ * SetViewCursor: Sets the cursor for the view according to the current Client Tool.
+ *
+ * Changes the cursor depending on the current tool mode. Each time the Tool mode
+ * changes, you should call this function. If you add extra tool modes, you
+ * will need to adjust this function.
+ */
+void CSceneView::setViewCursor()
+{
+ long theCurrentToolSettings = g_StudioApp.GetToolMode();
+ long theCurrentSelectSettings = g_StudioApp.GetSelectMode();
+
+ // See what tool mode we are in
+ switch (theCurrentToolSettings) {
+ case STUDIO_TOOLMODE_MOVE:
+ switch (theCurrentSelectSettings) {
+ case STUDIO_SELECTMODE_ENTITY:
+ m_playerWnd->setCursor(m_cursorItemMove);
+ break;
+ case STUDIO_SELECTMODE_GROUP:
+ m_playerWnd->setCursor(m_cursorGroupMove);
+ break;
+ // Default - shouldn't happen
+ default:
+ m_playerWnd->setCursor(m_cursorItemMove);
+ break;
+ }
+ break;
+
+ case STUDIO_TOOLMODE_ROTATE:
+ switch (theCurrentSelectSettings) {
+ case STUDIO_SELECTMODE_ENTITY:
+ m_playerWnd->setCursor(m_cursorItemRotate);
+ break;
+ case STUDIO_SELECTMODE_GROUP:
+ m_playerWnd->setCursor(m_cursorGroupRotate);
+ break;
+ // Default - shouldn't happen
+ default:
+ m_playerWnd->setCursor(m_cursorItemRotate);
+ break;
+ }
+ break;
+
+ case STUDIO_TOOLMODE_SCALE:
+ switch (theCurrentSelectSettings) {
+ case STUDIO_SELECTMODE_ENTITY:
+ m_playerWnd->setCursor(m_cursorItemScale);
+ break;
+ case STUDIO_SELECTMODE_GROUP:
+ m_playerWnd->setCursor(m_cursorGroupScale);
+ break;
+ // Default - shouldn't happen
+ default:
+ m_playerWnd->setCursor(m_cursorItemScale);
+ break;
+ }
+ break;
+
+ case STUDIO_TOOLMODE_CAMERA_PAN:
+ m_playerWnd->setCursor(m_cursorEditCameraPan);
+ break;
+
+ case STUDIO_TOOLMODE_CAMERA_ZOOM:
+ m_playerWnd->setCursor(m_cursorEditCameraZoom);
+ break;
+
+ case STUDIO_TOOLMODE_CAMERA_ROTATE:
+ m_playerWnd->setCursor(m_cursorEditCameraRotate);
+ break;
+
+ // Default - shouldn't happen
+ default:
+ m_playerWnd->setCursor(m_cursorItemMove);
+ break;
+ }
+}
+
+//==============================================================================
+/**
+ * RecalcMatte: Recalculates the matte around the Client based on the settings.
+ *
+ * This will recalculate the matting around the Client based on the Client's
+ * current size. If the Client is a "Fit To Window" mode, then the matte region
+ * is cleared.
+ */
+//==============================================================================
+void CSceneView::recalcMatte()
+{
+ long theXOffset = 0;
+ long theYOffset = 0;
+ QRect theClientRect = rect();
+
+ // Adjust the client area based if rulers are visible
+ if (m_playerContainerWnd) {
+ m_playerContainerWnd->setGeometry(theXOffset, theYOffset,
+ theClientRect.width() - theXOffset,
+ theClientRect.height() - theYOffset);
+
+ // Recenter the Client rect
+ m_playerContainerWnd->RecenterClient();
+ }
+}
+
+void CSceneView::resizeEvent(QResizeEvent* event)
+{
+ QWidget::resizeEvent(event);
+ if (m_playerContainerWnd) {
+ recalcMatte();
+ setPlayerWndPosition();
+ g_StudioApp.GetCore()->GetDoc( )->GetSceneGraph()->RequestRender();
+ }
+}
+
+//==============================================================================
+/**
+ * SetPlayerWndPosition: Sets the position of the child player window
+ *
+ * Called when the view is scrolled to position the child player window
+ *
+ */
+//==============================================================================
+void CSceneView::setPlayerWndPosition()
+{
+ // Move the child player window to coincide with the scrollbars
+ if (m_playerContainerWnd) {
+ long theLeft, theTop;
+ // Retrieve the left and top edge of the presentation currently in view
+ m_playerContainerWnd->SetPlayerWndPosition(theLeft, theTop);
+ m_playerContainerWnd->update();
+ }
+}
+
+//==============================================================================
+/**
+ * Resets its scroll ranges and recenters client in the window. This is called when
+ * an outside source needs to tell the scene view that size ranges have changed such
+ * as the preferences telling the sceneview that the size changed.
+ */
+void CSceneView::recheckSizingMode()
+{
+ if (m_playerContainerWnd)
+ m_playerContainerWnd->SetScrollRanges();
+}
+
+//==============================================================================
+/**
+ * Redirect to PlayerContainerWnd to check whether we are in deployment view mode.
+ * @return true if is in deployment view mode, else false
+ */
+bool CSceneView::isDeploymentView()
+{
+ // Default mode is SCENE_VIEW so if playercontainerwnd does not exist (should only happen on
+ // startup), it is deployment view
+ bool theStatus = true;
+ if (m_playerContainerWnd)
+ theStatus = m_playerContainerWnd->IsDeploymentView();
+
+ return theStatus;
+}
+
+//==============================================================================
+/**
+ * Redirect to PlayerContainerWnd to set the view mode of the current scene view,
+ * whether we are in editing mode or deployment mode. For editing mode, we want to
+ * use the full scene area without any matte area.
+ * @param inViewMode the view mode of this scene
+ */
+void CSceneView::setViewMode(CPlayerContainerWnd::EViewMode inViewMode)
+{
+ if (m_playerContainerWnd)
+ m_playerContainerWnd->SetViewMode(inViewMode);
+}
+
+void CSceneView::setToolMode(long inMode)
+{
+ if (m_playerContainerWnd)
+ m_playerContainerWnd->setToolMode(inMode);
+ setViewCursor();
+}
+
+//==============================================================================
+/**
+ * When the active camera is changed, the display string needs to be changed. Hence
+ * find which entry is the one which is modified and update with the new string
+ * @param inCamera the camera that has been modified
+ */
+void CSceneView::onEditCameraChanged()
+{
+ // Reset any scrolling and recalculate the window position.
+ if (m_playerContainerWnd) {
+ m_playerContainerWnd->SetScrollRanges();
+ recalcMatte();
+ setPlayerWndPosition();
+ }
+
+ // Update the view mode accordingly
+ setViewMode(g_StudioApp.getRenderer().GetEditCamera() >= 0 ? CPlayerContainerWnd::VIEW_EDIT
+ : CPlayerContainerWnd::VIEW_SCENE);
+ m_playerWnd->update();
+}
+
+void CSceneView::onAuthorZoomChanged()
+{
+ onEditCameraChanged();
+}
+
+void CSceneView::onRulerGuideToggled()
+{
+ m_playerContainerWnd->OnRulerGuideToggled();
+}
diff --git a/src/Authoring/Studio/UI/SceneView.h b/src/Authoring/Studio/UI/SceneView.h
new file mode 100644
index 00000000..c4948e39
--- /dev/null
+++ b/src/Authoring/Studio/UI/SceneView.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_SCENE_VIEW_H
+#define INCLUDED_SCENE_VIEW_H 1
+
+#pragma once
+
+#include "PlayerWnd.h"
+#include "PlayerContainerWnd.h"
+#include "DispatchListeners.h"
+
+#include <QtWidgets/qwidget.h>
+#include <QtGui/qcursor.h>
+
+class CHotKeys;
+
+class CSceneView : public QWidget,
+ public CEditCameraChangeListener
+{
+ Q_OBJECT
+protected:
+ QScopedPointer<CPlayerContainerWnd> m_playerContainerWnd; // first-level child
+ QScopedPointer<CPlayerWnd> m_playerWnd; // second-level child (grandchild)
+ QCursor m_arrowCursor; // A pointer to the current cursor (changes according to mode)
+ QCursor m_cursorGroupMove; // The move group cursor
+ QCursor m_cursorGroupRotate; // The rotate group cursor
+ QCursor m_cursorGroupScale; // The scale group cursor
+ QCursor m_cursorItemMove; // The move item cursor
+ QCursor m_cursorItemRotate; // The rotate item cursor
+ QCursor m_cursorItemScale; // The scale item cursor
+ QCursor m_cursorEditCameraPan; // The edit camera pan cursor
+ QCursor m_cursorEditCameraRotate; // The edit camera rotate cursor
+ QCursor m_cursorEditCameraZoom; // The edit camera zoom cursor
+
+ long m_previousSelectMode; // The previous select mode
+
+public:
+ CSceneView(QWidget *parent = nullptr);
+ CSceneView(); // used for serialization only!
+ virtual ~CSceneView();
+
+ void setViewCursor();
+ void recheckSizingMode();
+
+ void setPlayerWndPosition();
+
+ // redirect to/from PlayerContainerWnd
+ bool isDeploymentView();
+ void setViewMode(CPlayerContainerWnd::EViewMode inViewMode);
+ void setToolMode(long inMode);
+
+ void onRulerGuideToggled();
+
+ // CEditCameraChangeListener
+ void onEditCameraChanged() override;
+ void onEditCamerasTransformed() override {}
+ void onAuthorZoomChanged() override;
+
+ QSize sizeHint() const override;
+
+ void onToolGroupSelection();
+ void onToolItemSelection();
+
+ CPlayerWnd *getPlayerWnd() const;
+
+Q_SIGNALS:
+ void toolChanged();
+
+protected:
+ void showEvent(QShowEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+
+private:
+ void recalcMatte();
+ void onDropReceived();
+};
+
+#endif // INCLUDED_SCENE_VIEW_H
diff --git a/src/Authoring/Studio/UI/StartupDlg.cpp b/src/Authoring/Studio/UI/StartupDlg.cpp
new file mode 100644
index 00000000..59b29a1b
--- /dev/null
+++ b/src/Authoring/Studio/UI/StartupDlg.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#include "stdafx.h"
+#include "StudioDefs.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+
+#include "StartupDlg.h"
+#include "StudioPreferences.h"
+#include "ui_StartupDlg.h"
+
+#include <QtCore/qfileinfo.h>
+#include <QtGui/qpalette.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdir.h>
+#include <QtWidgets/qdesktopwidget.h>
+
+// CStartupDlg dialog
+
+CStartupDlg::CStartupDlg(QWidget *pParent)
+ : QDialog(pParent, Qt::MSWindowsFixedSizeDialogHint)
+ , m_Choice(EStartupChoice_Invalid)
+ , m_RecentDocSelected("")
+ , m_ui(new Ui::StartupDlg)
+ , m_palette(nullptr)
+{
+ m_ui->setupUi(this);
+}
+
+CStartupDlg::~CStartupDlg()
+{
+ delete m_palette;
+}
+
+static QString GetFileTimeReadable(const Qt3DSFile &inFile)
+{
+ QFileInfo finfo(inFile.GetAbsolutePath().toQString());
+ if (!finfo.exists())
+ return {};
+
+ return finfo.lastModified().toString("MM/dd/yyyy");
+}
+
+void CStartupDlg::showEvent(QShowEvent *ev)
+{
+ OnInitDialog();
+ QDialog::showEvent(ev);
+}
+
+void CStartupDlg::reject()
+{
+ m_Choice = EStartupChoice_Exit;
+ QDialog::reject();
+}
+
+void CStartupDlg::OnInitDialog()
+{
+ QWidget *p = qobject_cast<QWidget *>(parent());
+ if (p) {
+ QRect pRect;
+ if (p->isMaximized()) {
+ pRect = QApplication::desktop()->availableGeometry(
+ QApplication::desktop()->screenNumber(p));
+ } else {
+ pRect = p->frameGeometry();
+ }
+
+ move(pRect.x() + pRect.width() / 2 - width() / 2,
+ pRect.y() + pRect.height() / 2 - height() / 2);
+ }
+
+ connect(m_ui->newDocument, &ClickableLabel::clicked, this, &CStartupDlg::OnNewDocClicked);
+ connect(m_ui->openDocument, &ClickableLabel::clicked, this, &CStartupDlg::OnOpenDocClicked);
+
+ // Load the product version
+ m_ProductVersionStr = QStringLiteral("Qt 3D Studio v")
+ + CStudioPreferences::GetVersionString().toQString();
+ m_ui->versionStr->setText(m_ProductVersionStr);
+
+ // Populate the recent document list
+ for (uint theIndex = 0; theIndex < RECENT_COUNT; ++theIndex) {
+ ClickableLabel *recent
+ = findChild<ClickableLabel *>(QStringLiteral("recent%1").arg(theIndex));
+ connect(recent, &ClickableLabel::clicked, this, &CStartupDlg::OnStnClickedStartupRecent);
+
+ recent->setProperty("recentIndex", theIndex);
+
+ if (m_RecentDocs.size() > theIndex) {
+ // Set the name
+ recent->setText(m_RecentDocs[theIndex].GetName().toQString());
+ // Set path and date to tooltip
+ QFileInfo thePath(m_RecentDocs[theIndex].GetAbsolutePath().toQString());
+ QString toolTip = thePath.absoluteDir().path();
+ toolTip.append(QStringLiteral("\n"));
+ toolTip.append(GetFileTimeReadable(m_RecentDocs[theIndex]));
+ recent->setToolTip(toolTip);
+ } else {
+ recent->setEnabled(false);
+ recent->setText(QString());
+ }
+ }
+}
+
+void CStartupDlg::AddRecentItem(const Qt3DSFile &inRecentItem)
+{
+ m_RecentDocs.push_back(inRecentItem);
+}
+
+CStartupDlg::EStartupChoice CStartupDlg::GetChoice()
+{
+ return m_Choice;
+}
+
+Qt3DSFile CStartupDlg::GetRecentDoc() const
+{
+ return m_RecentDocSelected;
+}
+
+void CStartupDlg::OnNewDocClicked()
+{
+ m_Choice = EStartupChoice_NewDoc;
+ QDialog::accept();
+}
+
+void CStartupDlg::OnOpenDocClicked()
+{
+ m_Choice = EStartupChoice_OpenDoc;
+ QDialog::accept();
+}
+
+void CStartupDlg::OnStnClickedStartupRecent()
+{
+ const int index = sender()->property("recentIndex").toInt();
+ OpenRecent(index);
+}
+
+void CStartupDlg::OpenRecent(size_t inIndex)
+{
+ if (inIndex < m_RecentDocs.size()) {
+ m_RecentDocSelected = m_RecentDocs[inIndex];
+ m_Choice = EStartupChoice_OpenRecent;
+ QDialog::accept();
+ }
+}
+
+void CStartupDlg::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+ QPixmap pic = QPixmap(":/startup/open_dialog.png");
+ pic.setDevicePixelRatio(devicePixelRatio());
+
+ if (!m_palette) {
+ m_palette = new QPalette;
+ m_palette->setBrush(QPalette::Window, pic);
+ setPalette(*m_palette);
+ }
+
+ resize(pic.size());
+ setFixedSize(size());
+}
diff --git a/src/Authoring/Studio/UI/StartupDlg.h b/src/Authoring/Studio/UI/StartupDlg.h
new file mode 100644
index 00000000..bab905c2
--- /dev/null
+++ b/src/Authoring/Studio/UI/StartupDlg.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2006 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_STARTUP_DLG
+#define INCLUDED_STARTUP_DLG 1
+
+#pragma once
+
+//==============================================================================
+// Includes
+//==============================================================================
+
+#include "Qt3DSString.h"
+#include "Qt3DSFile.h"
+
+#include <QtWidgets/qdialog.h>
+
+#ifdef QT_NAMESPACE
+using namespace QT_NAMESPACE;
+#endif
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+ class StartupDlg;
+}
+QT_END_NAMESPACE
+
+//==============================================================================
+/**
+ * CGLVersionDlg: Dialog class for showing what user can do upon startup
+ */
+//==============================================================================
+class CStartupDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ enum EStartupChoice {
+ EStartupChoice_Invalid = -1,
+ EStartupChoice_NewDoc,
+ EStartupChoice_OpenDoc,
+ EStartupChoice_OpenRecent,
+ EStartupChoice_Exit
+ };
+
+public:
+ CStartupDlg(QWidget *pParent = nullptr); // standard constructor
+ virtual ~CStartupDlg();
+
+protected:
+ const static int RECENT_COUNT = 10;
+
+ void paintEvent(QPaintEvent *event) override;
+ void showEvent(QShowEvent *) override;
+ void reject() override;
+
+protected Q_SLOTS:
+ void OnNewDocClicked();
+ void OnOpenDocClicked();
+ void OnStnClickedStartupRecent();
+ void OpenRecent(size_t inIndex);
+
+private:
+ // Dialog background
+ QPalette *m_palette;
+
+ // Product version string
+ QString m_ProductVersionStr;
+
+ // Choice
+ EStartupChoice m_Choice = EStartupChoice_Invalid;
+
+ // Recent Docs
+ std::vector<Qt3DSFile> m_RecentDocs;
+ Qt3DSFile m_RecentDocSelected;
+
+public:
+ void OnInitDialog();
+ void AddRecentItem(const Qt3DSFile &inRecentItem);
+ EStartupChoice GetChoice();
+ Qt3DSFile GetRecentDoc() const;
+
+private:
+ QScopedPointer<Ui::StartupDlg> m_ui;
+};
+
+#endif // INCLUDED_STARTUP_DLG
diff --git a/src/Authoring/Studio/UI/StartupDlg.ui b/src/Authoring/Studio/UI/StartupDlg.ui
new file mode 100644
index 00000000..54ba58a0
--- /dev/null
+++ b/src/Authoring/Studio/UI/StartupDlg.ui
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StartupDlg</class>
+ <widget class="QDialog" name="StartupDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>442</width>
+ <height>650</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <widget class="QLabel" name="recentDocLabel">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>210</y>
+ <width>411</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>RECENT FILES</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QWidget" name="verticalLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>250</y>
+ <width>401</width>
+ <height>381</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="recentList">
+ <item>
+ <widget class="ClickableLabel" name="recent0">
+ <property name="text">
+ <string>Recent0.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent1">
+ <property name="text">
+ <string>Recent1.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent2">
+ <property name="text">
+ <string>Recent2.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent3">
+ <property name="text">
+ <string>Recent3.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent4">
+ <property name="text">
+ <string>Recent4.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>4</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent5">
+ <property name="text">
+ <string>Recent5.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent6">
+ <property name="text">
+ <string>Recent6.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>6</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent7">
+ <property name="text">
+ <string>Recent7.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>7</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent8">
+ <property name="text">
+ <string>Recent8.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>8</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="recent9">
+ <property name="text">
+ <string>Recent9.uip</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>9</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="verticalLayoutWidget_2">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>130</y>
+ <width>401</width>
+ <height>61</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="buttons">
+ <item>
+ <widget class="ClickableLabel" name="newDocument">
+ <property name="text">
+ <string>Create Project...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ClickableLabel" name="openDocument">
+ <property name="text">
+ <string>Open Project...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="docIndex" stdset="0">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="versionStr">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>90</y>
+ <width>411</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Qt 3D Studio version string</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ClickableLabel</class>
+ <extends>QLabel</extends>
+ <header>ClickableLabel.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/Authoring/Studio/UI/StudioAppPrefsPage.cpp b/src/Authoring/Studio/UI/StudioAppPrefsPage.cpp
new file mode 100644
index 00000000..5eb859e4
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioAppPrefsPage.cpp
@@ -0,0 +1,559 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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 "ui_StudioAppPrefsPage.h"
+
+#include "Doc.h"
+#include "StudioAppPrefsPage.h"
+#include "StudioConst.h"
+#include "StudioProjectSettings.h"
+#include "StudioPreferences.h"
+#include "StudioApp.h"
+#include "StudioPreferences.h"
+#include "CommonConstants.h"
+#include "Views.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "ClientDataModelBridge.h"
+#include "Core.h"
+#include "IStudioRenderer.h"
+
+#include <QtWidgets/qcolordialog.h>
+#include <QtWidgets/qmessagebox.h>
+#include <QtGui/qstandarditemmodel.h>
+#include <QtCore/qdiriterator.h>
+
+//==============================================================================
+/**
+ * Constructor: Initializes the object.
+ */
+//==============================================================================
+CStudioAppPrefsPage::CStudioAppPrefsPage(QWidget *parent)
+ : CStudioPreferencesPropPage(parent)
+ , m_timebarShowTime(false)
+ , m_interpolationIsSmooth(false)
+ , m_restartNeeded(false)
+ , m_autosaveChanged(false)
+ , m_ui(new Ui::StudioAppPrefsPage)
+{
+ m_font = QFont(CStudioPreferences::GetFontFaceName());
+ m_font.setPixelSize(CStudioPreferences::fontSize());
+
+ // Create a bold font for the group box text
+ m_boldFont = m_font;
+ m_boldFont.setBold(true);
+
+ onInitDialog();
+}
+
+//==============================================================================
+/**
+ * Destructor: Releases the object.
+ */
+//==============================================================================
+CStudioAppPrefsPage::~CStudioAppPrefsPage()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CStudioAppPrefsPage message handlers
+
+void CStudioAppPrefsPage::onInitDialog()
+{
+ m_ui->setupUi(this);
+
+ // Add tool tips for controls
+ m_ui->m_DefaultInterpolation->setToolTip(tr("Set default keyframe interpolation type"));
+ m_ui->m_checkTimelineAbsoluteSnapping->setToolTip(tr("Enable timeline snapping grid"));
+ m_ui->m_SnapRangeCombo->setToolTip(tr("Set resolution of timeline snapping grid"));
+ m_ui->m_buttonRestoreDefaults->setToolTip(tr("Click to restore default Studio settings"));
+ m_ui->m_EditViewBGColor->setAutoFillBackground(true);
+
+ // Set fonts for child windows.
+ for (auto w : findChildren<QWidget *>())
+ w->setFont(m_font);
+
+ // Make the group text bold
+ for (auto w : findChildren<QGroupBox *>())
+ w->setFont(m_boldFont);
+
+ // Hidden until we have some other Preview configurations than just Viewer
+ m_ui->groupBoxPreview->setVisible(false);
+
+ // Load the settings for the controls
+ loadSettings();
+
+ auto activated = static_cast<void(QComboBox::*)(int)>(&QComboBox::activated);
+ connect(m_ui->m_buttonRestoreDefaults, &QPushButton::clicked,
+ this, &CStudioAppPrefsPage::onButtonRestoreDefaults);
+ connect(m_ui->m_buttonResetLayout, &QPushButton::clicked, [=](){
+ onApply(); // Save changed preferences before resetting, as it causes Studio to shut down
+ CStudioPreferencesPropPage::endDialog(PREFS_RESET_LAYOUT);
+ });
+ connect(m_ui->m_DefaultInterpolation, activated, this, [=](){ setModified(true); });
+ connect(m_ui->m_SnapRangeCombo, activated, this, [=](){ setModified(true); });
+ connect(m_ui->m_checkTimelineAbsoluteSnapping, &QCheckBox::clicked,
+ this, [=](){ setModified(true); enableOptions(); });
+ connect(m_ui->m_EditViewBGColor, &QPushButton::clicked,
+ this, &CStudioAppPrefsPage::onBgColorButtonClicked);
+ connect(m_ui->m_EditViewStartupView, activated, this, [=](){ setModified(true); });
+ connect(m_ui->selectorWidth,
+ static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ this, [=](){ setModified(true); m_restartNeeded = true; });
+ connect(m_ui->selectorLength,
+ static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ this, [=](){ setModified(true); m_restartNeeded = true; });
+ connect(m_ui->autosaveEnabled, &QCheckBox::clicked, this,
+ [=](){ setModified(true); m_autosaveChanged = true; });
+ connect(m_ui->autosaveInterval, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, [=](){ setModified(true); m_autosaveChanged = true; });
+ connect(m_ui->clearAutosaveFiles, &QPushButton::clicked,
+ this, &CStudioAppPrefsPage::onClearAutosaveFiles);
+#if 0 // Removed until we have some other Preview configurations than just Viewer
+ connect(m_ui->m_PreviewSelector, activated,
+ this, &CStudioAppPrefsPage::onChangePreviewConfiguration);
+#endif
+}
+
+//==============================================================================
+/**
+ * LoadSettings: Load the settings from the CDoc and set the control values.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioAppPrefsPage::loadSettings()
+{
+ // Get the Interpolation Preference
+ m_ui->m_DefaultInterpolation->addItem(tr("Smooth"));
+ m_ui->m_DefaultInterpolation->addItem(tr("Linear"));
+
+ long theInterpolationPref = 0;
+ if (CStudioPreferences::GetInterpolation())
+ theInterpolationPref = 0;
+ else
+ theInterpolationPref = 1;
+ m_ui->m_DefaultInterpolation->setCurrentIndex(theInterpolationPref);
+
+ // Timeline snapping grid
+ m_ui->m_checkTimelineAbsoluteSnapping->setChecked(
+ CStudioPreferences::IsTimelineSnappingGridActive());
+
+ // Tool handles
+ m_ui->selectorWidth->setValue(CStudioPreferences::getSelectorLineWidth());
+ m_ui->selectorLength->setValue(CStudioPreferences::getSelectorLineLength());
+
+ // The scale mode
+ m_ui->m_SnapRangeCombo->addItem(tr("Low Resolution"));
+ m_ui->m_SnapRangeCombo->addItem(tr("Medium Resolution"));
+ m_ui->m_SnapRangeCombo->addItem(tr("High Resolution"));
+ long theResolution = (long)CStudioPreferences::GetTimelineSnappingGridResolution();
+ m_ui->m_SnapRangeCombo->setCurrentIndex(theResolution);
+
+ // Autosave options
+ m_ui->autosaveEnabled->setChecked(CStudioPreferences::GetAutoSavePreference());
+ m_ui->autosaveInterval->setValue(CStudioPreferences::GetAutoSaveDelay());
+
+ onitEditStartViewCombo();
+
+ enableOptions();
+
+#if 0 // Removed until we have some other Preview configurations than just Viewer
+ loadPreviewSelections();
+#endif
+
+ m_bgColor = CStudioPreferences::GetEditViewBackgroundColor();
+ updateColorButton();
+}
+
+void CStudioAppPrefsPage::updateColorButton()
+{
+ QString bgColorStyle = QStringLiteral("background-color: ") + m_bgColor.name();
+ m_ui->m_EditViewBGColor->setStyleSheet(bgColorStyle);
+ setModified(true);
+}
+
+//==============================================================================
+/**
+ * SaveSettings: Save the settings from the controls to the CDoc
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioAppPrefsPage::saveSettings()
+{
+ // Default interpolation
+ g_StudioApp.GetCore()->GetDoc()->SetDefaultKeyframeInterpolation(
+ m_ui->m_DefaultInterpolation->currentIndex() == 0);
+
+ // Timeline snapping grid
+ CStudioPreferences::SetTimelineSnappingGridActive(
+ m_ui->m_checkTimelineAbsoluteSnapping->isChecked());
+ long theCurrentSelection = m_ui->m_SnapRangeCombo->currentIndex();
+ CStudioPreferences::SetTimelineSnappingGridResolution((ESnapGridResolution)theCurrentSelection);
+
+ // Edit View Background Color
+ CStudioPreferences::SetEditViewBackgroundColor(m_bgColor);
+
+ // Preferred Startup View
+ long theSel = m_ui->m_EditViewStartupView->currentIndex();
+ long theNumItems = m_ui->m_EditViewStartupView->count();
+ CStudioPreferences::SetPreferredStartupView(
+ (theSel == theNumItems - 1) ? -1 : theSel); // -1 for deployment view
+
+ // Tool handles
+ CStudioPreferences::setSelectorLineWidth(m_ui->selectorWidth->value());
+ CStudioPreferences::setSelectorLineLength(m_ui->selectorLength->value());
+
+ // Autosave options
+ CStudioPreferences::SetAutoSavePreference(m_ui->autosaveEnabled->isChecked());
+ CStudioPreferences::SetAutoSaveDelay(m_ui->autosaveInterval->value());
+ enableAutosave(m_ui->autosaveEnabled->isChecked());
+ setAutosaveInterval(m_ui->autosaveInterval->value());
+ m_autosaveChanged = false;
+
+#if 0 // Removed until we have some other Preview configurations than just Viewer
+ savePreviewSettings();
+#endif
+
+ if (m_restartNeeded) {
+ // If handles changed, a restart of Studio is needed
+ QMessageBox::information(this, tr("Restart Needed"),
+ tr("Some settings were changed that require a"
+ " restart of the Qt 3D Studio to take effect."));
+ // Just show the dialog once (unless the values are changed again)
+ m_restartNeeded = false;
+ }
+}
+
+//==============================================================================
+/**
+ * OnApply: Handler for the Apply button
+ *
+ * @param None
+ */
+//==============================================================================
+bool CStudioAppPrefsPage::onApply()
+{
+ // Apply was clicked - save settings and disable the Apply button
+ saveSettings();
+
+ setModified(false);
+
+ // Request that the renderer refreshes as settings may have changed
+ g_StudioApp.getRenderer().RequestRender();
+
+ return CStudioPreferencesPropPage::onApply();
+}
+
+//==============================================================================
+/**
+ * OnOK: Handler for the OK button
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioAppPrefsPage::onOK()
+{
+ CStudioPreferencesPropPage::onOK();
+}
+
+//==============================================================================
+/**
+ * OnButtonRestoreDefaults: Restore the defaults and exit the preferences.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioAppPrefsPage::onButtonRestoreDefaults()
+{
+ int theChoice = 0;
+
+ // Ask the user if she really wants to do this
+ theChoice = QMessageBox::question(this,
+ tr("Restore Defaults"),
+ tr("Are you sure that you want to restore all program "
+ "\ndefaults? Your current settings will be lost."));
+
+ // If the "yes" button was selected
+ if (theChoice == QMessageBox::Yes) {
+ // Restore default preferences by passing PREFS_RESET_DEFAULTS back
+ // to the CStudioDocPreferences (that called this preferences sheet)
+ CStudioPreferencesPropPage::endDialog(PREFS_RESET_DEFAULTS);
+ }
+}
+
+//==============================================================================
+/**
+ * EnableOptions: Enable/disable options.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioAppPrefsPage::enableOptions()
+{
+ m_ui->m_SnapRangeCombo->setEnabled(m_ui->m_checkTimelineAbsoluteSnapping->isChecked());
+}
+
+//==============================================================================
+/**
+ * Initialise the combo box that displays the preferred startup view.
+ * Set the initial selection to that saved to the preferences
+ */
+//==============================================================================
+void CStudioAppPrefsPage::onitEditStartViewCombo()
+{
+ Q3DStudio::IStudioRenderer &theRenderer = g_StudioApp.getRenderer();
+ QStringList theCameraNames;
+ theRenderer.GetEditCameraList(theCameraNames);
+ for (int idx = 0, end = theCameraNames.size(); idx < end; ++idx) {
+ m_ui->m_EditViewStartupView->addItem(
+ theCameraNames.at(idx));
+ m_ui->m_EditViewStartupView->setItemData(m_ui->m_EditViewStartupView->count() - 1,
+ QVariant((int)idx + 1));
+ }
+
+ m_ui->m_EditViewStartupView->addItem("--------------------------");
+ m_ui->m_EditViewStartupView->setItemData(m_ui->m_EditViewStartupView->count() - 1, -1); // set to an invalid pointer
+ // make item non-selectable
+ QStandardItemModel *model =
+ qobject_cast<QStandardItemModel *>(m_ui->m_EditViewStartupView->model());
+ QStandardItem *item = model->item(theCameraNames.size());
+ item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
+
+ // add the deployment view as the last selection
+ m_ui->m_EditViewStartupView->addItem(tr("Scene Camera View"));
+ m_ui->m_EditViewStartupView->setItemData(m_ui->m_EditViewStartupView->count() - 1, 0);
+
+ long thePreferredView = CStudioPreferences::GetPreferredStartupView();
+ long theNumItems = m_ui->m_EditViewStartupView->count();
+ if (thePreferredView == -1) // deployment view
+ m_ui->m_EditViewStartupView->setCurrentIndex(theNumItems - 1); // set to the last one
+ else if (thePreferredView < theNumItems - 1)
+ m_ui->m_EditViewStartupView->setCurrentIndex(thePreferredView);
+ else // possibly from old content where cameras are removed
+ m_ui->m_EditViewStartupView->setCurrentIndex(0);
+}
+
+#if 0 // Removed until we have some other Preview configurations than just Viewer
+void CStudioAppPrefsPage::loadPreviewSelections()
+{
+ // Load the configurations from all the .build files
+ Q3DStudio::CBuildConfigurations &theConfig = g_StudioApp.GetCore()->GetBuildConfigurations();
+ Q3DStudio::CBuildConfigurations::TBuildConfigurations theConfigurations =
+ theConfig.GetConfigurations();
+ Q3DStudio::CBuildConfigurations::TBuildConfigurations::iterator theIter;
+ for (theIter = theConfigurations.begin(); theIter != theConfigurations.end(); ++theIter) {
+ const Q3DStudio::CString &theConfig = theIter->first;
+ m_ui->m_PreviewSelector->addItem(theConfig.toQString());
+ m_ui->m_PreviewSelector->setItemData(m_ui->m_PreviewSelector->count() - 1,
+ QVariant::fromValue(theIter->second));
+ }
+
+ int thePreviewSelected = m_ui->m_PreviewSelector->findText(
+ CStudioPreferences::GetPreviewConfig().toQString());
+ m_ui->m_PreviewSelector->setCurrentIndex(thePreviewSelected);
+ if (thePreviewSelected == -1) {
+ // select the first build configuration, or if no conriguration, the first application, i.e.
+ // AMPlayer
+ m_ui->m_PreviewSelector->setCurrentIndex(0);
+ long thePreviewCount = m_ui->m_PreviewSelector->count();
+ for (long theIndex = 0; theIndex < thePreviewCount; ++theIndex) {
+ if (m_ui->m_PreviewSelector->itemData(
+ theIndex).value<Q3DStudio::CBuildConfiguration *>() != nullptr) {
+ m_ui->m_PreviewSelector->setCurrentIndex(theIndex);
+ break;
+ }
+ }
+ }
+
+ LoadBuildProperties();
+}
+
+//==============================================================================
+/**
+ * When the build configuration is changed, all the properties have to be updated.
+ */
+//==============================================================================
+void CStudioAppPrefsPage::onChangePreviewConfiguration()
+{
+ LoadBuildProperties();
+}
+#endif
+
+void CStudioAppPrefsPage::onBgColorButtonClicked()
+{
+ QColor previousColor = m_bgColor;
+ QColorDialog *theColorDlg = new QColorDialog(previousColor, this);
+ theColorDlg->setOption(QColorDialog::DontUseNativeDialog, true);
+ connect(theColorDlg, &QColorDialog::currentColorChanged,
+ this, &CStudioAppPrefsPage::onBackgroundColorChanged);
+ if (theColorDlg->exec() == QDialog::Accepted)
+ m_bgColor = theColorDlg->selectedColor();
+ else
+ m_bgColor = previousColor;
+ updateColorButton();
+ CStudioPreferences::SetEditViewBackgroundColor(m_bgColor);
+ g_StudioApp.getRenderer().RequestRender();
+}
+
+void CStudioAppPrefsPage::onBackgroundColorChanged(const QColor &color)
+{
+ m_bgColor = color;
+ updateColorButton();
+ CStudioPreferences::SetEditViewBackgroundColor(m_bgColor);
+ g_StudioApp.getRenderer().RequestRender();
+}
+
+void CStudioAppPrefsPage::enableAutosave(bool enabled)
+{
+ if (m_autosaveChanged)
+ g_StudioApp.SetAutosaveEnabled(enabled);
+}
+
+void CStudioAppPrefsPage::setAutosaveInterval(int interval)
+{
+ if (m_autosaveChanged)
+ g_StudioApp.SetAutosaveInterval(interval);
+}
+
+void CStudioAppPrefsPage::onClearAutosaveFiles()
+{
+ // Find all *_autosave.uip files and delete them
+ QDirIterator files(g_StudioApp.GetCore()->GetDoc()->GetDocumentDirectory().toQString());
+ while (files.hasNext()) {
+ if (files.next().endsWith(QStringLiteral("_autosave.uip")))
+ QFile::remove(files.filePath());
+ }
+}
+
+//==============================================================================
+/**
+ * Load the build properties for the current preview application selected
+ */
+//==============================================================================
+#if 0 // Removed until we have some other Preview configurations than just Viewer
+void CStudioAppPrefsPage::loadBuildProperties()
+{
+ // Remove those dynamic controls
+ RemovePreviewPropertyControls();
+
+ if (m_ui->m_PreviewSelector->count() > 0) {
+ Q3DStudio::CBuildConfiguration *theConfig =
+ m_ui->m_PreviewSelector->itemData(
+ m_ui->m_PreviewSelector->currentIndex())
+ .value<Q3DStudio::CBuildConfiguration *>();
+ if (theConfig) {
+ // Only configuration read from .build files will have the ItemDataPtr set.
+
+ Q3DStudio::CBuildConfiguration::TConfigProperties &theProperties =
+ theConfig->GetBuildProperties();
+
+ auto layout = qobject_cast<QFormLayout *>(m_ui->groupBoxPreview->layout());
+ auto activated = static_cast<void(QComboBox::*)(int)>(&QComboBox::activated);
+
+ if (theProperties.empty() == false) {
+ Q3DStudio::CBuildConfiguration::TConfigProperties::iterator theIter;
+
+ for (theIter = theProperties.begin(); theIter != theProperties.end(); ++theIter) {
+ Q3DStudio::CBuildConfiguration::TConfigPropertyValues &theValues =
+ theIter->GetAcceptableValues();
+ // Only create the combo if there is more than 1 choices
+ if (theValues.size() > 1) {
+ Q3DStudio::CBuildConfiguration::TConfigPropertyValues::iterator
+ theValueIter;
+ long theMaxLength = 0;
+ for (theValueIter = theValues.begin(); theValueIter != theValues.end();
+ ++theValueIter) {
+ long theLabelLength = theValueIter->GetLabel().Length();
+ if (theLabelLength > theMaxLength)
+ theMaxLength = theLabelLength;
+ }
+
+ QLabel *theStaticText = new QLabel(theIter->GetLabel().toQString());
+ theStaticText->setFont(m_Font);
+ QComboBox *thePropertyDropdown = new QComboBox();
+ connect(thePropertyDropdown, activated, [&]() {SetModified(true);});
+ thePropertyDropdown->setFont(m_Font);
+ layout->addRow(theStaticText, thePropertyDropdown);
+
+ m_BuildProperties.push_back(std::make_pair(
+ &*theIter, std::make_pair(theStaticText, thePropertyDropdown)));
+
+ Q3DStudio::CString thePropertyValue =
+ CStudioPreferences::GetPreviewProperty(theIter->GetName());
+ for (theValueIter = theValues.begin(); theValueIter != theValues.end();
+ ++theValueIter) {
+ thePropertyDropdown->addItem(theValueIter->GetLabel().toQString());
+ thePropertyDropdown->setItemData(thePropertyDropdown->count() - 1, QVariant::fromValue(&*theValueIter));
+ if (theValueIter->GetName() == thePropertyValue)
+ thePropertyDropdown->setCurrentIndex(thePropertyDropdown->count() - 1);
+ }
+
+ // Select the first entry
+ if (thePropertyDropdown->currentIndex() == -1)
+ thePropertyDropdown->setCurrentIndex(0);
+ }
+ }
+ }
+ }
+ }
+}
+
+void CStudioAppPrefsPage::SavePreviewSettings()
+{
+ QString thePreviewApp = m_ui->m_PreviewSelector->currentText();
+ CStudioPreferences::SetPreviewConfig(Q3DStudio::CString::fromQString(thePreviewApp));
+
+ std::list<TBuildNameControlPair>::iterator theIter;
+ for (theIter = m_BuildProperties.begin(); theIter != m_BuildProperties.end(); ++theIter) {
+ QComboBox *theCombo = theIter->second.second;
+ Q3DStudio::CString theName = theIter->first->GetName();
+ Q3DStudio::CBuildConfiguration::SConfigPropertyValue *thePropertyValue =
+ theCombo->itemData(theCombo->currentIndex())
+ .value<Q3DStudio::CBuildConfiguration::SConfigPropertyValue *>();
+ CStudioPreferences::SetPreviewProperty(theName, thePropertyValue->GetName());
+ }
+}
+
+//==============================================================================
+/**
+ * Remove all the dynamically added controls that was read in from the build file
+ */
+//==============================================================================
+void CStudioAppPrefsPage::RemovePreviewPropertyControls()
+{
+ // Remove the created control
+ std::list<TBuildNameControlPair>::iterator theIter;
+ for (theIter = m_BuildProperties.begin(); theIter != m_BuildProperties.end(); ++theIter) {
+ delete theIter->second.first;
+ delete theIter->second.second;
+ }
+ m_BuildProperties.clear();
+}
+#endif
diff --git a/src/Authoring/Studio/UI/StudioAppPrefsPage.h b/src/Authoring/Studio/UI/StudioAppPrefsPage.h
new file mode 100644
index 00000000..26a8f280
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioAppPrefsPage.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef STUDIOAPPPREFSPAGE_H_
+#define STUDIOAPPPREFSPAGE_H_
+
+#include "BuildConfigParser.h"
+
+#include "StudioPreferencesPropSheet.h"
+
+QT_FORWARD_DECLARE_CLASS(QComboBox)
+QT_FORWARD_DECLARE_CLASS(QLabel)
+
+QT_BEGIN_NAMESPACE
+namespace Ui
+{
+ class StudioAppPrefsPage;
+}
+QT_END_NAMESPACE
+
+class CStudioAppPrefsPage : public CStudioPreferencesPropPage
+{
+ Q_OBJECT
+protected:
+ typedef std::pair<QLabel *, QComboBox *> TBuildLabelDropdownPair;
+ typedef std::pair<Q3DStudio::CBuildConfiguration::SConfigProperty *, TBuildLabelDropdownPair>
+ TBuildNameControlPair;
+
+public:
+ explicit CStudioAppPrefsPage(QWidget *parent = nullptr);
+ ~CStudioAppPrefsPage();
+
+ // Dialog Data
+ QColor m_bgColor;
+
+public:
+ bool onApply() override;
+ void onOK() override;
+ void onBackgroundColorChanged(const QColor &color);
+
+protected:
+ bool m_timebarShowTime; // TRUE if timebars are to display their time value
+ bool m_interpolationIsSmooth; // TRUE if default interpolation is smooth
+ QFont m_font; // Font for text
+ QFont m_boldFont; // Bold font for drawing the group boxes
+ bool m_restartNeeded;
+ bool m_autosaveChanged;
+
+ void enableOptions();
+ void loadSettings();
+ void saveSettings();
+
+ virtual void onInitDialog();
+ void onButtonRestoreDefaults();
+#if 0 // Removed until we have some other Preview configurations that just Viewer
+ void onChangePreviewConfiguration();
+#endif
+ void onBgColorButtonClicked();
+
+ void enableAutosave(bool enabled);
+ void setAutosaveInterval(int interval);
+ void onClearAutosaveFiles();
+ void onitEditStartViewCombo();
+
+protected:
+ std::list<TBuildNameControlPair> m_buildProperties; // List of build properties, either
+ // ComboBox or Static
+
+#if 0 // Removed until we have some other Preview configurations that just Viewer
+ void loadPreviewSelections();
+ void loadBuildProperties();
+ void savePreviewSettings();
+ void removePreviewPropertyControls();
+#endif
+ QScopedPointer<QT_PREPEND_NAMESPACE(Ui::StudioAppPrefsPage)> m_ui;
+
+private:
+ void updateColorButton();
+};
+
+#endif
diff --git a/src/Authoring/Studio/UI/StudioAppPrefsPage.ui b/src/Authoring/Studio/UI/StudioAppPrefsPage.ui
new file mode 100644
index 00000000..6d24979d
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioAppPrefsPage.ui
@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StudioAppPrefsPage</class>
+ <widget class="QWidget" name="StudioAppPrefsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>347</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>General</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Default Interpolation</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_DefaultInterpolation</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="m_DefaultInterpolation"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="m_SnapRangeCombo"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="m_checkTimelineAbsoluteSnapping">
+ <property name="text">
+ <string>Timeline Snapping Grid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="m_groupBoxEditingView">
+ <property name="title">
+ <string>Editing View</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Background Color</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_EditViewBGColor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" colspan="2">
+ <widget class="QPushButton" name="m_EditViewBGColor">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Preferred Startup View</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_EditViewStartupView</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="2">
+ <widget class="QComboBox" name="m_EditViewStartupView"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBoxToolHandles">
+ <property name="title">
+ <string>Manipulator Tool Handles</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="selectorWidth">
+ <property name="toolTip">
+ <string>The width of the 3D view
+manipulator tool handles</string>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="minimum">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.500000000000000</double>
+ </property>
+ <property name="value">
+ <double>3.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Width</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Length</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QDoubleSpinBox" name="selectorLength">
+ <property name="toolTip">
+ <string>The length of the 3D view
+manipulator tool handles</string>
+ </property>
+ <property name="decimals">
+ <number>0</number>
+ </property>
+ <property name="minimum">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>50.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBoxAutosave">
+ <property name="title">
+ <string>Autosave</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="autosaveEnabled">
+ <property name="text">
+ <string>Autosave Enabled</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="intervalLabel">
+ <property name="text">
+ <string>Interval (seconds)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QSpinBox" name="autosaveInterval">
+ <property name="toolTip">
+ <string>The length of the 3D view
+manipulator tool handles.</string>
+ </property>
+ <property name="minimum">
+ <number>30</number>
+ </property>
+ <property name="maximum">
+ <number>3600</number>
+ </property>
+ <property name="singleStep">
+ <number>30</number>
+ </property>
+ <property name="value">
+ <number>600</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="clearAutosaveFiles">
+ <property name="toolTip">
+ <string>Clear all autosave files from project folder</string>
+ </property>
+ <property name="text">
+ <string>Clear Autosave Files</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_buttonRestoreDefaults">
+ <property name="maximumSize">
+ <size>
+ <width>293</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Restore Defaults</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_buttonResetLayout">
+ <property name="toolTip">
+ <string>Click to restore default Studio
+palette positions and visibilities</string>
+ </property>
+ <property name="text">
+ <string>Reset Layout</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBoxPreview">
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Configuration</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_PreviewSelector</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="m_PreviewSelector"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/Authoring/Studio/UI/StudioPreferencesPropSheet.cpp b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.cpp
new file mode 100644
index 00000000..6edb1cfb
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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 "ui_StudioPreferencesPropSheet.h"
+
+#include "StudioPreferences.h"
+#include "StudioPreferencesPropSheet.h"
+#include "StudioProjectSettingsPage.h"
+
+#include <QtWidgets/qpushbutton.h>
+
+CStudioPreferencesPropPage::CStudioPreferencesPropPage(QWidget *parent)
+ : QWidget(parent)
+{
+}
+
+void CStudioPreferencesPropPage::setModified(bool modified)
+{
+ setProperty("modified", modified);
+
+ auto s = sheet();
+ if (s) {
+ auto buttons = s->findChild<QDialogButtonBox *>();
+ bool anyModified = false;
+ for (auto page : s->findChildren<CStudioPreferencesPropPage *>())
+ anyModified |= page->property("modified").toBool();
+ buttons->button(QDialogButtonBox::Apply)->setEnabled(anyModified);
+ }
+}
+
+CStudioPreferencesPropSheet* CStudioPreferencesPropPage::sheet()
+{
+ QWidget *parent = parentWidget();
+ while (parent != nullptr) {
+ if (auto sheet = qobject_cast<CStudioPreferencesPropSheet *>(parent))
+ return sheet;
+ parent = parent->parentWidget();
+ }
+ return nullptr;
+}
+
+
+void CStudioPreferencesPropPage::endDialog(int returnCode)
+{
+ auto s = sheet();
+ if (s)
+ s->done(returnCode);
+}
+
+CStudioPreferencesPropSheet::CStudioPreferencesPropSheet(const QString &pszCaption,
+ QWidget *pParentWnd,
+ int iSelectPage)
+ : QDialog(pParentWnd)
+ , m_ui(new Ui::StudioPreferencesPropSheet)
+{
+ setWindowTitle(pszCaption);
+ onInitDialog();
+ m_ui->m_TabCtrl->setCurrentIndex(iSelectPage);
+}
+
+CStudioPreferencesPropSheet::~CStudioPreferencesPropSheet()
+{
+}
+
+void CStudioPreferencesPropSheet::onInitDialog()
+{
+ m_ui->setupUi(this);
+ m_ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
+
+ m_Font = QFont(CStudioPreferences::GetFontFaceName(), 8);
+ setFont(m_Font);
+
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked,
+ this, &CStudioPreferencesPropSheet::apply);
+}
+
+bool CStudioPreferencesPropSheet::apply()
+{
+ for (auto page : findChildren<CStudioPreferencesPropPage *>()) {
+ if (!page->onApply())
+ return false;
+ }
+ return true;
+}
+
+void CStudioPreferencesPropSheet::accept()
+{
+ if (apply())
+ QDialog::accept();
+}
+
+void CStudioPreferencesPropSheet::reject()
+{
+ for (auto page : findChildren<CStudioPreferencesPropPage *>())
+ page->onCancel();
+ QDialog::reject();
+}
diff --git a/src/Authoring/Studio/UI/StudioPreferencesPropSheet.h b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.h
new file mode 100644
index 00000000..e732cd21
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef STUDIOPREFERENCESPROPSHEET_H
+#define STUDIOPREFERENCESPROPSHEET_H
+
+#pragma once
+
+#include <QtWidgets/qdialog.h>
+
+class CStudioProjectSettingsPage;
+class CStudioPreferencesPropSheet;
+class CStudioApp;
+
+QT_BEGIN_NAMESPACE
+namespace Ui
+{
+ class StudioPreferencesPropSheet;
+}
+QT_END_NAMESPACE
+
+class CStudioPreferencesPropPage : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit CStudioPreferencesPropPage(QWidget *parent = nullptr);
+
+ virtual bool onApply() { onOK(); setModified(false); return true; }
+ virtual void onOK() {}
+ virtual void onCancel() {}
+
+protected:
+ CStudioPreferencesPropSheet* sheet();
+
+ void setModified(bool modified);
+ void endDialog(int returnCode);
+};
+
+class CStudioPreferencesPropSheet : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit CStudioPreferencesPropSheet(const QString &pszCaption, QWidget *pParentWnd = nullptr,
+ int iSelectPage = 0);
+
+protected:
+ QFont m_Font; // Font for text
+
+public:
+ virtual ~CStudioPreferencesPropSheet();
+
+protected:
+ virtual void onInitDialog();
+
+ bool apply();
+ void accept() override;
+ void reject() override;
+
+private:
+ QScopedPointer<QT_PREPEND_NAMESPACE(Ui::StudioPreferencesPropSheet)> m_ui;
+};
+
+#endif
diff --git a/src/Authoring/Studio/UI/StudioPreferencesPropSheet.ui b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.ui
new file mode 100644
index 00000000..4fd305d0
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioPreferencesPropSheet.ui
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StudioPreferencesPropSheet</class>
+ <widget class="QDialog" name="StudioPreferencesPropSheet">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>382</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Studio Preferences</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="m_TabCtrl">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="CStudioAppPrefsPage" name="m_AppPrefsPage">
+ <attribute name="icon">
+ <iconset resource="../../images.qrc">
+ <normaloff>:/images/prefstab-00.png</normaloff>:/images/prefstab-00.png</iconset>
+ </attribute>
+ <attribute name="title">
+ <string>Studio</string>
+ </attribute>
+ </widget>
+ <widget class="CStudioProjectSettingsPage" name="m_ProjectSettingsPage">
+ <attribute name="icon">
+ <iconset resource="../../images.qrc">
+ <normaloff>:/images/prefstab-01.png</normaloff>:/images/prefstab-01.png</iconset>
+ </attribute>
+ <attribute name="title">
+ <string>Presentation Settings</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>CStudioProjectSettingsPage</class>
+ <extends>QWidget</extends>
+ <header>StudioProjectSettingsPage.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>CStudioAppPrefsPage</class>
+ <extends>QWidget</extends>
+ <header>StudioAppPrefsPage.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../../images.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>StudioPreferencesPropSheet</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>StudioPreferencesPropSheet</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/Authoring/Studio/UI/StudioProjectSettingsPage.cpp b/src/Authoring/Studio/UI/StudioProjectSettingsPage.cpp
new file mode 100644
index 00000000..240d96f9
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioProjectSettingsPage.cpp
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+
+#include "stdafx.h"
+
+#include "ui_StudioProjectSettingsPage.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "StudioProjectSettingsPage.h"
+#include "StudioProjectSettings.h"
+#include "StudioApp.h"
+#include "Doc.h"
+#include "Views.h"
+#include "MainFrm.h"
+#include "CommonConstants.h"
+
+#include "StudioPreferences.h"
+#include "Core.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CStudioProjectSettingsPage property page
+
+//==============================================================================
+/**
+ * Constructor: Initializes the object.
+ */
+//==============================================================================
+CStudioProjectSettingsPage::CStudioProjectSettingsPage(QWidget *parent)
+ : CStudioPreferencesPropPage(parent)
+ , m_AspectRatio(0.0f)
+ , m_ui(new Ui::StudioProjectSettingsPage)
+{
+ m_Font = QFont(CStudioPreferences::GetFontFaceName());
+ m_Font.setPixelSize(CStudioPreferences::fontSize());
+
+ // Create a bold font for the group box text
+ m_BoldFont = m_Font;
+ m_BoldFont.setBold(true);
+
+ OnInitDialog();
+}
+
+//==============================================================================
+/**
+ * Destructor: Releases the object.
+ */
+//==============================================================================
+CStudioProjectSettingsPage::~CStudioProjectSettingsPage()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CStudioProjectSettingsPage message handlers
+
+//==============================================================================
+/**
+ * OnInitDialog: Handle the WM_INITDIALOG message.
+ *
+ * Initialize the dialog by setting the various control values.
+ *
+ * @param None
+ *
+ * @return Returns TRUE always.
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnInitDialog()
+{
+ m_ui->setupUi(this);
+
+ m_ui->m_ClientSizeWidth->setToolTip(tr("Presentation Width"));
+ m_ui->m_ClientSizeHeight->setToolTip(tr("Presentation Height"));
+ m_ui->m_checkConstrainProportions->setToolTip(tr("Check to maintain the aspect ratio when "
+ "changing presentation width or height"));
+ m_ui->m_Author->setToolTip(tr("Enter an author name for this presentation"));
+ m_ui->m_Company->setToolTip(tr("Enter a company name for this presentation"));
+
+ // Set fonts for child windows.
+ for (auto w : findChildren<QWidget *>())
+ w->setFont(m_Font);
+
+ // Make the group text bold
+ for (auto w : findChildren<QGroupBox *>())
+ w->setFont(m_BoldFont);
+
+ // Set the ranges of the client width and height
+ m_ui->m_ClientSizeWidth->setRange(1, 16384);
+ m_ui->m_ClientSizeHeight->setRange(1, 16384);
+
+ // Load the settings for the controls
+ this->LoadSettings();
+
+ auto valueChanged = static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged);
+ connect(m_ui->m_ClientSizeWidth, valueChanged,
+ this, &CStudioProjectSettingsPage::OnChangeEditPresWidth);
+ connect(m_ui->m_ClientSizeHeight, valueChanged,
+ this, &CStudioProjectSettingsPage::OnChangeEditPresHeight);
+ connect(m_ui->m_checkConstrainProportions, &QCheckBox::clicked,
+ this, &CStudioProjectSettingsPage::OnCheckMaintainRatio);
+ connect(m_ui->m_Author, &QLineEdit::textEdited,
+ this, &CStudioProjectSettingsPage::OnChangeAuthor);
+ connect(m_ui->m_Company, &QLineEdit::textEdited,
+ this, &CStudioProjectSettingsPage::OnChangeCompany);
+}
+
+//==============================================================================
+/**
+ * LoadSettings: Load the settings from the project settings and set the control values.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::LoadSettings()
+{
+ // Get the Client size
+ CStudioProjectSettings *theProjectSettings = g_StudioApp.GetCore()->GetStudioProjectSettings();
+ CPt theClientSize = theProjectSettings->GetPresentationSize();
+
+ // Set client width & height
+ m_ui->m_ClientSizeWidth->setValue(theClientSize.x);
+ m_ui->m_ClientSizeHeight->setValue(theClientSize.y);
+
+ // Save the aspect ratio
+ m_AspectRatio = (double)theClientSize.x / (double)theClientSize.y;
+
+ // Maintain Aspect Ratio checkbox
+ m_ui->m_checkConstrainProportions->setChecked(theProjectSettings->GetMaintainAspect());
+
+ m_ui->m_checkPortraitFormat->setChecked(theProjectSettings->GetRotatePresentation());
+
+ // Author
+ m_ui->m_Author->setText(theProjectSettings->GetAuthor());
+
+ // Company
+ m_ui->m_Company->setText(theProjectSettings->GetCompany());
+}
+
+//==============================================================================
+/**
+ * SaveSettings: Save the settings from the controls to the project settings.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::SaveSettings()
+{
+ CPt theClientSize;
+ CStudioProjectSettings *theProjectSettings = g_StudioApp.GetCore()->GetStudioProjectSettings();
+
+ // Presentation width & height
+ theClientSize.x = m_ui->m_ClientSizeWidth->value();
+ theClientSize.y = m_ui->m_ClientSizeHeight->value();
+ theProjectSettings->SetPresentationSize(theClientSize);
+
+ // Author
+ QString theAuthor = m_ui->m_Author->text();
+ theProjectSettings->SetAuthor(theAuthor);
+
+ // Company
+ QString theCompany = m_ui->m_Company->text();
+ theProjectSettings->SetCompany(theCompany);
+
+ g_StudioApp.GetViews()->recheckMainframeSizingMode();
+
+ // Maintain Aspect Ratio checkbox
+ theProjectSettings->SetMaintainAspect(m_ui->m_checkConstrainProportions->isChecked());
+
+ theProjectSettings->SetRotatePresentation(m_ui->m_checkPortraitFormat->isChecked());
+}
+
+//==============================================================================
+/**
+ * Generic function when settings are modified.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnSettingsModified()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnApply: Handler for the Apply button
+ *
+ * @param None
+ */
+//==============================================================================
+bool CStudioProjectSettingsPage::onApply()
+{
+ // Apply was clicked - save settings and disabled the Apply button
+ this->SaveSettings();
+
+ this->setModified(FALSE);
+
+ return CStudioPreferencesPropPage::onApply();
+}
+
+//==============================================================================
+/**
+ * OnOK: Handler for the OK button
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::onOK()
+{
+ CStudioPreferencesPropPage::onOK();
+}
+
+//==============================================================================
+/**
+ * OnChangeEditPresWidth: EN_CHANGE handler for the IDC_EDIT_PRESWIDTH field
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeEditPresWidth()
+{
+ this->setModified(TRUE);
+
+ // Should the aspect ratio be maintained?
+ if (m_ui->m_checkConstrainProportions->isChecked()) {
+ long thePresWidth, thePresHeight;
+
+ thePresWidth = m_ui->m_ClientSizeWidth->value();
+
+ // Change the height
+ thePresHeight = ((double)thePresWidth / m_AspectRatio);
+
+ QSignalBlocker sb(m_ui->m_ClientSizeHeight);
+ m_ui->m_ClientSizeHeight->setValue(thePresHeight);
+ }
+}
+
+//==============================================================================
+/**
+ * OnChangeEditPresHeight: EN_CHANGE handler for the IDC_EDIT_PRESHEIGHT field
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeEditPresHeight()
+{
+ this->setModified(TRUE);
+
+ // Should the aspect ratio be maintained?
+ if (m_ui->m_checkConstrainProportions->isChecked()) {
+ long thePresWidth, thePresHeight;
+
+ thePresHeight = m_ui->m_ClientSizeHeight->value();
+
+ // Change the width
+ thePresWidth = ((double)thePresHeight * m_AspectRatio);
+
+ QSignalBlocker sb(m_ui->m_ClientSizeWidth);
+ m_ui->m_ClientSizeWidth->setValue(thePresWidth);
+ }
+}
+
+//==============================================================================
+/**
+ * OnCheckMaintainRatio: The aspect ratio checkbox has changed.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnCheckMaintainRatio()
+{
+ this->setModified(TRUE);
+
+ long thePresWidth, thePresHeight;
+
+ // Get the width and height
+ thePresWidth = m_ui->m_ClientSizeWidth->value();
+ thePresHeight = m_ui->m_ClientSizeHeight->value();
+
+ // Save the Aspect Ratio
+ m_AspectRatio = (double)thePresWidth / (double)thePresHeight;
+}
+
+//==============================================================================
+/**
+ * OnChangeAuthor: EN_CHANGE handler for the IDC_AUTHOR field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeAuthor()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnChangeCompany: EN_CHANGE handler for the IDC_COMPANY field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeCompany()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnChangeSet1: EN_CHANGE handler for the IDC_SET1 field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeSet1()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnChangeSet2: EN_CHANGE handler for the IDC_SET2 field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeSet2()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnChangeSet3: EN_CHANGE handler for the IDC_SET3 field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeSet3()
+{
+ this->setModified(TRUE);
+}
+
+//==============================================================================
+/**
+ * OnChangeSet5: EN_CHANGE handler for the IDC_SET5 field.
+ *
+ * @param None
+ */
+//==============================================================================
+void CStudioProjectSettingsPage::OnChangeSet5()
+{
+ this->setModified(TRUE);
+}
diff --git a/src/Authoring/Studio/UI/StudioProjectSettingsPage.h b/src/Authoring/Studio/UI/StudioProjectSettingsPage.h
new file mode 100644
index 00000000..fd66c77a
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioProjectSettingsPage.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2002 NVIDIA Corporation.
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef STUDIOPROJECTSETTINGSPAGE_H
+#define STUDIOPROJECTSETTINGSPAGE_H
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+//==============================================================================
+// Includes
+//==============================================================================
+
+#include "StudioPreferencesPropSheet.h"
+
+#ifdef _USENEWCOLORPICKER_
+#include "StudioColorPicker.h"
+#endif
+
+//==============================================================================
+// Forwards
+//==============================================================================
+class CStudioApp;
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+ class StudioProjectSettingsPage;
+}
+QT_END_NAMESPACE
+
+//==============================================================================
+// Base class for the settings for different modes
+//==============================================================================
+class CStudioProjectSettingsPage : public CStudioPreferencesPropPage
+{
+ Q_OBJECT
+ // Construction
+public:
+ explicit CStudioProjectSettingsPage(QWidget *parent = nullptr);
+ ~CStudioProjectSettingsPage();
+
+ // Overrides
+ // ClassWizard generate virtual function overrides
+public:
+ bool onApply() override;
+ void onOK() override;
+
+ // Implementation
+protected:
+ double m_AspectRatio; ///< Stores the presentation width divided by the presentation height
+ QFont m_Font; ///< Font for text
+ QFont m_BoldFont; ///< Bold font for drawing the group boxes
+
+ void LoadSettings();
+ void SaveSettings();
+
+protected:
+ // Generated message map functions
+ virtual void OnInitDialog();
+ void OnChangeEditPresWidth();
+ void OnChangeEditPresHeight();
+ void OnCheckMaintainRatio();
+ void OnChangeAuthor();
+ void OnChangeCompany();
+ void OnSettingsModified();
+ void OnSelChangePreviewApp();
+ void OnCustomPreviewMore();
+ void OnChangeSet1();
+ void OnChangeSet2();
+ void OnChangeSet3();
+ void OnChangeSet5();
+
+ QScopedPointer<QT_PREPEND_NAMESPACE(Ui::StudioProjectSettingsPage)> m_ui;
+};
+
+#endif
diff --git a/src/Authoring/Studio/UI/StudioProjectSettingsPage.ui b/src/Authoring/Studio/UI/StudioProjectSettingsPage.ui
new file mode 100644
index 00000000..07a4bf65
--- /dev/null
+++ b/src/Authoring/Studio/UI/StudioProjectSettingsPage.ui
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StudioProjectSettingsPage</class>
+ <widget class="QWidget" name="StudioProjectSettingsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>259</width>
+ <height>269</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Presentation</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Width x Height</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_ClientSizeWidth</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="m_ClientSizeWidth">
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="m_ClientSizeHeight">
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QCheckBox" name="m_checkConstrainProportions">
+ <property name="text">
+ <string>Constrain Proportions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QCheckBox" name="m_checkPortraitFormat">
+ <property name="text">
+ <string>Portrait Format</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Project Info</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Author</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_Author</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="m_Author"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Company</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_Company</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="m_Company"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>m_ClientSizeWidth</tabstop>
+ <tabstop>m_ClientSizeHeight</tabstop>
+ <tabstop>m_checkConstrainProportions</tabstop>
+ <tabstop>m_checkPortraitFormat</tabstop>
+ <tabstop>m_Author</tabstop>
+ <tabstop>m_Company</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>