diff --git a/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png new file mode 100644 index 0000000000..cc1eda5bb8 --- /dev/null +++ b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f22df64b93d4bec91e56b60efa3d5ce2915ce388a2dc627f1ab720678e3d5 +size 334987 diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc index 1ffd7cf3e7..ac55c48a6b 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc @@ -11,6 +11,9 @@ iOS.svg Linux.svg macOS.svg + DefaultProjectImage.png + ArrowDownLine.svg + ArrowUpLine.svg Backgrounds/FirstTimeBackgroundImage.jpg diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp similarity index 77% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 95dcec3e18..03e6a34b89 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include @@ -22,7 +22,7 @@ namespace O3DE::ProjectManager { - ProjectSettingsCtrl::ProjectSettingsCtrl(QWidget* parent) + CreateProjectCtrl::CreateProjectCtrl(QWidget* parent) : ScreenWidget(parent) { QVBoxLayout* vLayout = new QVBoxLayout(); @@ -34,11 +34,11 @@ namespace O3DE::ProjectManager QDialogButtonBox* backNextButtons = new QDialogButtonBox(); vLayout->addWidget(backNextButtons); - m_backButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole); - m_nextButton = backNextButtons->addButton("Next", QDialogButtonBox::ApplyRole); + m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); - connect(m_backButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleBackButton); - connect(m_nextButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleNextButton); + connect(m_backButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleNextButton); m_screensOrder = { @@ -47,15 +47,16 @@ namespace O3DE::ProjectManager }; m_screensCtrl->BuildScreens(m_screensOrder); m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::NewProjectSettings, false); + UpdateNextButtonText(); } - ProjectManagerScreen ProjectSettingsCtrl::GetScreenEnum() + ProjectManagerScreen CreateProjectCtrl::GetScreenEnum() { - return ProjectManagerScreen::NewProjectSettingsCore; + return ProjectManagerScreen::CreateProject; } - void ProjectSettingsCtrl::HandleBackButton() + void CreateProjectCtrl::HandleBackButton() { if (!m_screensCtrl->GotoPreviousScreen()) { @@ -66,7 +67,7 @@ namespace O3DE::ProjectManager UpdateNextButtonText(); } } - void ProjectSettingsCtrl::HandleNextButton() + void CreateProjectCtrl::HandleNextButton() { ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); @@ -116,9 +117,14 @@ namespace O3DE::ProjectManager } } - void ProjectSettingsCtrl::UpdateNextButtonText() + void CreateProjectCtrl::UpdateNextButtonText() { - m_nextButton->setText(m_screensCtrl->GetCurrentScreen()->GetNextButtonText()); + QString nextButtonText = tr("Next"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Create Project"); + } + m_nextButton->setText(nextButtonText); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h similarity index 90% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.h index 42f1ce1978..213bff3bc2 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h @@ -21,12 +21,12 @@ namespace O3DE::ProjectManager { - class ProjectSettingsCtrl + class CreateProjectCtrl : public ScreenWidget { public: - explicit ProjectSettingsCtrl(QWidget* parent = nullptr); - ~ProjectSettingsCtrl() = default; + explicit CreateProjectCtrl(QWidget* parent = nullptr); + ~CreateProjectCtrl() = default; ProjectManagerScreen GetScreenEnum() override; protected slots: diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp index a1be7e8ac9..8654b221fb 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp @@ -21,13 +21,6 @@ namespace O3DE::ProjectManager { - inline constexpr static int s_contentMargins = 80; - inline constexpr static int s_buttonSpacing = 30; - inline constexpr static int s_iconSize = 24; - inline constexpr static int s_spacerSize = 20; - inline constexpr static int s_boxButtonWidth = 210; - inline constexpr static int s_boxButtonHeight = 280; - FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent) : ScreenWidget(parent) { @@ -79,8 +72,8 @@ namespace O3DE::ProjectManager void FirstTimeUseScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void FirstTimeUseScreen::HandleAddProjectButton() { diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h index b6b57dc16b..80a2310d7a 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h @@ -37,6 +37,13 @@ namespace O3DE::ProjectManager QPushButton* m_createProjectButton; QPushButton* m_addProjectButton; + + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_buttonSpacing = 30; + inline constexpr static int s_iconSize = 24; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_boxButtonWidth = 210; + inline constexpr static int s_boxButtonHeight = 280; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index bbc6099f24..7d8cee45b4 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -170,9 +170,4 @@ namespace O3DE::ProjectManager { return ProjectManagerScreen::GemCatalog; } - - QString GemCatalogScreen::GetNextButtonText() - { - return "Create Project"; - } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index bf4202499f..44e0727c7e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit GemCatalogScreen(QWidget* parent = nullptr); ~GemCatalogScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; private: QVector GenerateTestData(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index 153c0964c7..ffbf1bf6fe 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -96,11 +96,6 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::NewProjectSettings; } - QString NewProjectSettingsScreen::GetNextButtonText() - { - return tr("Next"); - } - void NewProjectSettingsScreen::HandleBrowseButton() { QString defaultPath = m_projectPathLineEdit->text(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h index dbd4388668..1cfd3c9c35 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit NewProjectSettingsScreen(QWidget* parent = nullptr); ~NewProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; ProjectInfo GetProjectInfo(); QString GetProjectTemplatePath(); diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp new file mode 100644 index 0000000000..ec1acdad61 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp @@ -0,0 +1,102 @@ +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +//#define SHOW_ALL_PROJECT_ACTIONS + +namespace O3DE::ProjectManager +{ + inline constexpr static int s_projectImageWidth = 210; + inline constexpr static int s_projectImageHeight = 280; + + LabelButton::LabelButton(QWidget* parent) + : QLabel(parent) + { + } + + void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event) + { + emit triggered(); + } + + ProjectButton::ProjectButton(const QString& projectName, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(":/Resources/DefaultProjectImage.png") + { + Setup(); + } + + ProjectButton::ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(projectImage) + { + Setup(); + } + + void ProjectButton::Setup() + { + QVBoxLayout* vLayout = new QVBoxLayout(); + vLayout->setSpacing(0); + vLayout->setContentsMargins(0, 0, 0, 0); + setLayout(vLayout); + + m_projectImageLabel = new LabelButton(this); + m_projectImageLabel->setFixedSize(s_projectImageWidth, s_projectImageHeight); + vLayout->addWidget(m_projectImageLabel); + + m_projectImageLabel->setPixmap(QPixmap(m_projectImagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding)); + + QMenu* newProjectMenu = new QMenu(this); + m_editProjectAction = newProjectMenu->addAction(tr("Edit Project Settings...")); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems...")); + newProjectMenu->addSeparator(); + m_copyProjectAction = newProjectMenu->addAction(tr("Duplicate")); + newProjectMenu->addSeparator(); + m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE")); + m_deleteProjectAction = newProjectMenu->addAction(tr("Delete the Project")); +#endif + + m_projectSettingsMenuButton = new QPushButton(this); + m_projectSettingsMenuButton->setText(m_projectName); + m_projectSettingsMenuButton->setMenu(newProjectMenu); + m_projectSettingsMenuButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); + m_projectSettingsMenuButton->setStyleSheet("font-size: 14px; text-align:left;"); + vLayout->addWidget(m_projectSettingsMenuButton); + + setFixedSize(s_projectImageWidth, s_projectImageHeight + m_projectSettingsMenuButton->height()); + + connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); }); + connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); }); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectName); }); + connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectName); }); + connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectName); }); + connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectName); }); +#endif + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h new file mode 100644 index 0000000000..c1aee8e63e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h @@ -0,0 +1,73 @@ +/* + * 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 +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QPixmap) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QAction) + +namespace O3DE::ProjectManager +{ + class LabelButton + : public QLabel + { + Q_OBJECT // AUTOMOC + + public: + explicit LabelButton(QWidget* parent = nullptr); + ~LabelButton() = default; + + signals: + void triggered(); + + public slots: + void mousePressEvent(QMouseEvent* event) override; + }; + + class ProjectButton + : public QFrame + { + Q_OBJECT // AUTOMOC + + public: + explicit ProjectButton(const QString& projectName, QWidget* parent = nullptr); + explicit ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent = nullptr); + ~ProjectButton() = default; + + signals: + void OpenProject(const QString& projectName); + void EditProject(const QString& projectName); + void EditProjectGems(const QString& projectName); + void CopyProject(const QString& projectName); + void RemoveProject(const QString& projectName); + void DeleteProject(const QString& projectName); + + private: + void Setup(); + + QString m_projectName; + QString m_projectImagePath; + LabelButton* m_projectImageLabel; + QPushButton* m_projectSettingsMenuButton; + QAction* m_editProjectAction; + QAction* m_editProjectGemsAction; + QAction* m_copyProjectAction; + QAction* m_removeProjectAction; + QAction* m_deleteProjectAction; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp index 4136b9eb8c..eb79f2da1e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp @@ -50,9 +50,9 @@ namespace O3DE::ProjectManager QVector screenEnums = { ProjectManagerScreen::FirstTimeUse, - ProjectManagerScreen::NewProjectSettingsCore, + ProjectManagerScreen::CreateProject, ProjectManagerScreen::ProjectsHome, - ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::UpdateProject, ProjectManagerScreen::EngineSettings }; m_screensCtrl->BuildScreens(screenEnums); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp index 52fca439b4..76aa1d2897 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp @@ -30,6 +30,23 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::ProjectSettings; } + ProjectInfo ProjectSettingsScreen::GetProjectInfo() + { + // Impl pending next PR + return ProjectInfo(); + } + + void ProjectSettingsScreen::SetProjectInfo() + { + // Impl pending next PR + } + + bool ProjectSettingsScreen::Validate() + { + // Impl pending next PR + return true; + } + void ProjectSettingsScreen::HandleGemsButton() { emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h index 1ec1b46f44..a4cafcd93a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h @@ -13,6 +13,7 @@ #if !defined(Q_MOC_RUN) #include +#include #endif namespace Ui @@ -30,6 +31,11 @@ namespace O3DE::ProjectManager ~ProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; + ProjectInfo GetProjectInfo(); + void SetProjectInfo(); + + bool Validate(); + protected slots: void HandleGemsButton(); diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp index 539f79b017..411b46c55d 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp @@ -12,21 +12,103 @@ #include -#include - +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace O3DE::ProjectManager { ProjectsHomeScreen::ProjectsHomeScreen(QWidget* parent) : ScreenWidget(parent) - , m_ui(new Ui::ProjectsHomeClass()) { - m_ui->setupUi(this); + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins); - 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); + QHBoxLayout* topLayout = new QHBoxLayout(); + + QLabel* titleLabel = new QLabel(this); + titleLabel->setText("My Projects"); + titleLabel->setStyleSheet("font-size: 24px"); + topLayout->addWidget(titleLabel); + + QSpacerItem* topSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum); + topLayout->addItem(topSpacer); + + QMenu* newProjectMenu = new QMenu(this); + m_createNewProjectAction = newProjectMenu->addAction("Create New Project"); + m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project"); + + QPushButton* newProjectMenuButton = new QPushButton(this); + newProjectMenuButton->setText("New Project..."); + newProjectMenuButton->setMenu(newProjectMenu); + newProjectMenuButton->setFixedWidth(s_newProjectButtonWidth); + newProjectMenuButton->setStyleSheet("font-size: 14px;"); + topLayout->addWidget(newProjectMenuButton); + + vLayout->addLayout(topLayout); + + // Get all projects and create a horizontal scrolling list of them + auto projectsResult = PythonBindingsInterface::Get()->GetProjects(); + if (projectsResult.IsSuccess() && !projectsResult.GetValue().isEmpty()) + { + QScrollArea* projectsScrollArea = new QScrollArea(this); + QWidget* scrollWidget = new QWidget(); + QGridLayout* projectGridLayout = new QGridLayout(); + scrollWidget->setLayout(projectGridLayout); + projectsScrollArea->setWidget(scrollWidget); + projectsScrollArea->setWidgetResizable(true); + + int gridIndex = 0; + for (auto project : projectsResult.GetValue()) + { + ProjectButton* projectButton; + QString projectPreviewPath = project.m_path + m_projectPreviewImagePath; + QFileInfo doesPreviewExist(projectPreviewPath); + if (doesPreviewExist.exists() && doesPreviewExist.isFile()) + { + projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this); + } + else + { + projectButton = new ProjectButton(project.m_projectName, this); + } + + // Create rows of projects buttons s_projectButtonRowCount buttons wide + projectGridLayout->addWidget(projectButton, gridIndex / s_projectButtonRowCount, gridIndex % s_projectButtonRowCount); + + connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsHomeScreen::HandleOpenProject); + connect(projectButton, &ProjectButton::EditProject, this, &ProjectsHomeScreen::HandleEditProject); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsHomeScreen::HandleEditProjectGems); + connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsHomeScreen::HandleCopyProject); + connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsHomeScreen::HandleRemoveProject); + connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsHomeScreen::HandleDeleteProject); +#endif + ++gridIndex; + } + + vLayout->addWidget(projectsScrollArea); + } + + // Using border-image allows for scaling options background-image does not support + setStyleSheet("O3DE--ProjectManager--ScreenWidget { border-image: url(:/Backgrounds/FirstTimeBackgroundImage.jpg) repeat repeat; }"); + + connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleNewProjectButton); + connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleAddProjectButton); } ProjectManagerScreen ProjectsHomeScreen::GetScreenEnum() @@ -36,16 +118,41 @@ namespace O3DE::ProjectManager void ProjectsHomeScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void ProjectsHomeScreen::HandleAddProjectButton() { // Do nothing for now } - void ProjectsHomeScreen::HandleEditProjectButton() + void ProjectsHomeScreen::HandleOpenProject(const QString& projectPath) { - emit ChangeScreenRequest(ProjectManagerScreen::ProjectSettings); + // Open the editor with this project open + emit NotifyCurrentProject(projectPath); + } + void ProjectsHomeScreen::HandleEditProject(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ResetScreenRequest(ProjectManagerScreen::UpdateProject); + emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject); + } + void ProjectsHomeScreen::HandleEditProjectGems(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); + } + void ProjectsHomeScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath) + { + // Open file dialog and choose location for copied project then register copy with O3DE + } + void ProjectsHomeScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath) + { + // Unregister Project from O3DE + } + void ProjectsHomeScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath) + { + // Remove project from 03DE and delete from disk + ProjectsHomeScreen::HandleRemoveProject(projectPath); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h index 9fd5919d2d..e8d1ac4fb5 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h @@ -15,11 +15,6 @@ #include #endif -namespace Ui -{ - class ProjectsHomeClass; -} - namespace O3DE::ProjectManager { class ProjectsHomeScreen @@ -34,10 +29,23 @@ namespace O3DE::ProjectManager protected slots: void HandleNewProjectButton(); void HandleAddProjectButton(); - void HandleEditProjectButton(); + void HandleOpenProject(const QString& projectPath); + void HandleEditProject(const QString& projectPath); + void HandleEditProjectGems(const QString& projectPath); + void HandleCopyProject(const QString& projectPath); + void HandleRemoveProject(const QString& projectPath); + void HandleDeleteProject(const QString& projectPath); private: - QScopedPointer m_ui; + QAction* m_createNewProjectAction; + QAction* m_addExistingProjectAction; + + const QString m_projectPreviewImagePath = "/preview.png"; + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_projectButtonRowCount = 4; + inline constexpr static int s_newProjectButtonWidth = 156; + }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui deleted file mode 100644 index 2ba93ccf90..0000000000 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui +++ /dev/null @@ -1,137 +0,0 @@ - - - ProjectsHomeClass - - - - 0 - 0 - 826 - 585 - - - - Form - - - - - - My Projects - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - :/Add.svg:/Add.svg - - - - - - - - 0 - 0 - - - - - - - - :/Select_Folder.svg:/Select_Folder.svg - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - Edit Project - - - - - - - Open a Project - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 9a5e82dafb..8c79a153c8 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -540,7 +540,8 @@ namespace O3DE::ProjectManager ProjectInfo PythonBindings::ProjectInfoFromPath(pybind11::handle path) { ProjectInfo projectInfo; - projectInfo.m_path = Py_To_String(path); + projectInfo.m_path = Py_To_String(path); + projectInfo.m_isNew = false; auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path); if (pybind11::isinstance(projectData)) diff --git a/Code/Tools/ProjectManager/Source/ScreenDefs.h b/Code/Tools/ProjectManager/Source/ScreenDefs.h index 658b8d88fd..13289e2481 100644 --- a/Code/Tools/ProjectManager/Source/ScreenDefs.h +++ b/Code/Tools/ProjectManager/Source/ScreenDefs.h @@ -18,10 +18,11 @@ namespace O3DE::ProjectManager Invalid = -1, Empty, FirstTimeUse, - NewProjectSettingsCore, + CreateProject, NewProjectSettings, GemCatalog, ProjectsHome, + UpdateProject, ProjectSettings, EngineSettings }; diff --git a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp index 1089f8ee94..d37ccdb59f 100644 --- a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp +++ b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include #include #include @@ -30,8 +31,8 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::FirstTimeUse): newScreen = new FirstTimeUseScreen(parent); break; - case (ProjectManagerScreen::NewProjectSettingsCore): - newScreen = new ProjectSettingsCtrl(parent); + case (ProjectManagerScreen::CreateProject): + newScreen = new CreateProjectCtrl(parent); break; case (ProjectManagerScreen::NewProjectSettings): newScreen = new NewProjectSettingsScreen(parent); @@ -42,6 +43,9 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::ProjectsHome): newScreen = new ProjectsHomeScreen(parent); break; + case (ProjectManagerScreen::UpdateProject): + newScreen = new UpdateProjectCtrl(parent); + break; case (ProjectManagerScreen::ProjectSettings): newScreen = new ProjectSettingsScreen(parent); break; diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index 483066e031..e80747d67b 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -41,15 +41,12 @@ namespace O3DE::ProjectManager { return true; } - virtual QString GetNextButtonText() - { - return "Next"; - } signals: void ChangeScreenRequest(ProjectManagerScreen screen); void GotoPreviousScreenRequest(); void ResetScreenRequest(ProjectManagerScreen screen); + void NotifyCurrentProject(const QString& projectPath); }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp index b8a38ed155..a77c434026 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp @@ -117,6 +117,7 @@ namespace O3DE::ProjectManager connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen); connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen); connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen); + connect(newScreen, &ScreenWidget::NotifyCurrentProject, this, &ScreensCtrl::NotifyCurrentProject); } void ScreensCtrl::ResetAllScreens() diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h index 7912a314e3..a9d1023b4b 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h @@ -35,6 +35,9 @@ namespace O3DE::ProjectManager ScreenWidget* FindScreen(ProjectManagerScreen screen); ScreenWidget* GetCurrentScreen(); + signals: + void NotifyCurrentProject(const QString& projectPath); + public slots: bool ChangeToScreen(ProjectManagerScreen screen); bool ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit = true); diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp new file mode 100644 index 0000000000..84e3d8359d --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -0,0 +1,139 @@ +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + UpdateProjectCtrl::UpdateProjectCtrl(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(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); + + connect(m_backButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleNextButton); + connect(reinterpret_cast(parent), &ScreensCtrl::NotifyCurrentProject, this, &UpdateProjectCtrl::UpdateCurrentProject); + + m_screensOrder = + { + ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::GemCatalog + }; + m_screensCtrl->BuildScreens(m_screensOrder); + m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::ProjectSettings, false); + + UpdateNextButtonText(); + + } + + ProjectManagerScreen UpdateProjectCtrl::GetScreenEnum() + { + return ProjectManagerScreen::UpdateProject; + } + + void UpdateProjectCtrl::HandleBackButton() + { + if (!m_screensCtrl->GotoPreviousScreen()) + { + emit GotoPreviousScreenRequest(); + } + else + { + UpdateNextButtonText(); + } + } + void UpdateProjectCtrl::HandleNextButton() + { + ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); + ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); + auto screenOrderIter = m_screensOrder.begin(); + for (; screenOrderIter != m_screensOrder.end(); ++screenOrderIter) + { + if (*screenOrderIter == screenEnum) + { + ++screenOrderIter; + break; + } + } + + if (screenEnum == ProjectManagerScreen::ProjectSettings) + { + auto projectScreen = reinterpret_cast(currentScreen); + if (projectScreen) + { + if (!projectScreen->Validate()) + { + QMessageBox::critical(this, tr("Invalid project settings"), tr("Invalid project settings")); + return; + } + + m_projectInfo = projectScreen->GetProjectInfo(); + } + } + + if (screenOrderIter != m_screensOrder.end()) + { + m_screensCtrl->ChangeToScreen(*screenOrderIter); + UpdateNextButtonText(); + } + else + { + auto result = PythonBindingsInterface::Get()->UpdateProject(m_projectInfo); + if (result) + { + emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome); + } + else + { + QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project.")); + } + } + } + + void UpdateProjectCtrl::UpdateCurrentProject(const QString& projectPath) + { + auto projectResult = PythonBindingsInterface::Get()->GetProject(projectPath); + if (projectResult.IsSuccess()) + { + m_projectInfo = projectResult.GetValue(); + } + } + + void UpdateProjectCtrl::UpdateNextButtonText() + { + QString nextButtonText = tr("Continue"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Update Project"); + } + m_nextButton->setText(nextButtonText); + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h new file mode 100644 index 0000000000..ee871e7bb2 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h @@ -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. + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include "ProjectInfo.h" +#include +#include +#include +#endif + + +namespace O3DE::ProjectManager +{ + class UpdateProjectCtrl + : public ScreenWidget + { + public: + explicit UpdateProjectCtrl(QWidget* parent = nullptr); + ~UpdateProjectCtrl() = default; + ProjectManagerScreen GetScreenEnum() override; + + + protected slots: + void HandleBackButton(); + void HandleNextButton(); + void UpdateCurrentProject(const QString& projectPath); + + private: + void UpdateNextButtonText(); + + ScreensCtrl* m_screensCtrl; + QPushButton* m_backButton; + QPushButton* m_nextButton; + QVector m_screensOrder; + + ProjectInfo m_projectInfo; + + ProjectManagerScreen m_screenEnum; + }; + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 16bc8cf965..5fd2b4a9d8 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -41,16 +41,19 @@ set(FILES Source/ProjectInfo.cpp Source/NewProjectSettingsScreen.h Source/NewProjectSettingsScreen.cpp - Source/ProjectSettingsCtrl.h - Source/ProjectSettingsCtrl.cpp + Source/CreateProjectCtrl.h + Source/CreateProjectCtrl.cpp + Source/UpdateProjectCtrl.h + Source/UpdateProjectCtrl.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/ProjectButtonWidget.h + Source/ProjectButtonWidget.cpp Source/LinkWidget.h Source/LinkWidget.cpp Source/TagWidget.h