ソースを参照

Rearchitecture Project Manager Screens Workflow and Create Project Settings Ctrl

* Renamed UX screen files and classes to include screen in the name

* Changed screens to emit a screen change request a controller can connect to

* Made ScreensCtrl that owns and manages screens and their changing and history

* Made Project Settings Control managing back and next buttons

* Add Project Setting Model and moved New Project Settings Ui into Screen file

* Goto previous screen always works

* Removed unnecessary QObject namespace from connect calls

* Merged ProjectSettingsModel into ProjectInfo
AMZN-nggieber 4 年 前
コミット
7ecd1b1761
34 ファイル変更679 行追加453 行削除
  1. 6 11
      Code/Tools/ProjectManager/Source/EngineSettingsScreen.cpp
  2. 4 6
      Code/Tools/ProjectManager/Source/EngineSettingsScreen.h
  3. 0 0
      Code/Tools/ProjectManager/Source/EngineSettingsScreen.ui
  4. 0 47
      Code/Tools/ProjectManager/Source/FirstTimeUse.cpp
  5. 44 0
      Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp
  6. 4 6
      Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h
  7. 0 0
      Code/Tools/ProjectManager/Source/FirstTimeUseScreen.ui
  8. 8 17
      Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp
  9. 5 7
      Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h
  10. 0 47
      Code/Tools/ProjectManager/Source/NewProjectSettings.cpp
  11. 0 97
      Code/Tools/ProjectManager/Source/NewProjectSettings.ui
  12. 82 0
      Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
  13. 30 0
      Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
  14. 5 1
      Code/Tools/ProjectManager/Source/ProjectInfo.cpp
  15. 11 3
      Code/Tools/ProjectManager/Source/ProjectInfo.h
  16. 17 54
      Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp
  17. 3 13
      Code/Tools/ProjectManager/Source/ProjectManagerWindow.h
  18. 1 5
      Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui
  19. 95 0
      Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp
  20. 14 12
      Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h
  21. 9 13
      Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp
  22. 4 6
      Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h
  23. 0 0
      Code/Tools/ProjectManager/Source/ProjectSettingsScreen.ui
  24. 0 57
      Code/Tools/ProjectManager/Source/ProjectsHome.cpp
  25. 51 0
      Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp
  26. 4 6
      Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h
  27. 0 0
      Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui
  28. 4 1
      Code/Tools/ProjectManager/Source/ScreenDefs.h
  29. 29 14
      Code/Tools/ProjectManager/Source/ScreenFactory.cpp
  30. 3 4
      Code/Tools/ProjectManager/Source/ScreenFactory.h
  31. 22 7
      Code/Tools/ProjectManager/Source/ScreenWidget.h
  32. 149 0
      Code/Tools/ProjectManager/Source/ScreensCtrl.cpp
  33. 53 0
      Code/Tools/ProjectManager/Source/ScreensCtrl.h
  34. 22 19
      Code/Tools/ProjectManager/project_manager_files.cmake

+ 6 - 11
Code/Tools/ProjectManager/Source/EngineSettings.cpp → Code/Tools/ProjectManager/Source/EngineSettingsScreen.cpp

@@ -10,26 +10,21 @@
  *
  */
 
-#include <EngineSettings.h>
+#include <EngineSettingsScreen.h>
 
-#include <Source/ui_EngineSettings.h>
+#include <Source/ui_EngineSettingsScreen.h>
 
 namespace O3DE::ProjectManager
 {
-    EngineSettings::EngineSettings(ProjectManagerWindow* window)
-        : ScreenWidget(window)
+    EngineSettingsScreen::EngineSettingsScreen(QWidget* parent)
+        : ScreenWidget(parent)
         , m_ui(new Ui::EngineSettingsClass())
     {
         m_ui->setupUi(this);
     }
 
-    EngineSettings::~EngineSettings()
+    ProjectManagerScreen EngineSettingsScreen::GetScreenEnum()
     {
+        return ProjectManagerScreen::EngineSettings;
     }
-
-    void EngineSettings::ConnectSlotsAndSignals()
-    {
-        // Do nothing for now
-    }
-
 } // namespace O3DE::ProjectManager

+ 4 - 6
Code/Tools/ProjectManager/Source/EngineSettings.h → Code/Tools/ProjectManager/Source/EngineSettingsScreen.h

@@ -22,15 +22,13 @@ namespace Ui
 
 namespace O3DE::ProjectManager
 {
-    class EngineSettings
+    class EngineSettingsScreen
         : public ScreenWidget
     {
     public:
-        explicit EngineSettings(ProjectManagerWindow* window);
-        ~EngineSettings();
-
-    protected:
-        void ConnectSlotsAndSignals() override;
+        explicit EngineSettingsScreen(QWidget* parent = nullptr);
+        ~EngineSettingsScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
 
     private:
         QScopedPointer<Ui::EngineSettingsClass> m_ui;

+ 0 - 0
Code/Tools/ProjectManager/Source/EngineSettings.ui → Code/Tools/ProjectManager/Source/EngineSettingsScreen.ui


+ 0 - 47
Code/Tools/ProjectManager/Source/FirstTimeUse.cpp

@@ -1,47 +0,0 @@
-/*
- * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
- * its licensors.
- *
- * For complete copyright and license terms please see the LICENSE at the root of this
- * distribution (the "License"). All use of this software is governed by the License,
- * or, if provided, by the license below or the license accompanying this file. Do not
- * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- */
-
-#include <FirstTimeUse.h>
-
-#include <Source/ui_FirstTimeUse.h>
-
-namespace O3DE::ProjectManager
-{
-    FirstTimeUse::FirstTimeUse(ProjectManagerWindow* window)
-        : ScreenWidget(window)
-        , m_ui(new Ui::FirstTimeUseClass())
-    {
-        m_ui->setupUi(this);
-
-        ConnectSlotsAndSignals();
-    }
-
-    FirstTimeUse::~FirstTimeUse()
-    {
-    }
-
-    void FirstTimeUse::ConnectSlotsAndSignals()
-    {
-        QObject::connect(m_ui->createProjectButton, &QPushButton::pressed, this, &FirstTimeUse::HandleNewProjectButton);
-        QObject::connect(m_ui->openProjectButton, &QPushButton::pressed, this, &FirstTimeUse::HandleOpenProjectButton);
-    }
-
-    void FirstTimeUse::HandleNewProjectButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::NewProjectSettings);
-    }
-    void FirstTimeUse::HandleOpenProjectButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::ProjectsHome);
-    }
-
-} // namespace O3DE::ProjectManager

