diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 0ec395a6df..9c0b4726ed 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,40 @@ namespace O3DE::ProjectManager m_stack->addWidget(m_gemCatalogScreen); vLayout->addWidget(m_stack); + // When there are multiple project templates present, we re-gather the gems when changing the selected the project template. + connect(m_newProjectSettingsScreen, &NewProjectSettingsScreen::OnTemplateSelectionChanged, this, [=](int oldIndex, [[maybe_unused]] int newIndex) + { + const GemModel* gemModel = m_gemCatalogScreen->GetGemModel(); + const QVector toBeAdded = gemModel->GatherGemsToBeAdded(); + const QVector toBeRemoved = gemModel->GatherGemsToBeRemoved(); + if (!toBeAdded.isEmpty() || !toBeRemoved.isEmpty()) + { + // In case the user enabled or disabled any gem and the current selection does not match the default from the + // // project template anymore, we need to ask the user if they want to proceed as their modifications will be lost. + const QString title = tr("Modifications will be lost"); + const QString text = tr("You selected a new project template after modifying the enabled gems.\n\n" + "All modifications will be lost and the default from the new project template will be used.\n\n" + "Do you want to proceed?"); + if (QMessageBox::warning(this, title, text, QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) + { + // The users wants to proceed. Reinitialize based on the newly selected project template. + ReinitGemCatalogForSelectedTemplate(); + } + else + { + // Roll-back to the previously selected project template and + // block signals so that we don't end up in this same callback again. + m_newProjectSettingsScreen->SelectProjectTemplate(oldIndex, /*blockSignals=*/true); + } + } + else + { + // In case the user did not enable or disable any gem and the currently enabled gems matches the previously selected + // ones from the project template, we can just reinitialize based on the newly selected project template. + ReinitGemCatalogForSelectedTemplate(); + } + }); + QDialogButtonBox* buttons = new QDialogButtonBox(); buttons->setObjectName("footer"); vLayout->addWidget(buttons); @@ -81,10 +116,8 @@ namespace O3DE::ProjectManager currentScreen->NotifyCurrentScreen(); } - // Gather the gems from the project template. When we will have multiple project templates, we need to re-gather them - // on changing the template and let the user know that any further changes on top of the template will be lost. - QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); - m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); + // Gather the enabled gems from the default project template when starting the create new project workflow. + ReinitGemCatalogForSelectedTemplate(); } void CreateProjectCtrl::HandleBackButton() @@ -223,4 +256,9 @@ namespace O3DE::ProjectManager } } + void CreateProjectCtrl::ReinitGemCatalogForSelectedTemplate() + { + const QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); + m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h index c2b4528802..c453e2d500 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h @@ -40,6 +40,7 @@ namespace O3DE::ProjectManager #ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED void OnChangeScreenRequest(ProjectManagerScreen screen); void HandleSecondaryButton(); + void ReinitGemCatalogForSelectedTemplate(); #endif // TEMPLATE_GEM_CONFIGURATION_ENABLED private: diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index 0fdfc6bdf5..b7fcf8446e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -30,6 +30,8 @@ namespace O3DE::ProjectManager void ReinitForProject(const QString& projectPath, bool isNewProject); bool EnableDisableGemsForProject(const QString& projectPath); + GemModel* GetGemModel() const { return m_gemModel; } + private: void FillModel(const QString& projectPath, bool isNewProject); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index efecb2d901..26e5e074e5 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -81,8 +81,14 @@ namespace O3DE::ProjectManager { if (button && button->property(k_templateIndexProperty).isValid()) { - int projectIndex = button->property(k_templateIndexProperty).toInt(); - UpdateTemplateDetails(m_templates.at(projectIndex)); + int projectTemplateIndex = button->property(k_templateIndexProperty).toInt(); + if (m_selectedTemplateIndex != projectTemplateIndex) + { + const int oldIndex = m_selectedTemplateIndex; + m_selectedTemplateIndex = projectTemplateIndex; + UpdateTemplateDetails(m_templates.at(m_selectedTemplateIndex)); + emit OnTemplateSelectionChanged(/*oldIndex=*/oldIndex, /*newIndex=*/m_selectedTemplateIndex); + } } }); @@ -115,7 +121,8 @@ namespace O3DE::ProjectManager flowLayout->addWidget(templateButton); } - m_projectTemplateButtonGroup->buttons().first()->setChecked(true); + // Select the first project template (default selection). + SelectProjectTemplate(0, /*blockSignals=*/true); } containerLayout->addWidget(templatesScrollArea); } @@ -159,8 +166,9 @@ namespace O3DE::ProjectManager QString NewProjectSettingsScreen::GetProjectTemplatePath() { - const int templateIndex = m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt(); - return m_templates.at(templateIndex).m_path; + AZ_Assert(m_selectedTemplateIndex == m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt(), + "Selected template index not in sync with the currently checked project template button."); + return m_templates.at(m_selectedTemplateIndex).m_path; } QFrame* NewProjectSettingsScreen::CreateTemplateDetails(int margin) @@ -216,4 +224,27 @@ namespace O3DE::ProjectManager m_templateSummary->setText(templateInfo.m_summary); m_templateIncludedGems->Update(templateInfo.m_includedGems); } + + void NewProjectSettingsScreen::SelectProjectTemplate(int index, bool blockSignals) + { + const QList buttons = m_projectTemplateButtonGroup->buttons(); + if (index >= buttons.size()) + { + return; + } + + if (blockSignals) + { + m_projectTemplateButtonGroup->blockSignals(true); + } + + QAbstractButton* button = buttons.at(index); + button->setChecked(true); + m_selectedTemplateIndex = button->property(k_templateIndexProperty).toInt(); + + if (blockSignals) + { + m_projectTemplateButtonGroup->blockSignals(false); + } + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h index 4238ef98be..d812bfd091 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h @@ -22,6 +22,8 @@ namespace O3DE::ProjectManager class NewProjectSettingsScreen : public ProjectSettingsScreen { + Q_OBJECT + public: explicit NewProjectSettingsScreen(QWidget* parent = nullptr); ~NewProjectSettingsScreen() = default; @@ -31,6 +33,11 @@ namespace O3DE::ProjectManager void NotifyCurrentScreen() override; + void SelectProjectTemplate(int index, bool blockSignals = false); + + signals: + void OnTemplateSelectionChanged(int oldIndex, int newIndex); + private: QString GetDefaultProjectPath(); QFrame* CreateTemplateDetails(int margin); @@ -41,6 +48,7 @@ namespace O3DE::ProjectManager QLabel* m_templateSummary; TagContainerWidget* m_templateIncludedGems; QVector m_templates; + int m_selectedTemplateIndex = -1; inline constexpr static int s_spacerSize = 20; inline constexpr static int s_templateDetailsContentMargin = 20;