diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index 507cf38726..298d2a749a 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -218,6 +218,10 @@ QTabBar::tab:focus { color: #666666; } +#verticalSeparatingLine { + color: #888888; +} + /************** Project Settings **************/ #projectSettings { margin-top:42px; @@ -481,6 +485,14 @@ QProgressBar::chunk { font-weight: 600; } +#gemCatalogMenuButton { + qproperty-flat: true; + max-width:36px; + min-width:36px; + max-height:24px; + min-height:24px; +} + #GemCatalogCartOverlayGemDownloadHeader { margin:0; padding: 0px; diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 84b931cb30..65e01803aa 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -49,6 +49,8 @@ namespace O3DE::ProjectManager m_stack->addWidget(m_gemCatalogScreen); vLayout->addWidget(m_stack); + connect(m_gemCatalogScreen, &ScreenWidget::ChangeScreenRequest, this, &CreateProjectCtrl::OnChangeScreenRequest); + // 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) { @@ -133,7 +135,7 @@ namespace O3DE::ProjectManager } else { - emit GotoPreviousScreenRequest(); + emit GoToPreviousScreenRequest(); } } diff --git a/Code/Tools/ProjectManager/Source/EngineScreenCtrl.cpp b/Code/Tools/ProjectManager/Source/EngineScreenCtrl.cpp index c78a9426db..f30a8e0daa 100644 --- a/Code/Tools/ProjectManager/Source/EngineScreenCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/EngineScreenCtrl.cpp @@ -29,17 +29,17 @@ namespace O3DE::ProjectManager topBarFrameWidget->setLayout(topBarHLayout); - QTabWidget* tabWidget = new QTabWidget(); - tabWidget->setObjectName("engineTab"); - tabWidget->tabBar()->setObjectName("engineTabBar"); - tabWidget->tabBar()->setFocusPolicy(Qt::TabFocus); + m_tabWidget = new QTabWidget(); + m_tabWidget->setObjectName("engineTab"); + m_tabWidget->tabBar()->setObjectName("engineTabBar"); + m_tabWidget->tabBar()->setFocusPolicy(Qt::TabFocus); m_engineSettingsScreen = new EngineSettingsScreen(); m_gemRepoScreen = new GemRepoScreen(); - tabWidget->addTab(m_engineSettingsScreen, tr("General")); - tabWidget->addTab(m_gemRepoScreen, tr("Gem Repositories")); - topBarHLayout->addWidget(tabWidget); + m_tabWidget->addTab(m_engineSettingsScreen, tr("General")); + m_tabWidget->addTab(m_gemRepoScreen, tr("Gem Repositories")); + topBarHLayout->addWidget(m_tabWidget); vLayout->addWidget(topBarFrameWidget); @@ -61,4 +61,28 @@ namespace O3DE::ProjectManager return true; } + bool EngineScreenCtrl::ContainsScreen(ProjectManagerScreen screen) + { + if (screen == m_engineSettingsScreen->GetScreenEnum() || screen == m_gemRepoScreen->GetScreenEnum()) + { + return true; + } + + return false; + } + + void EngineScreenCtrl::GoToScreen(ProjectManagerScreen screen) + { + if (screen == m_engineSettingsScreen->GetScreenEnum()) + { + m_tabWidget->setCurrentWidget(m_engineSettingsScreen); + m_engineSettingsScreen->NotifyCurrentScreen(); + } + else if (screen == m_gemRepoScreen->GetScreenEnum()) + { + m_tabWidget->setCurrentWidget(m_gemRepoScreen); + m_gemRepoScreen->NotifyCurrentScreen(); + } + } + } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/EngineScreenCtrl.h b/Code/Tools/ProjectManager/Source/EngineScreenCtrl.h index 9e799f13e7..b7142ba226 100644 --- a/Code/Tools/ProjectManager/Source/EngineScreenCtrl.h +++ b/Code/Tools/ProjectManager/Source/EngineScreenCtrl.h @@ -11,6 +11,8 @@ #include #endif +QT_FORWARD_DECLARE_CLASS(QTabWidget) + namespace O3DE::ProjectManager { QT_FORWARD_DECLARE_CLASS(EngineSettingsScreen) @@ -26,7 +28,10 @@ namespace O3DE::ProjectManager QString GetTabText() override; bool IsTab() override; + bool ContainsScreen(ProjectManagerScreen screen) override; + void GoToScreen(ProjectManagerScreen screen) override; + QTabWidget* m_tabWidget = nullptr; EngineSettingsScreen* m_engineSettingsScreen = nullptr; GemRepoScreen* m_gemRepoScreen = nullptr; }; diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp index 79ff7624b7..0ecea215bf 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp @@ -8,12 +8,14 @@ #include #include +#include + #include #include #include #include +#include #include -#include namespace O3DE::ProjectManager { @@ -404,6 +406,28 @@ namespace O3DE::ProjectManager CartButton* cartButton = new CartButton(gemModel, downloadController); hLayout->addWidget(cartButton); + + hLayout->addSpacing(16); + + // Separating line + QFrame* vLine = new QFrame(); + vLine->setFrameShape(QFrame::VLine); + vLine->setObjectName("verticalSeparatingLine"); + hLayout->addWidget(vLine); + + hLayout->addSpacing(16); + + QMenu* gemMenu = new QMenu(this); + m_openGemReposAction = gemMenu->addAction(tr("Show Gem Repos")); + + connect(m_openGemReposAction, &QAction::triggered, this,[this](){ emit OpenGemsRepo(); }); + + QPushButton* gemMenuButton = new QPushButton(this); + gemMenuButton->setObjectName("gemCatalogMenuButton"); + gemMenuButton->setMenu(gemMenu); + gemMenuButton->setIcon(QIcon(":/menu.svg")); + gemMenuButton->setIconSize(QSize(36, 24)); + hLayout->addWidget(gemMenuButton); } void GemCatalogHeaderWidget::ReinitForProject() diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h index 8e0eaa13ba..fa381e54ae 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h @@ -15,13 +15,15 @@ #include #include #include +#include + #include #include #include #include #include #include -#include +#include #endif namespace O3DE::ProjectManager @@ -84,8 +86,13 @@ namespace O3DE::ProjectManager void ReinitForProject(); + signals: + void OpenGemsRepo(); + private: AzQtComponents::SearchLineEdit* m_filterLineEdit = nullptr; inline constexpr static int s_height = 60; + + QAction* m_openGemReposAction = nullptr; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index 58f3b48c81..cbe36400cf 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -38,6 +38,8 @@ namespace O3DE::ProjectManager m_headerWidget = new GemCatalogHeaderWidget(m_gemModel, m_proxModel, m_downloadController); vLayout->addWidget(m_headerWidget); + connect(m_headerWidget, &GemCatalogHeaderWidget::OpenGemsRepo, this, &GemCatalogScreen::HandleOpenGemRepo); + QHBoxLayout* hLayout = new QHBoxLayout(); hLayout->setMargin(0); vLayout->addLayout(hLayout); @@ -194,6 +196,27 @@ namespace O3DE::ProjectManager return EnableDisableGemsResult::Success; } + void GemCatalogScreen::HandleOpenGemRepo() + { + QVector gemsToBeAdded = m_gemModel->GatherGemsToBeAdded(true); + QVector gemsToBeRemoved = m_gemModel->GatherGemsToBeRemoved(true); + + if (!gemsToBeAdded.empty() || !gemsToBeRemoved.empty()) + { + QMessageBox::StandardButton warningResult = QMessageBox::warning( + nullptr, "Pending Changes", + "There are some unsaved changes to the gem selection,
they will be lost if you change screens.
Are you sure?", + QMessageBox::No | QMessageBox::Yes); + + if (warningResult != QMessageBox::Yes) + { + return; + } + } + + emit ChangeScreenRequest(ProjectManagerScreen::GemRepos); + } + ProjectManagerScreen GemCatalogScreen::GetScreenEnum() { return ProjectManagerScreen::GemCatalog; diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index 361e34b214..456a5fe91c 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -41,7 +41,11 @@ namespace O3DE::ProjectManager GemModel* GetGemModel() const { return m_gemModel; } DownloadController* GetDownloadController() const { return m_downloadController; } + private slots: + void HandleOpenGemRepo(); + private: + void FillModel(const QString& projectPath); GemListView* m_gemListView = nullptr; diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index 9563fc2f6a..148dcdb8c8 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -47,6 +47,14 @@ namespace O3DE::ProjectManager return tr("Missing"); } + virtual bool ContainsScreen([[maybe_unused]] ProjectManagerScreen screen) + { + return false; + } + virtual void GoToScreen([[maybe_unused]] ProjectManagerScreen screen) + { + } + //! Notify this screen it is the current screen virtual void NotifyCurrentScreen() { @@ -55,7 +63,7 @@ namespace O3DE::ProjectManager signals: void ChangeScreenRequest(ProjectManagerScreen screen); - void GotoPreviousScreenRequest(); + void GoToPreviousScreenRequest(); void ResetScreenRequest(ProjectManagerScreen screen); void NotifyCurrentProject(const QString& projectPath); void NotifyBuildProject(const ProjectInfo& projectInfo); diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp index df0bdb29f4..314765def0 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp @@ -83,11 +83,28 @@ namespace O3DE::ProjectManager bool ScreensCtrl::ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit) { + ScreenWidget* newScreen = nullptr; + const auto iterator = m_screenMap.find(screen); if (iterator != m_screenMap.end()) + { + newScreen = iterator.value(); + } + else + { + // Check if screen is contained by another screen + for (ScreenWidget* checkingScreen : m_screenMap) + { + if (checkingScreen->ContainsScreen(screen)) + { + newScreen = checkingScreen; + break; + } + } + } + if (newScreen) { ScreenWidget* currentScreen = GetCurrentScreen(); - ScreenWidget* newScreen = iterator.value(); if (currentScreen != newScreen) { @@ -109,6 +126,11 @@ namespace O3DE::ProjectManager newScreen->NotifyCurrentScreen(); + if (iterator == m_screenMap.end()) + { + newScreen->GoToScreen(screen); + } + return true; } } @@ -116,7 +138,7 @@ namespace O3DE::ProjectManager return false; } - bool ScreensCtrl::GotoPreviousScreen() + bool ScreensCtrl::GoToPreviousScreen() { if (!m_screenVisitOrder.isEmpty()) { @@ -171,7 +193,7 @@ namespace O3DE::ProjectManager m_screenMap.insert(screen, newScreen); connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen); - connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen); + connect(newScreen, &ScreenWidget::GoToPreviousScreenRequest, this, &ScreensCtrl::GoToPreviousScreen); connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen); connect(newScreen, &ScreenWidget::NotifyCurrentProject, this, &ScreensCtrl::NotifyCurrentProject); connect(newScreen, &ScreenWidget::NotifyBuildProject, this, &ScreensCtrl::NotifyBuildProject); diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h index 7132d64dd0..ab69a09ea3 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h @@ -41,7 +41,7 @@ namespace O3DE::ProjectManager public slots: bool ChangeToScreen(ProjectManagerScreen screen); bool ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit = true); - bool GotoPreviousScreen(); + bool GoToPreviousScreen(); void ResetScreen(ProjectManagerScreen screen); void ResetAllScreens(); void DeleteScreen(ProjectManagerScreen screen); diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp index fd2ebf340f..1c8f9a6931 100644 --- a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -40,6 +40,10 @@ namespace O3DE::ProjectManager m_updateSettingsScreen = new UpdateProjectSettingsScreen(); m_gemCatalogScreen = new GemCatalogScreen(); + connect(m_gemCatalogScreen, &ScreenWidget::ChangeScreenRequest, this, [this](ProjectManagerScreen screen){ + emit ChangeScreenRequest(screen); + }); + m_stack = new QStackedWidget(this); m_stack->setObjectName("body"); m_stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding)); @@ -118,7 +122,7 @@ namespace O3DE::ProjectManager { if (UpdateProjectSettings(true)) { - emit GotoPreviousScreenRequest(); + emit GoToPreviousScreenRequest(); } } }