+ 44 - 0
Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp

@@ -0,0 +1,44 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include <FirstTimeUseScreen.h>
+
+#include <Source/ui_FirstTimeUseScreen.h>
+
+namespace O3DE::ProjectManager
+{
+    FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent)
+        : ScreenWidget(parent)
+        , m_ui(new Ui::FirstTimeUseClass())
+    {
+        m_ui->setupUi(this);
+
+        connect(m_ui->createProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleNewProjectButton);
+        connect(m_ui->openProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleOpenProjectButton);
+    }
+
+    ProjectManagerScreen FirstTimeUseScreen::GetScreenEnum()
+    {
+        return ProjectManagerScreen::FirstTimeUse;
+    }
+
+    void FirstTimeUseScreen::HandleNewProjectButton()
+    {
+        emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore);
+        emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore);
+    }
+    void FirstTimeUseScreen::HandleOpenProjectButton()
+    {
+        emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome);
+    }
+
+} // namespace O3DE::ProjectManager

+ 4 - 6
Code/Tools/ProjectManager/Source/FirstTimeUse.h → Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h

@@ -22,15 +22,13 @@ namespace Ui
 
 namespace O3DE::ProjectManager
 {
-    class FirstTimeUse
+    class FirstTimeUseScreen
         : public ScreenWidget
     {
     public:
-        explicit FirstTimeUse(ProjectManagerWindow* window);
-        ~FirstTimeUse();
-
-    protected:
-        void ConnectSlotsAndSignals() override;
+        explicit FirstTimeUseScreen(QWidget* parent = nullptr);
+        ~FirstTimeUseScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
 
     protected slots:
         void HandleNewProjectButton();

+ 0 - 0
Code/Tools/ProjectManager/Source/FirstTimeUse.ui → Code/Tools/ProjectManager/Source/FirstTimeUseScreen.ui


+ 8 - 17
Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp → Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp

@@ -10,16 +10,15 @@
  *
  */
 
-#include <GemCatalog/GemCatalog.h>
-#include <QDialogButtonBox>
+#include <GemCatalog/GemCatalogScreen.h>
 #include <QVBoxLayout>
 #include <QHBoxLayout>
 #include <QPushButton>
 
 namespace O3DE::ProjectManager
 {
-    GemCatalog::GemCatalog(ProjectManagerWindow* window)
-        : ScreenWidget(window)
+    GemCatalogScreen::GemCatalogScreen(QWidget* parent)
+        : ScreenWidget(parent)
     {
         m_gemModel = new GemModel(this);
 
@@ -40,15 +39,6 @@ namespace O3DE::ProjectManager
         inspectorPlaceholderWidget->setFixedWidth(250);
         hLayout->addWidget(inspectorPlaceholderWidget);
 
-        // Temporary back and next buttons until they are centralized and shared.
-        QDialogButtonBox* backNextButtons = new QDialogButtonBox();
-        vLayout->addWidget(backNextButtons);
-
-        QPushButton* tempBackButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole);
-        QPushButton* tempNextButton = backNextButtons->addButton("Next", QDialogButtonBox::AcceptRole);
-        connect(tempBackButton, &QPushButton::pressed, this, &GemCatalog::HandleBackButton);
-        connect(tempNextButton, &QPushButton::pressed, this, &GemCatalog::HandleConfirmButton);
-
         // Start: Temporary gem test data
         {
             m_gemModel->AddGem(GemInfo("EMotion FX",
@@ -90,12 +80,13 @@ namespace O3DE::ProjectManager
         // End: Temporary gem test data
     }
 
-    void GemCatalog::HandleBackButton()
+    ProjectManagerScreen GemCatalogScreen::GetScreenEnum()
     {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::NewProjectSettings);
+        return ProjectManagerScreen::GemCatalog;
     }
-    void GemCatalog::HandleConfirmButton()
+
+    QString GemCatalogScreen::GetNextButtonText()
     {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::ProjectsHome);
+        return "Create Project";
     }
 } // namespace O3DE::ProjectManager

+ 5 - 7
Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.h → Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h

@@ -19,16 +19,14 @@
 
 namespace O3DE::ProjectManager
 {
-    class GemCatalog
+    class GemCatalogScreen
         : public ScreenWidget
     {
     public:
-        explicit GemCatalog(ProjectManagerWindow* window);
-        ~GemCatalog() = default;
-
-    protected slots:
-        void HandleBackButton();
-        void HandleConfirmButton();
+        explicit GemCatalogScreen(QWidget* parent = nullptr);
+        ~GemCatalogScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
+        QString GetNextButtonText() override;
 
     private:
         GemListView* m_gemListView = nullptr;

+ 0 - 47
Code/Tools/ProjectManager/Source/NewProjectSettings.cpp

@@ -1,47 +0,0 @@
-/*
- * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
- * its licensors.
- *
- * For complete copyright and license terms please see the LICENSE at the root of this
- * distribution (the "License"). All use of this software is governed by the License,
- * or, if provided, by the license below or the license accompanying this file. Do not
- * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- */
-
-#include <NewProjectSettings.h>
-
-#include <Source/ui_NewProjectSettings.h>
-
-namespace O3DE::ProjectManager
-{
-    NewProjectSettings::NewProjectSettings(ProjectManagerWindow* window)
-        : ScreenWidget(window)
-        , m_ui(new Ui::NewProjectSettingsClass())
-    {
-        m_ui->setupUi(this);
-
-        ConnectSlotsAndSignals();
-    }
-
-    NewProjectSettings::~NewProjectSettings()
-    {
-    }
-
-    void NewProjectSettings::ConnectSlotsAndSignals()
-    {
-        QObject::connect(m_ui->backButton, &QPushButton::pressed, this, &NewProjectSettings::HandleBackButton);
-        QObject::connect(m_ui->nextButton, &QPushButton::pressed, this, &NewProjectSettings::HandleNextButton);
-    }
-
-    void NewProjectSettings::HandleBackButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::FirstTimeUse);
-    }
-    void NewProjectSettings::HandleNextButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::GemCatalog);
-    }
-
-} // namespace O3DE::ProjectManager

