Merge pull request #1306 from yuriy0/FullScreenGamePreview
Full screen game preview for Atom viewport
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -113,6 +113,8 @@ public:
|
||||
//! Switch 2D viewports.
|
||||
void Cycle2DViewport();
|
||||
|
||||
using AzQtComponents::ToolBarArea::SetMainWidget;
|
||||
|
||||
public slots:
|
||||
void ResetLayout();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user