From 1586c00fc8e630298fa2c601ee28fa28772e1486 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Thu, 1 Jul 2021 09:53:17 -0700 Subject: [PATCH] [LYN-4929] Correct gems not showing as enabled for a template (#1722) * When there are multiple project templates present, we re-gather the gems when changing the selected the project template. * In case the user enabled or disabled any gem and they select a new project template, we show a warning dialog where users can either cancel the operation or proceed to the new project template. The warning dialog will only appear in case the enabled gems actually differ from the currently used template's default. * New helper function to select the used project template. * Storing the currently used project template index and only update the template details and emitting the changed event in case the user has actually chosen another template. This avoids emitting signals in case the user clicks on the already selected template. Signed-off-by: Benjamin Jillich --- .../Source/CreateProjectCtrl.cpp | 46 +++++++++++++++++-- .../ProjectManager/Source/CreateProjectCtrl.h | 1 + .../Source/GemCatalog/GemCatalogScreen.h | 2 + .../Source/NewProjectSettingsScreen.cpp | 41 +++++++++++++++-- .../Source/NewProjectSettingsScreen.h | 8 ++++ 5 files changed, 89 insertions(+), 9 deletions(-) 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;