+ 0 - 97
Code/Tools/ProjectManager/Source/NewProjectSettings.ui

@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>NewProjectSettingsClass</class>
- <widget class="QWidget" name="NewProjectSettingsClass">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>880</width>
-    <height>546</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
-   <item>
-    <widget class="QLabel" name="projectNameLabel">
-     <property name="text">
-      <string>Project Name</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLineEdit" name="projectNameLineEdit"/>
-   </item>
-   <item>
-    <widget class="QLabel" name="projectPathLabel">
-     <property name="text">
-      <string>Project Path</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLineEdit" name="projectPathLineEdit"/>
-   </item>
-   <item>
-    <widget class="QLabel" name="projectTemplateLabel">
-     <property name="text">
-      <string>Project Template</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QRadioButton" name="projectTemplateStandardRadioButton">
-       <property name="text">
-        <string>Standard (Recommened)</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QRadioButton" name="projectTemplateStandardEmptyButton">
-       <property name="text">
-        <string>Empty</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <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>
-     <item>
-      <widget class="QPushButton" name="backButton">
-       <property name="text">
-        <string>Back</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="nextButton">
-       <property name="text">
-        <string>Next</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>

+ 82 - 0
Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp

@@ -0,0 +1,82 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include <NewProjectSettingsScreen.h>
+
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QRadioButton>
+#include <QSpacerItem>
+
+namespace O3DE::ProjectManager
+{
+    NewProjectSettingsScreen::NewProjectSettingsScreen(QWidget* parent)
+        : ScreenWidget(parent)
+    {
+        QHBoxLayout* hLayout = new QHBoxLayout();
+        this->setLayout(hLayout);
+
+        QVBoxLayout* vLayout = new QVBoxLayout(this);
+
+        QLabel* projectNameLabel = new QLabel(this);
+        projectNameLabel->setText("Project Name");
+        vLayout->addWidget(projectNameLabel);
+
+        QLineEdit* projectNameLineEdit = new QLineEdit(this);
+        vLayout->addWidget(projectNameLineEdit);
+
+        QLabel* projectPathLabel = new QLabel(this);
+        projectPathLabel->setText("Project Location");
+        vLayout->addWidget(projectPathLabel);
+
+        QLineEdit* projectPathLineEdit = new QLineEdit(this);
+        vLayout->addWidget(projectPathLineEdit);
+
+        QLabel* projectTemplateLabel = new QLabel(this);
+        projectTemplateLabel->setText("Project Template");
+        vLayout->addWidget(projectTemplateLabel);
+
+        QHBoxLayout* templateLayout = new QHBoxLayout(this);
+        vLayout->addItem(templateLayout);
+
+        QRadioButton* projectTemplateStandardRadioButton = new QRadioButton(this);
+        projectTemplateStandardRadioButton->setText("Standard (Recommened)");
+        projectTemplateStandardRadioButton->setChecked(true);
+        templateLayout->addWidget(projectTemplateStandardRadioButton);
+
+        QRadioButton* projectTemplateEmptyRadioButton = new QRadioButton(this);
+        projectTemplateEmptyRadioButton->setText("Empty");
+        templateLayout->addWidget(projectTemplateEmptyRadioButton);
+
+        QSpacerItem* verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+        vLayout->addItem(verticalSpacer);
+
+        hLayout->addItem(vLayout);
+
+        QWidget* gemsListPlaceholder = new QWidget(this);
+        gemsListPlaceholder->setFixedWidth(250);
+        hLayout->addWidget(gemsListPlaceholder);
+    }
+
+    ProjectManagerScreen NewProjectSettingsScreen::GetScreenEnum()
+    {
+        return ProjectManagerScreen::NewProjectSettings;
+    }
+
+    QString NewProjectSettingsScreen::GetNextButtonText()
+    {
+        return "Create Project";
+    }
+
+} // namespace O3DE::ProjectManager

+ 30 - 0
Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h

@@ -0,0 +1,30 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+#pragma once
+
+#if !defined(Q_MOC_RUN)
+#include <ScreenWidget.h>
+#endif
+
+namespace O3DE::ProjectManager
+{
+    class NewProjectSettingsScreen
+        : public ScreenWidget
+    {
+    public:
+        explicit NewProjectSettingsScreen(QWidget* parent = nullptr);
+        ~NewProjectSettingsScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
+        QString GetNextButtonText() override;
+    };
+
+} // namespace O3DE::ProjectManager

+ 5 - 1
Code/Tools/ProjectManager/Source/ProjectInfo.cpp

@@ -14,11 +14,15 @@
 
 namespace O3DE::ProjectManager
 {
-    ProjectInfo::ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId)
+    ProjectInfo::ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId,
+        const QString& imagePath, const QString& backgroundImagePath, bool isNew)
         : m_path(path)
         , m_projectName(projectName)
         , m_productName(productName)
         , m_projectId(projectId)
+        , m_imagePath(imagePath)
+        , m_backgroundImagePath(backgroundImagePath)
+        , m_isNew(isNew)
     {
     }
 } // namespace O3DE::ProjectManager

+ 11 - 3
Code/Tools/ProjectManager/Source/ProjectInfo.h

@@ -23,14 +23,22 @@ namespace O3DE::ProjectManager
     {
     public:
         ProjectInfo() = default;
-        ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId);
+        ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId,
+            const QString& imagePath, const QString& backgroundImagePath, bool isNew);
 
-        // from o3de_manifest.json and o3de_projects.json
+        // From o3de_manifest.json and o3de_projects.json
         QString m_path;
 
