From 73d5617af354fe8dd18ea044c374645082041f9b Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Mon, 14 Jun 2021 10:02:49 -0400 Subject: [PATCH 1/6] Full screen game preview for Atom viewport --- Code/Sandbox/Editor/CryEdit.cpp | 5 + Code/Sandbox/Editor/EditorViewportWidget.cpp | 144 +++++++++++++++++++ Code/Sandbox/Editor/EditorViewportWidget.h | 5 + Code/Sandbox/Editor/MainWindow.cpp | 16 ++- Code/Sandbox/Editor/Resource.h | 1 + Code/Sandbox/Editor/Settings.cpp | 6 + Code/Sandbox/Editor/ToolbarManager.cpp | 1 + 7 files changed, 174 insertions(+), 4 deletions(-) diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index 955a299172..815f986e1a 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -376,6 +376,11 @@ void CCryEditApp::RegisterActionHandlers() ON_COMMAND(ID_EDIT_FETCH, OnEditFetch) ON_COMMAND(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, OnFileExportToGameNoSurfaceTexture) ON_COMMAND(ID_VIEW_SWITCHTOGAME, OnViewSwitchToGame) + MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_VIEW_SWITCHTOGAME_FULLSCREEN, [this]() { + auto fs = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once"); + fs->Set(1); + OnViewSwitchToGame(); + }); ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject) ON_COMMAND(ID_RENAME_OBJ, OnRenameObj) ON_COMMAND(ID_EDITMODE_MOVE, OnEditmodeMove) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index 5a444f0521..10a680c00c 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -82,6 +82,8 @@ #include "AnimationContext.h" #include "Objects/SelectionGroup.h" #include "Core/QtEditorApplication.h" +#include "MainWindow.h" +#include "LayoutWnd.h" // ComponentEntityEditorPlugin #include @@ -694,6 +696,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) } } SetCurrentCursor(STD_CURSOR_GAME); + + if (ShouldPreviewFullscreen()) + { + StartFullscreenPreview(); + } } if (m_renderViewport) @@ -712,6 +719,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) m_bInOrbitMode = false; m_bInZoomMode = false; + if (m_inFullscreenPreview) + { + StopFullscreenPreview(); + } + RestoreViewportAfterGameMode(); } @@ -1368,11 +1380,30 @@ void EditorViewportWidget::SetViewportId(int id) { CViewport::SetViewportId(id); + // First delete any existing layout + // This also deletes any existing render viewport widget (since it will be added to the layout + if (QLayout* l = layout()) + { + QLayoutItem* item; + while ((item = l->takeAt(0)) != 0) + { + if (QWidget* w = item->widget()) + { + delete w; + } + l->removeItem(item); + delete item; + } + delete l; + } + // Now that we have an ID, we can initialize our viewport. m_renderViewport = new AtomToolsFramework::RenderViewportWidget(this, false); if (!m_renderViewport->InitializeViewportContext(id)) { AZ_Warning("EditorViewportWidget", false, "Failed to initialize RenderViewportWidget's ViewportContext"); + delete m_renderViewport; + m_renderViewport = nullptr; return; } auto viewportContext = m_renderViewport->GetViewportContext(); @@ -3027,4 +3058,117 @@ float EditorViewportSettings::AngleStep() const return SandboxEditor::AngleSnappingSize(); } +bool EditorViewportWidget::ShouldPreviewFullscreen() +{ + CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout(); + if (!layout) + { + AZ_Assert(false, "CRenderViewport: No View Manager layout"); + return false; + } + + // Doesn't work with split layout (TODO: figure out why and make it work) + if (layout->GetLayout() != EViewLayout::ET_Layout0) { return false; } + + // Not supported in VR + if (gSettings.bEnableGameModeVR) { return false; } + + // If level not loaded, don't preview in fullscreen (preview shouldn't work at all without a level, but it does) + if (auto ge = GetIEditor()->GetGameEngine()) + { + if (!ge->IsLevelLoaded()) { return false; } + } + + // Check 'ed_previewGameInFullscreen_once' and 'ed_previewGameInFullscreen' cvars + if (gEnv->pConsole) + { + if (auto v = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once")) + { + if (v->GetIVal() != 0) + { + v->Set(0); + return true; + } + } + + { + auto v = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen"); + return v && v->GetIVal() != 0; // if it doesn't exist, assume its value is 0 + } + + return true; + } + else + { + return false; + } +} + +void EditorViewportWidget::StartFullscreenPreview() +{ + AZ_Assert(!m_inFullscreenPreview, AZ_FUNCTION_SIGNATURE " - called when already in full screen preview"); + m_inFullscreenPreview = true; + + QScreen* screen = QGuiApplication::primaryScreen(); + QRect screenGeometry = screen->geometry(); + + // Unparent this and show it, which turns it into a free floating window + // Also set style to frameless and disable resizing by user + setParent(nullptr); + setWindowFlag(Qt::FramelessWindowHint, true); + setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, true); + setFixedSize(screenGeometry.size()); + move(QPoint(screenGeometry.x(), screenGeometry.y())); + showMaximized(); + + // Hide the main window + MainWindow::instance()->hide(); +} + +void EditorViewportWidget::StopFullscreenPreview() +{ + AZ_Assert(m_inFullscreenPreview, AZ_FUNCTION_SIGNATURE " - called when not in full screen preview"); + m_inFullscreenPreview = false; + + // Unset frameless window flags + setWindowFlag(Qt::FramelessWindowHint, false); + setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); + + // Unset fixed size (note that 50x50 is the minimum set in the constructor) + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + setMinimumSize(50, 50); + + // Attach this viewport to the primary view pane (whose index is 0). + if (CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout()) + { + if (CLayoutViewPane* viewPane = layout->GetViewPaneByIndex(0)) + { + // Force-reattach this viewport to its view pane by first detaching + viewPane->DetachViewport(); + viewPane->AttachViewport(this); + + // Set the main widget of the layout, which causes this widgets size to be bound to the layout + // and the viewport title bar to be displayed + layout->SetMainWidget(viewPane); + } + else + { + AZ_Assert(false, "CRenderViewport: No view pane with ID 0 (primary view pane)"); + } + } + else + { + AZ_Assert(false, "CRenderViewport: No View Manager layout"); + } + + // Set this as the selected viewport + GetIEditor()->GetViewManager()->SelectViewport(this); + + // Show this widget (setting flags may hide it) + showNormal(); + + // Show the main window + MainWindow::instance()->show(); +} + #include diff --git a/Code/Sandbox/Editor/EditorViewportWidget.h b/Code/Sandbox/Editor/EditorViewportWidget.h index 6b2db65847..53c96011b1 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.h +++ b/Code/Sandbox/Editor/EditorViewportWidget.h @@ -385,6 +385,11 @@ protected: }; void ResetToViewSourceType(const ViewSourceType& viewSourType); + bool ShouldPreviewFullscreen(); + void StartFullscreenPreview(); + void StopFullscreenPreview(); + + bool m_inFullscreenPreview = false; bool m_bRenderContextCreated = false; bool m_bInRotateMode = false; bool m_bInMoveMode = false; diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index ddc8ff5058..4b0b0e104a 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -949,6 +949,12 @@ void MainWindow::InitActions() .SetApplyHoverEffect() .SetCheckable(true) .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdatePlayGame); + am->AddAction(ID_VIEW_SWITCHTOGAME_FULLSCREEN, tr("Play &Game (Maximized)")) + .SetShortcut(tr("Ctrl+Shift+G")) + .SetStatusTip(tr("Activate the game input mode (maximized)")) + .SetIcon(Style::icon("Play")) + .SetApplyHoverEffect() + .SetCheckable(true); am->AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, tr("Play Controls")) .SetText(tr("Play Controls")); am->AddAction(ID_SWITCH_PHYSICS, tr("Simulate")) @@ -1266,10 +1272,12 @@ void MainWindow::OnGameModeChanged(bool inGameMode) { menuBar()->setDisabled(inGameMode); m_toolbarManager->SetEnabled(!inGameMode); - QAction* action = m_actionManager->GetAction(ID_VIEW_SWITCHTOGAME); - action->blockSignals(true); // avoid a loop - action->setChecked(inGameMode); - action->blockSignals(false); + + // avoid a loop + AZStd::vector actions = { m_actionManager->GetAction(ID_VIEW_SWITCHTOGAME), m_actionManager->GetAction(ID_VIEW_SWITCHTOGAME_FULLSCREEN) }; + for (auto action : actions) action->blockSignals(true); + for (auto action : actions) action->setChecked(inGameMode); + for (auto action : actions) action->blockSignals(false); } void MainWindow::OnEditorNotifyEvent(EEditorNotifyEvent ev) diff --git a/Code/Sandbox/Editor/Resource.h b/Code/Sandbox/Editor/Resource.h index bd6ae94184..8ef6c0b906 100644 --- a/Code/Sandbox/Editor/Resource.h +++ b/Code/Sandbox/Editor/Resource.h @@ -111,6 +111,7 @@ #define ID_EDIT_FETCH 33465 #define ID_FILE_EXPORTTOGAMENOSURFACETEXTURE 33473 #define ID_VIEW_SWITCHTOGAME 33477 +#define ID_VIEW_SWITCHTOGAME_FULLSCREEN 33478 #define ID_EDIT_DELETE 33480 #define ID_MOVE_OBJECT 33481 #define ID_RENAME_OBJ 33483 diff --git a/Code/Sandbox/Editor/Settings.cpp b/Code/Sandbox/Editor/Settings.cpp index 15d3e793a5..66271a9967 100644 --- a/Code/Sandbox/Editor/Settings.cpp +++ b/Code/Sandbox/Editor/Settings.cpp @@ -947,6 +947,12 @@ void SEditorSettings::PostInitApply() REGISTER_CVAR2_CB("ed_keepEditorActive", &keepEditorActive, 0, VF_NULL, "Keep the editor active, even if no focus is set", KeepEditorActiveChanged); REGISTER_CVAR2("g_TemporaryLevelName", &g_TemporaryLevelName, "temp_level", VF_NULL, "Temporary level named used for experimental levels."); + REGISTER_INT("ed_previewGameInFullscreen", 0, VF_DEV_ONLY, "Preview the game (Ctrl+G, \"Play Game\", etc.) in fullscreen. 0 = no, 1 = yes"); + gEnv->pConsole->GetCVar("ed_previewGameInFullscreen")->SetLimits(0, 1); + + REGISTER_INT("ed_previewGameInFullscreen_once", 0, VF_DEV_ONLY | VF_INVISIBLE, "Preview the game (Ctrl+G, \"Play Game\", etc.) in fullscreen once. 0 = no, 1 = yes"); + gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once")->SetLimits(0, 1); + CCryEditApp::instance()->KeepEditorActive(keepEditorActive > 0); } diff --git a/Code/Sandbox/Editor/ToolbarManager.cpp b/Code/Sandbox/Editor/ToolbarManager.cpp index 137057a4fa..0c68797b6a 100644 --- a/Code/Sandbox/Editor/ToolbarManager.cpp +++ b/Code/Sandbox/Editor/ToolbarManager.cpp @@ -603,6 +603,7 @@ AmazonToolbar ToolbarManager::GetPlayConsoleToolbar() const t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_VIEW_SWITCHTOGAME, TOOLBARS_WITH_PLAY_GAME); + t.AddAction(ID_VIEW_SWITCHTOGAME_FULLSCREEN, TOOLBARS_WITH_PLAY_GAME); t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_SWITCH_PHYSICS, TOOLBARS_WITH_PLAY_GAME); return t; From 074c3107cd08560fcae41c8e308e748335dbddc6 Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Mon, 14 Jun 2021 11:54:11 -0400 Subject: [PATCH 2/6] Expose protected method required by full screen preview feature --- Code/Sandbox/Editor/LayoutWnd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Code/Sandbox/Editor/LayoutWnd.h b/Code/Sandbox/Editor/LayoutWnd.h index 2af56f907c..66c9a9e889 100644 --- a/Code/Sandbox/Editor/LayoutWnd.h +++ b/Code/Sandbox/Editor/LayoutWnd.h @@ -113,6 +113,8 @@ public: //! Switch 2D viewports. void Cycle2DViewport(); + using AzQtComponents::ToolBarArea::SetMainWidget; + public slots: void ResetLayout(); From 37f70fb47cd9f5badb17022955473916cbe66160 Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Mon, 14 Jun 2021 12:08:43 -0400 Subject: [PATCH 3/6] Address some PR feedback. - Better variable names - Close a parenthesis in a comment - Check equality against nullptr instead of 0 - Add comment to document method of clearing a QLayout - Format some things - Const correctness - Remove a TODO in a comment - Attempt at removing concatenation of string literal AZ_FUNCTION_SIGNATURE, which might not be a literal on every compiler/platform --- Code/Sandbox/Editor/EditorViewportWidget.cpp | 44 ++++++++++++-------- Code/Sandbox/Editor/EditorViewportWidget.h | 2 +- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index 10a680c00c..ba181aa99b 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -1381,20 +1381,21 @@ void EditorViewportWidget::SetViewportId(int id) CViewport::SetViewportId(id); // First delete any existing layout - // This also deletes any existing render viewport widget (since it will be added to the layout - if (QLayout* l = layout()) + // This also deletes any existing render viewport widget (since it will be added to the layout) + // Below is the typical method of clearing a QLayout, see e.g. https://doc.qt.io/qt-5/qlayout.html#takeAt + if (QLayout* thisLayout = layout()) { QLayoutItem* item; - while ((item = l->takeAt(0)) != 0) + while ((item = thisLayout->takeAt(0)) != nullptr) { - if (QWidget* w = item->widget()) + if (QWidget* widget = item->widget()) { - delete w; + delete widget; } - l->removeItem(item); + thisLayout->removeItem(item); delete item; } - delete l; + delete thisLayout; } // Now that we have an ID, we can initialize our viewport. @@ -3058,7 +3059,7 @@ float EditorViewportSettings::AngleStep() const return SandboxEditor::AngleSnappingSize(); } -bool EditorViewportWidget::ShouldPreviewFullscreen() +bool EditorViewportWidget::ShouldPreviewFullscreen() const { CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout(); if (!layout) @@ -3067,16 +3068,25 @@ bool EditorViewportWidget::ShouldPreviewFullscreen() return false; } - // Doesn't work with split layout (TODO: figure out why and make it work) - if (layout->GetLayout() != EViewLayout::ET_Layout0) { return false; } + // Doesn't work with split layout + if (layout->GetLayout() != EViewLayout::ET_Layout0) + { + return false; + } // Not supported in VR - if (gSettings.bEnableGameModeVR) { return false; } + if (gSettings.bEnableGameModeVR) + { + return false; + } // If level not loaded, don't preview in fullscreen (preview shouldn't work at all without a level, but it does) if (auto ge = GetIEditor()->GetGameEngine()) { - if (!ge->IsLevelLoaded()) { return false; } + if (!ge->IsLevelLoaded()) + { + return false; + } } // Check 'ed_previewGameInFullscreen_once' and 'ed_previewGameInFullscreen' cvars @@ -3106,11 +3116,11 @@ bool EditorViewportWidget::ShouldPreviewFullscreen() void EditorViewportWidget::StartFullscreenPreview() { - AZ_Assert(!m_inFullscreenPreview, AZ_FUNCTION_SIGNATURE " - called when already in full screen preview"); + AZ_Assert(!m_inFullscreenPreview, "EditorViewportWidget::StartFullscreenPreview called when already in full screen preview"); m_inFullscreenPreview = true; - QScreen* screen = QGuiApplication::primaryScreen(); - QRect screenGeometry = screen->geometry(); + const QScreen* screen = QGuiApplication::primaryScreen(); + const QRect screenGeometry = screen->geometry(); // Unparent this and show it, which turns it into a free floating window // Also set style to frameless and disable resizing by user @@ -3121,13 +3131,13 @@ void EditorViewportWidget::StartFullscreenPreview() move(QPoint(screenGeometry.x(), screenGeometry.y())); showMaximized(); - // Hide the main window + // This must be done after unparenting this widget above MainWindow::instance()->hide(); } void EditorViewportWidget::StopFullscreenPreview() { - AZ_Assert(m_inFullscreenPreview, AZ_FUNCTION_SIGNATURE " - called when not in full screen preview"); + AZ_Assert(m_inFullscreenPreview, "EditorViewportWidget::StartFullscreenPreview called when not in full screen preview"); m_inFullscreenPreview = false; // Unset frameless window flags diff --git a/Code/Sandbox/Editor/EditorViewportWidget.h b/Code/Sandbox/Editor/EditorViewportWidget.h index 53c96011b1..511a7910c6 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.h +++ b/Code/Sandbox/Editor/EditorViewportWidget.h @@ -385,7 +385,7 @@ protected: }; void ResetToViewSourceType(const ViewSourceType& viewSourType); - bool ShouldPreviewFullscreen(); + bool ShouldPreviewFullscreen() const; void StartFullscreenPreview(); void StopFullscreenPreview(); From 5becf25a79d194286169d5f83d17d2d411731f32 Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Mon, 14 Jun 2021 12:14:58 -0400 Subject: [PATCH 4/6] Address some PR feedback. - Better comment explaining signal blocking - Clang format --- Code/Sandbox/Editor/MainWindow.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index 4b0b0e104a..1ad97f31de 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -1273,11 +1273,24 @@ void MainWindow::OnGameModeChanged(bool inGameMode) menuBar()->setDisabled(inGameMode); m_toolbarManager->SetEnabled(!inGameMode); - // avoid a loop + // block signals on the switch to game actions before setting the checked state, as + // setting the checked state triggers the action, which will re-enter this function + // and result in an infinite loop AZStd::vector actions = { m_actionManager->GetAction(ID_VIEW_SWITCHTOGAME), m_actionManager->GetAction(ID_VIEW_SWITCHTOGAME_FULLSCREEN) }; - for (auto action : actions) action->blockSignals(true); - for (auto action : actions) action->setChecked(inGameMode); - for (auto action : actions) action->blockSignals(false); + for (auto action : actions) + { + action->blockSignals(true); + } + + for (auto action : actions) + { + action->setChecked(inGameMode); + } + + for (auto action : actions) + { + action->blockSignals(false); + } } void MainWindow::OnEditorNotifyEvent(EEditorNotifyEvent ev) From 84492dee48b1c0cb3a99a7ab5eef586cc81373b5 Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Mon, 14 Jun 2021 16:19:18 -0400 Subject: [PATCH 5/6] Address some PR feedback - Use AZ::IConsole instead of deprecated Cry IConsole. - Create fullscreen preview widget on the same screen where the main window is found, instead of on the 'primary' screen - Remove "ed_previewGameInFullscreen", which had the effect of always doing a full screen preview. If this functionality is desired, it should be re-added as a registry key instead of a cvar --- Code/Sandbox/Editor/CryEdit.cpp | 6 +++-- Code/Sandbox/Editor/EditorViewportWidget.cpp | 25 +++++++------------- Code/Sandbox/Editor/Settings.cpp | 9 +++---- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index 815f986e1a..536821ca6c 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -53,6 +53,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include // AzFramework #include @@ -356,6 +357,8 @@ CCryEditDoc* CCryDocManager::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToM for (int i = idStart; i <= idEnd; ++i) \ ON_COMMAND(i, method); +AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once); + void CCryEditApp::RegisterActionHandlers() { ON_COMMAND(ID_APP_ABOUT, OnAppAbout) @@ -377,8 +380,7 @@ void CCryEditApp::RegisterActionHandlers() ON_COMMAND(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, OnFileExportToGameNoSurfaceTexture) ON_COMMAND(ID_VIEW_SWITCHTOGAME, OnViewSwitchToGame) MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_VIEW_SWITCHTOGAME_FULLSCREEN, [this]() { - auto fs = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once"); - fs->Set(1); + ed_previewGameInFullscreen_once = true; OnViewSwitchToGame(); }); ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index ba181aa99b..b02aafbe32 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include // AzFramework @@ -3059,6 +3060,8 @@ float EditorViewportSettings::AngleStep() const return SandboxEditor::AngleSnappingSize(); } +AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once); + bool EditorViewportWidget::ShouldPreviewFullscreen() const { CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout(); @@ -3089,23 +3092,10 @@ bool EditorViewportWidget::ShouldPreviewFullscreen() const } } - // Check 'ed_previewGameInFullscreen_once' and 'ed_previewGameInFullscreen' cvars - if (gEnv->pConsole) + // Check 'ed_previewGameInFullscreen_once' + if (ed_previewGameInFullscreen_once) { - if (auto v = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once")) - { - if (v->GetIVal() != 0) - { - v->Set(0); - return true; - } - } - - { - auto v = gEnv->pConsole->GetCVar("ed_previewGameInFullscreen"); - return v && v->GetIVal() != 0; // if it doesn't exist, assume its value is 0 - } - + ed_previewGameInFullscreen_once = true; return true; } else @@ -3119,7 +3109,8 @@ void EditorViewportWidget::StartFullscreenPreview() AZ_Assert(!m_inFullscreenPreview, "EditorViewportWidget::StartFullscreenPreview called when already in full screen preview"); m_inFullscreenPreview = true; - const QScreen* screen = QGuiApplication::primaryScreen(); + // Pick the screen on which the main window lies to use as the screen for the full screen preview + const QScreen* screen = MainWindow::instance()->screen(); const QRect screenGeometry = screen->geometry(); // Unparent this and show it, which turns it into a free floating window diff --git a/Code/Sandbox/Editor/Settings.cpp b/Code/Sandbox/Editor/Settings.cpp index 66271a9967..f805e2e84b 100644 --- a/Code/Sandbox/Editor/Settings.cpp +++ b/Code/Sandbox/Editor/Settings.cpp @@ -26,6 +26,7 @@ #include #include #include +#include // AzFramework #include @@ -926,6 +927,8 @@ void SEditorSettings::Load() } ////////////////////////////////////////////////////////////////////////// +AZ_CVAR(bool, ed_previewGameInFullscreen_once, false, nullptr, AZ::ConsoleFunctorFlags::IsInvisible, "Preview the game (Ctrl+G, \"Play Game\", etc.) in fullscreen once"); + void SEditorSettings::PostInitApply() { if (!gEnv || !gEnv->pConsole) @@ -947,12 +950,6 @@ void SEditorSettings::PostInitApply() REGISTER_CVAR2_CB("ed_keepEditorActive", &keepEditorActive, 0, VF_NULL, "Keep the editor active, even if no focus is set", KeepEditorActiveChanged); REGISTER_CVAR2("g_TemporaryLevelName", &g_TemporaryLevelName, "temp_level", VF_NULL, "Temporary level named used for experimental levels."); - REGISTER_INT("ed_previewGameInFullscreen", 0, VF_DEV_ONLY, "Preview the game (Ctrl+G, \"Play Game\", etc.) in fullscreen. 0 = no, 1 = yes"); - gEnv->pConsole->GetCVar("ed_previewGameInFullscreen")->SetLimits(0, 1); - - REGISTER_INT("ed_previewGameInFullscreen_once", 0, VF_DEV_ONLY | VF_INVISIBLE, "Preview the game (Ctrl+G, \"Play Game\", etc.) in fullscreen once. 0 = no, 1 = yes"); - gEnv->pConsole->GetCVar("ed_previewGameInFullscreen_once")->SetLimits(0, 1); - CCryEditApp::instance()->KeepEditorActive(keepEditorActive > 0); } From 7d1a12a14f667cd619dd0bc5f1df285b6aef9ce3 Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Tue, 15 Jun 2021 18:33:44 -0400 Subject: [PATCH 6/6] Bug fix: crash after full screen preview due to dangling pointer --- Code/Sandbox/Editor/EditorViewportWidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index b02aafbe32..9ff38a34c1 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -1381,6 +1381,10 @@ void EditorViewportWidget::SetViewportId(int id) { CViewport::SetViewportId(id); + // Clear the cached debugdisplay pointer. we're about to delete that render viewport, and deleting the render + // viewport invalidates the debugdisplay. + m_debugDisplay = nullptr; + // First delete any existing layout // This also deletes any existing render viewport widget (since it will be added to the layout) // Below is the typical method of clearing a QLayout, see e.g. https://doc.qt.io/qt-5/qlayout.html#takeAt