Merge pull request #1306 from yuriy0/FullScreenGamePreview

Full screen game preview for Atom viewport
This commit is contained in:
Nicholas Van Sickle
2021-06-16 08:40:29 -07:00
committed by GitHub
8 changed files with 193 additions and 4 deletions
+7
View File
@@ -53,6 +53,7 @@ AZ_POP_DISABLE_WARNING
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Console/IConsole.h>
// AzFramework
#include <AzFramework/Components/CameraBus.h>
@@ -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)
@@ -376,6 +379,10 @@ 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]() {
ed_previewGameInFullscreen_once = true;
OnViewSwitchToGame();
});
ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject)
ON_COMMAND(ID_RENAME_OBJ, OnRenameObj)
ON_COMMAND(ID_EDITMODE_MOVE, OnEditmodeMove)
@@ -29,6 +29,7 @@
#include <AzCore/Component/EntityId.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Math/VectorConversions.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Console/IConsole.h>
// AzFramework
@@ -82,6 +83,8 @@
#include "AnimationContext.h"
#include "Objects/SelectionGroup.h"
#include "Core/QtEditorApplication.h"
#include "MainWindow.h"
#include "LayoutWnd.h"
// ComponentEntityEditorPlugin
#include <Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h>
@@ -704,6 +707,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
}
}
SetCurrentCursor(STD_CURSOR_GAME);
if (ShouldPreviewFullscreen())
{
StartFullscreenPreview();
}
}
if (m_renderViewport)
@@ -722,6 +730,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
m_bInOrbitMode = false;
m_bInZoomMode = false;
if (m_inFullscreenPreview)
{
StopFullscreenPreview();
}
RestoreViewportAfterGameMode();
}
@@ -1378,11 +1391,35 @@ 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
if (QLayout* thisLayout = layout())
{
QLayoutItem* item;
while ((item = thisLayout->takeAt(0)) != nullptr)
{
if (QWidget* widget = item->widget())
{
delete widget;
}
thisLayout->removeItem(item);
delete item;
}
delete thisLayout;
}
// 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();
@@ -3037,4 +3074,116 @@ float EditorViewportSettings::AngleStep() const
return SandboxEditor::AngleSnappingSize();
}
AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once);
bool EditorViewportWidget::ShouldPreviewFullscreen() const
{
CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout();
if (!layout)
{
AZ_Assert(false, "CRenderViewport: No View Manager layout");
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 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'
if (ed_previewGameInFullscreen_once)
{
ed_previewGameInFullscreen_once = true;
return true;
}
else
{
return false;
}
}
void EditorViewportWidget::StartFullscreenPreview()
{
AZ_Assert(!m_inFullscreenPreview, "EditorViewportWidget::StartFullscreenPreview called when already in full screen preview");
m_inFullscreenPreview = true;
// 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
// 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();
// This must be done after unparenting this widget above
MainWindow::instance()->hide();
}
void EditorViewportWidget::StopFullscreenPreview()
{
AZ_Assert(m_inFullscreenPreview, "EditorViewportWidget::StartFullscreenPreview 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 <moc_EditorViewportWidget.cpp>
@@ -385,6 +385,11 @@ protected:
};
void ResetToViewSourceType(const ViewSourceType& viewSourType);
bool ShouldPreviewFullscreen() const;
void StartFullscreenPreview();
void StopFullscreenPreview();
bool m_inFullscreenPreview = false;
bool m_bRenderContextCreated = false;
bool m_bInRotateMode = false;
bool m_bInMoveMode = false;
+2
View File
@@ -113,6 +113,8 @@ public:
//! Switch 2D viewports.
void Cycle2DViewport();
using AzQtComponents::ToolBarArea::SetMainWidget;
public slots:
void ResetLayout();
+25 -4
View File
@@ -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,25 @@ 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);
// 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<QAction*> 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)
+1
View File
@@ -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
+3
View File
@@ -26,6 +26,7 @@
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Console/IConsole.h>
// AzFramework
#include <AzFramework/API/ApplicationAPI.h>
@@ -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)
+1
View File
@@ -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;