-        // from project.json
+        // From project.json
         QString m_projectName;
         QString m_productName;
         AZ::Uuid m_projectId;
+
+        // Used on projects home screen
+        QString m_imagePath;
+        QString m_backgroundImagePath;
+
+        // Used in project creation
+        bool m_isNew = false; //! Is this a new project or existing
     };
 } // namespace O3DE::ProjectManager

+ 17 - 54
Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp

@@ -30,7 +30,11 @@ namespace O3DE::ProjectManager
 
         m_pythonBindings = AZStd::make_unique<PythonBindings>(engineRootPath);
 
-        ConnectSlotsAndSignals();
+        m_screensCtrl = new ScreensCtrl();
+        m_ui->verticalLayout->addWidget(m_screensCtrl);
+
+        connect(m_ui->projectsMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleProjectsMenu);
+        connect(m_ui->engineMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleEngineMenu);
 
         QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast<int>(engineRootPath.Native().size()));
         const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/ProjectManager/Resources");
@@ -39,9 +43,16 @@ namespace O3DE::ProjectManager
 
         AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("projectlauncherwindow:ProjectManagerWindow.qss"));
 
-        BuildScreens();
-
-        ChangeToScreen(ProjectManagerScreen::FirstTimeUse);
+        QVector<ProjectManagerScreen> screenEnums =
+        {
+            ProjectManagerScreen::FirstTimeUse,
+            ProjectManagerScreen::NewProjectSettingsCore,
+            ProjectManagerScreen::ProjectsHome,
+            ProjectManagerScreen::ProjectSettings,
+            ProjectManagerScreen::EngineSettings
+        };
+        m_screensCtrl->BuildScreens(screenEnums);
+        m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::FirstTimeUse, false);
     }
 
     ProjectManagerWindow::~ProjectManagerWindow()
@@ -49,61 +60,13 @@ namespace O3DE::ProjectManager
         m_pythonBindings.reset();
     }
 
-    void ProjectManagerWindow::BuildScreens()
-    {
-        // Basically just iterate over the ProjectManagerScreen enum creating each screen
-        // Could add some fancy to do this but there are few screens right now
-
-        ResetScreen(ProjectManagerScreen::FirstTimeUse);
-        ResetScreen(ProjectManagerScreen::NewProjectSettings);
-        ResetScreen(ProjectManagerScreen::GemCatalog);
-        ResetScreen(ProjectManagerScreen::ProjectsHome);
-        ResetScreen(ProjectManagerScreen::ProjectSettings);
-        ResetScreen(ProjectManagerScreen::EngineSettings);
-    }
-
-    QStackedWidget* ProjectManagerWindow::GetScreenStack()
-    {
-        return m_ui->stackedScreens;
-    }
-
-    void ProjectManagerWindow::ChangeToScreen(ProjectManagerScreen screen)
-    {
-        int index = aznumeric_cast<int, ProjectManagerScreen>(screen);
-        m_ui->stackedScreens->setCurrentIndex(index);
-    }
-
-    void ProjectManagerWindow::ResetScreen(ProjectManagerScreen screen)
-    {
-        int index = aznumeric_cast<int, ProjectManagerScreen>(screen);
-
-        // Fine the old screen if it exists and get rid of it so we can start fresh
-        QWidget* oldScreen = m_ui->stackedScreens->widget(index);
-
-        if (oldScreen)
-        {
-            m_ui->stackedScreens->removeWidget(oldScreen);
-            oldScreen->deleteLater();
-        }
-
-        // Add new screen
-        QWidget* newScreen = BuildScreen(this, screen);
-        m_ui->stackedScreens->insertWidget(index, newScreen);
-    }
-
-    void ProjectManagerWindow::ConnectSlotsAndSignals()
-    {
-        QObject::connect(m_ui->projectsMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleProjectsMenu);
-        QObject::connect(m_ui->engineMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleEngineMenu);
-    }
-
     void ProjectManagerWindow::HandleProjectsMenu()
     {
-        ChangeToScreen(ProjectManagerScreen::ProjectsHome);
+        m_screensCtrl->ChangeToScreen(ProjectManagerScreen::ProjectsHome);
     }
     void ProjectManagerWindow::HandleEngineMenu()
     {
-        ChangeToScreen(ProjectManagerScreen::EngineSettings);
+        m_screensCtrl->ChangeToScreen(ProjectManagerScreen::EngineSettings);
     }
 
 } // namespace O3DE::ProjectManager

+ 3 - 13
Code/Tools/ProjectManager/Source/ProjectManagerWindow.h

@@ -12,10 +12,9 @@
 #pragma once
 
 #if !defined(Q_MOC_RUN)
-#include <ScreenDefs.h>
-
 #include <QMainWindow>
-#include <QStackedWidget>
+
+#include <ScreensCtrl.h>
 
 #include <PythonBindings.h>
 #endif
@@ -36,22 +35,13 @@ namespace O3DE::ProjectManager
         explicit ProjectManagerWindow(QWidget* parent, const AZ::IO::PathView& engineRootPath);
         ~ProjectManagerWindow();
 
-        void BuildScreens();
-        QStackedWidget* GetScreenStack();
-
-    public slots:
-        void ChangeToScreen(ProjectManagerScreen screen);
-        void ResetScreen(ProjectManagerScreen screen);
-
-    protected:
-        void ConnectSlotsAndSignals();
-
     protected slots:
         void HandleProjectsMenu();
         void HandleEngineMenu();
 
     private:
         QScopedPointer<Ui::ProjectManagerWindowClass> m_ui;
+        ScreensCtrl* m_screensCtrl;
         AZStd::unique_ptr<PythonBindings> m_pythonBindings;
     };
 

+ 1 - 5
Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui

@@ -14,11 +14,7 @@
    <string>O3DE Project Manager</string>
   </property>
   <widget class="QWidget" name="centralWidget">
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <item>
-     <widget class="QStackedWidget" name="stackedScreens"/>
-    </item>
-   </layout>
+   <layout class="QVBoxLayout" name="verticalLayout"/>
   </widget>
   <widget class="QMenuBar" name="menuBar">
    <property name="geometry">

+ 95 - 0
Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp

@@ -0,0 +1,95 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include <ProjectSettingsCtrl.h>
+#include <ScreensCtrl.h>
+
+#include <QDialogButtonBox>
+#include <QVBoxLayout>
+#include <QPushButton>
+
+namespace O3DE::ProjectManager
+{
+    ProjectSettingsCtrl::ProjectSettingsCtrl(QWidget* parent)
+        : ScreenWidget(parent)
+    {
+        QVBoxLayout* vLayout = new QVBoxLayout();
+        setLayout(vLayout);
+
+        m_screensCtrl = new ScreensCtrl();
+        vLayout->addWidget(m_screensCtrl);
+
+        QDialogButtonBox* backNextButtons = new QDialogButtonBox();
+        vLayout->addWidget(backNextButtons);
+
+        m_backButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole);
+        m_nextButton = backNextButtons->addButton("Next", QDialogButtonBox::ApplyRole);
+
+        connect(m_backButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleBackButton);
+        connect(m_nextButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleNextButton);
+
+        m_screensOrder =
+        {
+            ProjectManagerScreen::NewProjectSettings,
+            ProjectManagerScreen::GemCatalog
+        };
+        m_screensCtrl->BuildScreens(m_screensOrder);
+        m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::NewProjectSettings, false);
+        UpdateNextButtonText();
+    }
+
+    ProjectManagerScreen ProjectSettingsCtrl::GetScreenEnum()
+    {
+        return ProjectManagerScreen::NewProjectSettingsCore;
+    }
+
+    void ProjectSettingsCtrl::HandleBackButton()
+    {
+        if (!m_screensCtrl->GotoPreviousScreen())
+        {
+            emit GotoPreviousScreenRequest();
+        }
+        else
+        {
+            UpdateNextButtonText();
+        }
+    }
+    void ProjectSettingsCtrl::HandleNextButton()
+    {
+        ProjectManagerScreen screenEnum = m_screensCtrl->GetCurrentScreen()->GetScreenEnum();
+        auto screenOrderIter = m_screensOrder.begin();
+        for (; screenOrderIter != m_screensOrder.end(); ++screenOrderIter)
+        {
+            if (*screenOrderIter == screenEnum)
+            {
+                ++screenOrderIter;
+                break;
+            }
+        }
+
+        if (screenOrderIter != m_screensOrder.end())
+        {
+            m_screensCtrl->ChangeToScreen(*screenOrderIter);
+            UpdateNextButtonText();
+        }
+        else
+        {
+            emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome);
+        }
+    }
+
+    void ProjectSettingsCtrl::UpdateNextButtonText()
+    {
+        m_nextButton->setText(m_screensCtrl->GetCurrentScreen()->GetNextButtonText());
+    }
+
+} // namespace O3DE::ProjectManager

+ 14 - 12
Code/Tools/ProjectManager/Source/NewProjectSettings.h → Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h

@@ -13,31 +13,33 @@
 
 #if !defined(Q_MOC_RUN)
 #include <ScreenWidget.h>
-#endif
 
-namespace Ui
-{
-    class NewProjectSettingsClass;
-}
+#include <ScreensCtrl.h>
+
+#include <QPushButton>
+#endif
 
 namespace O3DE::ProjectManager
 {
-    class NewProjectSettings
+    class ProjectSettingsCtrl
         : public ScreenWidget
     {
     public:
-        explicit NewProjectSettings(ProjectManagerWindow* window);
-        ~NewProjectSettings();
-
-    protected:
-        void ConnectSlotsAndSignals() override;
+        explicit ProjectSettingsCtrl(QWidget* parent = nullptr);
+        ~ProjectSettingsCtrl() = default;
+        ProjectManagerScreen GetScreenEnum() override;
 
     protected slots:
         void HandleBackButton();
         void HandleNextButton();
 
     private:
-        QScopedPointer<Ui::NewProjectSettingsClass> m_ui;
+        void UpdateNextButtonText();
+
+        ScreensCtrl* m_screensCtrl;
+        QPushButton* m_backButton;
+        QPushButton* m_nextButton;
+        QVector<ProjectManagerScreen> m_screensOrder;
     };
 
 } // namespace O3DE::ProjectManager

+ 9 - 13
Code/Tools/ProjectManager/Source/ProjectSettings.cpp → Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp

@@ -10,33 +10,29 @@
  *
  */
 
-#include <ProjectSettings.h>
+#include <ProjectSettingsScreen.h>
 
-#include <Source/ui_ProjectSettings.h>
+#include <Source/ui_ProjectSettingsScreen.h>
 
 namespace O3DE::ProjectManager
 {
-    ProjectSettings::ProjectSettings(ProjectManagerWindow* window)
-        : ScreenWidget(window)
+    ProjectSettingsScreen::ProjectSettingsScreen(QWidget* parent)
+        : ScreenWidget(parent)
         , m_ui(new Ui::ProjectSettingsClass())
     {
         m_ui->setupUi(this);
 
-        ConnectSlotsAndSignals();
+        connect(m_ui->gemsButton, &QPushButton::pressed, this, &ProjectSettingsScreen::HandleGemsButton);
     }
 
-    ProjectSettings::~ProjectSettings()
+    ProjectManagerScreen ProjectSettingsScreen::GetScreenEnum()
     {
+        return ProjectManagerScreen::ProjectSettings;
     }
 
-    void ProjectSettings::ConnectSlotsAndSignals()
+    void ProjectSettingsScreen::HandleGemsButton()
     {
-        QObject::connect(m_ui->gemsButton, &QPushButton::pressed, this, &ProjectSettings::HandleGemsButton);
-    }
-
-    void ProjectSettings::HandleGemsButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::GemCatalog);
+        emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
     }
 
 } // namespace O3DE::ProjectManager

+ 4 - 6
Code/Tools/ProjectManager/Source/ProjectSettings.h → Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h

@@ -22,15 +22,13 @@ namespace Ui
 
 namespace O3DE::ProjectManager
 {
-    class ProjectSettings
+    class ProjectSettingsScreen
         : public ScreenWidget
     {
     public:
-        explicit ProjectSettings(ProjectManagerWindow* window);
-        ~ProjectSettings();
-
-    protected:
-        void ConnectSlotsAndSignals() override;
+        explicit ProjectSettingsScreen(QWidget* parent = nullptr);
+        ~ProjectSettingsScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
 
     protected slots:
         void HandleGemsButton();

+ 0 - 0
Code/Tools/ProjectManager/Source/ProjectSettings.ui → Code/Tools/ProjectManager/Source/ProjectSettingsScreen.ui


+ 0 - 57
Code/Tools/ProjectManager/Source/ProjectsHome.cpp

@@ -1,57 +0,0 @@
-/*
- * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
- * its licensors.
- *
- * For complete copyright and license terms please see the LICENSE at the root of this
- * distribution (the "License"). All use of this software is governed by the License,
- * or, if provided, by the license below or the license accompanying this file. Do not
- * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- */
-
-#include <ProjectsHome.h>
-
-#include <Source/ui_ProjectsHome.h>
-
-#include <PythonBindingsInterface.h>
-
-namespace O3DE::ProjectManager
-{
-    ProjectsHome::ProjectsHome(ProjectManagerWindow* window)
-        : ScreenWidget(window)
-        , m_ui(new Ui::ProjectsHomeClass())
-    {
-        m_ui->setupUi(this);
-
-        ConnectSlotsAndSignals();
-
-        // example of how to get the current project name
-        ProjectInfo currentProject = PythonBindingsInterface::Get()->GetCurrentProject();
-    }
-
-    ProjectsHome::~ProjectsHome()
-    {
-    }
-
-    void ProjectsHome::ConnectSlotsAndSignals()
-    {
-        QObject::connect(m_ui->newProjectButton, &QPushButton::pressed, this, &ProjectsHome::HandleNewProjectButton);
-        QObject::connect(m_ui->addProjectButton, &QPushButton::pressed, this, &ProjectsHome::HandleAddProjectButton);
-        QObject::connect(m_ui->editProjectButton, &QPushButton::pressed, this, &ProjectsHome::HandleEditProjectButton);
-    }
-
-    void ProjectsHome::HandleNewProjectButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::NewProjectSettings);
-    }
-    void ProjectsHome::HandleAddProjectButton()
-    {
-        //Do nothing for now
-    }
-    void ProjectsHome::HandleEditProjectButton()
-    {
-        m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::ProjectSettings);
-    }
-
-} // namespace O3DE::ProjectManager

+ 51 - 0
Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp

@@ -0,0 +1,51 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include <ProjectsHomeScreen.h>
+
+#include <Source/ui_ProjectsHomeScreen.h>
+
+#include <PythonBindingsInterface.h>
+
+namespace O3DE::ProjectManager
+{
+    ProjectsHomeScreen::ProjectsHomeScreen(QWidget* parent)
+        : ScreenWidget(parent)
+        , m_ui(new Ui::ProjectsHomeClass())
+    {
+        m_ui->setupUi(this);
+
+        connect(m_ui->newProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleNewProjectButton);
+        connect(m_ui->addProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleAddProjectButton);
+        connect(m_ui->editProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleEditProjectButton);
+    }
+
+    ProjectManagerScreen ProjectsHomeScreen::GetScreenEnum()
+    {
+        return ProjectManagerScreen::ProjectsHome;
+    }
+
+    void ProjectsHomeScreen::HandleNewProjectButton()
+    {
+        emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore);
+        emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore);
+    }
+    void ProjectsHomeScreen::HandleAddProjectButton()
+    {
+        // Do nothing for now
+    }
+    void ProjectsHomeScreen::HandleEditProjectButton()
+    {
+        emit ChangeScreenRequest(ProjectManagerScreen::ProjectSettings);
+    }
+
+} // namespace O3DE::ProjectManager

+ 4 - 6
Code/Tools/ProjectManager/Source/ProjectsHome.h → Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h

@@ -22,16 +22,14 @@ namespace Ui
 
 namespace O3DE::ProjectManager
 {
-    class ProjectsHome
+    class ProjectsHomeScreen
         : public ScreenWidget
     {
 
     public:
-        explicit ProjectsHome(ProjectManagerWindow* window);
-        ~ProjectsHome();
-
-    protected:
-        void ConnectSlotsAndSignals() override;
+        explicit ProjectsHomeScreen(QWidget* parent = nullptr);
+        ~ProjectsHomeScreen() = default;
+        ProjectManagerScreen GetScreenEnum() override;
 
     protected slots:
         void HandleNewProjectButton();

+ 0 - 0
Code/Tools/ProjectManager/Source/ProjectsHome.ui → Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui


+ 4 - 1
Code/Tools/ProjectManager/Source/ScreenDefs.h

@@ -13,9 +13,12 @@
 
 namespace O3DE::ProjectManager
 {
-    enum class ProjectManagerScreen
+    enum ProjectManagerScreen
     {
+        Invalid = -1,
+        Empty,
         FirstTimeUse,
+        NewProjectSettingsCore,
         NewProjectSettings,
         GemCatalog,
         ProjectsHome,

+ 29 - 14
Code/Tools/ProjectManager/Source/ScreenFactory.cpp

@@ -11,33 +11,48 @@
  */
 #include <ScreenFactory.h>
 
-#include <FirstTimeUse.h>
-#include <NewProjectSettings.h>
-#include <GemCatalog/GemCatalog.h>
-#include <ProjectsHome.h>
-#include <ProjectSettings.h>
-#include <EngineSettings.h>
+#include <FirstTimeUseScreen.h>
+#include <ProjectSettingsCtrl.h>
+#include <NewProjectSettingsScreen.h>
+#include <GemCatalog/GemCatalogScreen.h>
+#include <ProjectsHomeScreen.h>
+#include <ProjectSettingsScreen.h>
+#include <EngineSettingsScreen.h>
 
 namespace O3DE::ProjectManager
 {
-    QWidget* BuildScreen(ProjectManagerWindow* window, ProjectManagerScreen screen)
+    ScreenWidget* BuildScreen(QWidget* parent, ProjectManagerScreen screen)
     {
+        ScreenWidget* newScreen;
+
         switch(screen)
         {
         case (ProjectManagerScreen::FirstTimeUse):
-            return new FirstTimeUse(window);
+            newScreen = new FirstTimeUseScreen(parent);
+            break;
+        case (ProjectManagerScreen::NewProjectSettingsCore):
+            newScreen = new ProjectSettingsCtrl(parent);
+            break;
         case (ProjectManagerScreen::NewProjectSettings):
-            return new NewProjectSettings(window);
+            newScreen = new NewProjectSettingsScreen(parent);
+            break;
         case (ProjectManagerScreen::GemCatalog):
-            return new GemCatalog(window);
+            newScreen = new GemCatalogScreen(parent);
+            break;
         case (ProjectManagerScreen::ProjectsHome):
-            return new ProjectsHome(window);
+            newScreen = new ProjectsHomeScreen(parent);
+            break;
         case (ProjectManagerScreen::ProjectSettings):
-            return new ProjectSettings(window);
+            newScreen = new ProjectSettingsScreen(parent);
+            break;
         case (ProjectManagerScreen::EngineSettings):
-            return new EngineSettings(window);
+            newScreen = new EngineSettingsScreen(parent);
+            break;
+        case (ProjectManagerScreen::Empty):
         default:
-            return new QWidget(window->GetScreenStack());
+            newScreen = new ScreenWidget(parent);
         }
+
+        return newScreen;
     }
 } // namespace O3DE::ProjectManager

+ 3 - 4
Code/Tools/ProjectManager/Source/ScreenFactory.h

@@ -13,12 +13,11 @@
 
 #include <ScreenDefs.h>
 
-#include <ProjectManagerWindow.h>
-
 #include <QWidget>
 
-
 namespace O3DE::ProjectManager
 {
-    QWidget* BuildScreen(ProjectManagerWindow* window, ProjectManagerScreen screen);
+    class ScreenWidget;
+
+    ScreenWidget* BuildScreen(QWidget* parent = nullptr, ProjectManagerScreen screen = ProjectManagerScreen::Empty);
 } // namespace O3DE::ProjectManager

+ 22 - 7
Code/Tools/ProjectManager/Source/ScreenWidget.h

@@ -12,7 +12,7 @@
 #pragma once
 
 #if !defined(Q_MOC_RUN)
-#include <ProjectManagerWindow.h>
+#include <ScreenDefs.h>
 
 #include <QWidget>
 #endif
@@ -22,17 +22,32 @@ namespace O3DE::ProjectManager
     class ScreenWidget
         : public QWidget
     {
+        Q_OBJECT
+
     public:
-        explicit ScreenWidget(ProjectManagerWindow* window)
-            : QWidget(window->GetScreenStack())
-            , m_projectManagerWindow(window)
+        explicit ScreenWidget(QWidget* parent = nullptr)
+            : QWidget(parent)
         {
         }
+        ~ScreenWidget() = default;
 
-    protected:
-        virtual void ConnectSlotsAndSignals() {}
+        virtual ProjectManagerScreen GetScreenEnum()
+        {
+            return ProjectManagerScreen::Empty;
+        }
+        virtual bool IsReadyForNextScreen()
+        {
+            return true;
+        }
+        virtual QString GetNextButtonText()
+        {
+            return "Next";
+        }
 
-        ProjectManagerWindow* m_projectManagerWindow;
+    signals:
+        void ChangeScreenRequest(ProjectManagerScreen screen);
+        void GotoPreviousScreenRequest();
+        void ResetScreenRequest(ProjectManagerScreen screen);
     };
 
 } // namespace O3DE::ProjectManager

+ 149 - 0
Code/Tools/ProjectManager/Source/ScreensCtrl.cpp

@@ -0,0 +1,149 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include <ScreensCtrl.h>
+#include <ScreenFactory.h>
+#include <ScreenWidget.h>
+
+#include <QVBoxLayout>
+
+namespace O3DE::ProjectManager
+{
+    ScreensCtrl::ScreensCtrl(QWidget* parent)
+        : QWidget(parent)
+    {
+        QVBoxLayout* vLayout = new QVBoxLayout();
+        setLayout(vLayout);
+
+        m_screenStack = new QStackedWidget();
+        vLayout->addWidget(m_screenStack);
+
+        //Track the bottom of the stack
+        m_screenVisitOrder.push(ProjectManagerScreen::Invalid);
+    }
+
+    void ScreensCtrl::BuildScreens(QVector<ProjectManagerScreen> screens)
+    {
+        for (ProjectManagerScreen screen : screens)
+        {
+            ResetScreen(screen);
+        }
+    }
+
+    ScreenWidget* ScreensCtrl::FindScreen(ProjectManagerScreen screen)
+    {
+        const auto iterator = m_screenMap.find(screen);
+        if (iterator != m_screenMap.end())
+        {
+            return iterator.value();
+        }
+        else
+        {
+            return nullptr;
+        }
+    }
+
+    ScreenWidget* ScreensCtrl::GetCurrentScreen()
+    {
+        return reinterpret_cast<ScreenWidget*>(m_screenStack->currentWidget());
+    }
+
+    bool ScreensCtrl::ChangeToScreen(ProjectManagerScreen screen)
+    {
+        if (m_screenStack->currentWidget())
+        {
+            ScreenWidget* currentScreenWidget = GetCurrentScreen();
+            if (currentScreenWidget->IsReadyForNextScreen())
+            {
+                return ForceChangeToScreen(screen);
+            }
+        }
+        return false;
+    }
+
+    bool ScreensCtrl::ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit)
+    {
+        const auto iterator = m_screenMap.find(screen);
+        if (iterator != m_screenMap.end())
+        {
+            ScreenWidget* currentScreen = GetCurrentScreen();
+            if (currentScreen != iterator.value())
+            {
+                if (addVisit)
+                {
+                    m_screenVisitOrder.push(currentScreen->GetScreenEnum());
+                }
+                m_screenStack->setCurrentWidget(iterator.value());
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    bool ScreensCtrl::GotoPreviousScreen()
+    {
+        // Don't go back if we are on the first set screen
+        if (m_screenVisitOrder.top() != ProjectManagerScreen::Invalid)
+        {
+            // We do not check with screen if we can go back, we should always be able to go back
+            return ForceChangeToScreen(m_screenVisitOrder.pop(), false);
+        }
+        return false;
+    }
+
+    void ScreensCtrl::ResetScreen(ProjectManagerScreen screen)
+    {
+        // Delete old screen if it exists to start fresh
+        DeleteScreen(screen);
+
+        // Add new screen
+        ScreenWidget* newScreen = BuildScreen(this, screen);
+        m_screenStack->addWidget(newScreen);
+        m_screenMap.insert(screen, newScreen);
+
+        connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen);
+        connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen);
+        connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen);
+    }
+
+    void ScreensCtrl::ResetAllScreens()
+    {
+        for (auto iter = m_screenMap.begin(); iter != m_screenMap.end(); ++iter)
+        {
+            ResetScreen(iter.key());
+        }
+    }
+
+    void ScreensCtrl::DeleteScreen(ProjectManagerScreen screen)
+    {
+        // Find the old screen if it exists and get rid of it
+        const auto iter = m_screenMap.find(screen);
+        if (iter != m_screenMap.end())
+        {
+            m_screenStack->removeWidget(iter.value());
+            iter.value()->deleteLater();
+
+            // Erase does not cause a rehash so interators remain valid
+            m_screenMap.erase(iter);
+        }
+    }
+
+    void ScreensCtrl::DeleteAllScreens()
+    {
+        for (auto iter = m_screenMap.begin(); iter != m_screenMap.end(); ++iter)
+        {
+            DeleteScreen(iter.key());
+        }
+    }
+
+} // namespace O3DE::ProjectManager

+ 53 - 0
Code/Tools/ProjectManager/Source/ScreensCtrl.h

@@ -0,0 +1,53 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+#pragma once
+
+#if !defined(Q_MOC_RUN)
+#include <ScreenDefs.h>
+
+#include <QStackedWidget>
+#include <QStack>
+#endif
+
+namespace O3DE::ProjectManager
+{
+    class ScreenWidget;
+
+    class ScreensCtrl
+        : public QWidget
+    {
+        Q_OBJECT
+
+    public:
+        explicit ScreensCtrl(QWidget* parent = nullptr);
+        ~ScreensCtrl() = default;
+
+        void BuildScreens(QVector<ProjectManagerScreen> screens);
+        ScreenWidget* FindScreen(ProjectManagerScreen screen);
+        ScreenWidget* GetCurrentScreen();
+
+    public slots:
+        bool ChangeToScreen(ProjectManagerScreen screen);
+        bool ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit = true);
+        bool GotoPreviousScreen();
+        void ResetScreen(ProjectManagerScreen screen);
+        void ResetAllScreens();
+        void DeleteScreen(ProjectManagerScreen screen);
+        void DeleteAllScreens();
+
+    private:
+        QStackedWidget* m_screenStack;
+        QHash<ProjectManagerScreen, ScreenWidget*> m_screenMap;
+        QStack<ProjectManagerScreen> m_screenVisitOrder;
+    };
+
+} // namespace O3DE::ProjectManager

+ 22 - 19
Code/Tools/ProjectManager/project_manager_files.cmake

@@ -15,36 +15,39 @@ set(FILES
     Source/ScreenDefs.h
     Source/ScreenFactory.h
     Source/ScreenFactory.cpp
+    Source/ScreensCtrl.h
+    Source/ScreensCtrl.cpp
     Source/ScreenWidget.h
-    Source/FirstTimeUse.h
-    Source/FirstTimeUse.cpp
-    Source/FirstTimeUse.ui
-    Source/ProjectInfo.h
-    Source/ProjectInfo.cpp
+    Source/FirstTimeUseScreen.h
+    Source/FirstTimeUseScreen.cpp
+    Source/FirstTimeUseScreen.ui
     Source/ProjectManagerWindow.h
     Source/ProjectManagerWindow.cpp
     Source/ProjectManagerWindow.ui
     Source/PythonBindings.h
     Source/PythonBindings.cpp
     Source/PythonBindingsInterface.h
-    Source/NewProjectSettings.h
-    Source/NewProjectSettings.cpp
-    Source/NewProjectSettings.ui
-    Source/ProjectsHome.h
-    Source/ProjectsHome.cpp
-    Source/ProjectsHome.ui
-    Source/ProjectSettings.h
-    Source/ProjectSettings.cpp
-    Source/ProjectSettings.ui
-    Source/EngineSettings.h
-    Source/EngineSettings.cpp
-    Source/EngineSettings.ui
+    Source/ProjectInfo.h
+    Source/ProjectInfo.cpp
+    Source/NewProjectSettingsScreen.h
+    Source/NewProjectSettingsScreen.cpp
+    Source/ProjectSettingsCtrl.h
+    Source/ProjectSettingsCtrl.cpp
+    Source/ProjectsHomeScreen.h
+    Source/ProjectsHomeScreen.cpp
+    Source/ProjectsHomeScreen.ui
+    Source/ProjectSettingsScreen.h
+    Source/ProjectSettingsScreen.cpp
+    Source/ProjectSettingsScreen.ui
+    Source/EngineSettingsScreen.h
+    Source/EngineSettingsScreen.cpp
+    Source/EngineSettingsScreen.ui
     Source/LinkWidget.h
     Source/LinkWidget.cpp
     Source/TagWidget.h
     Source/TagWidget.cpp
-    Source/GemCatalog/GemCatalog.h
-    Source/GemCatalog/GemCatalog.cpp
+    Source/GemCatalog/GemCatalogScreen.h
+    Source/GemCatalog/GemCatalogScreen.cpp
     Source/GemCatalog/GemInfo.h
     Source/GemCatalog/GemInfo.cpp
     Source/GemCatalog/GemItemDelegate.h