Merge branch 'main' into ly-as-sdk/LYN-2948

This commit is contained in:
phistere
2021-05-16 11:51:00 -05:00
549 changed files with 5207 additions and 43781 deletions
@@ -0,0 +1,21 @@
/*
* 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 "EngineInfo.h"
namespace O3DE::ProjectManager
{
EngineInfo::EngineInfo(const QString& path)
: m_path(path)
{
}
} // namespace O3DE::ProjectManager
@@ -0,0 +1,29 @@
/*
* 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 <QString>
#endif
namespace O3DE::ProjectManager
{
class EngineInfo
{
public:
EngineInfo() = default;
EngineInfo(const QString& path);
QString m_path;
};
} // namespace O3DE::ProjectManager
@@ -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
@@ -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;
@@ -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
@@ -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
@@ -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();
@@ -10,16 +10,16 @@
*
*/
#include <GemCatalog/GemCatalog.h>
#include <QDialogButtonBox>
#include <GemCatalog/GemCatalogScreen.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <PythonBindingsInterface.h>
namespace O3DE::ProjectManager
{
GemCatalog::GemCatalog(ProjectManagerWindow* window)
: ScreenWidget(window)
GemCatalogScreen::GemCatalogScreen(QWidget* parent)
: ScreenWidget(parent)
{
m_gemModel = new GemModel(this);
@@ -40,15 +40,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",
@@ -88,14 +79,23 @@ namespace O3DE::ProjectManager
false));
}
// End: Temporary gem test data
auto result = PythonBindingsInterface::Get()->GetGems();
if (result.IsSuccess())
{
for (auto gemInfo : result.GetValue())
{
m_gemModel->AddGem(gemInfo);
}
}
}
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
@@ -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;
@@ -22,4 +22,10 @@ namespace O3DE::ProjectManager
, m_isAdded(isAdded)
{
}
bool GemInfo::IsValid() const
{
return !m_path.isEmpty() && !m_uuid.IsNull();
}
} // namespace O3DE::ProjectManager
@@ -35,8 +35,11 @@ namespace O3DE::ProjectManager
};
Q_DECLARE_FLAGS(Platforms, Platform)
GemInfo() = default;
GemInfo(const QString& name, const QString& creator, const QString& summary, Platforms platforms, bool isAdded);
bool IsValid() const;
QString m_path;
QString m_name;
QString m_displayName;
@@ -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
@@ -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>
@@ -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
@@ -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
@@ -14,11 +14,20 @@
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)
{
}
bool ProjectInfo::IsValid() const
{
return !m_path.isEmpty() && !m_projectId.IsNull();
}
} // namespace O3DE::ProjectManager
+12 -2
View File
@@ -23,14 +23,24 @@ 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);
bool IsValid() const;
// 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
@@ -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
@@ -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;
};
@@ -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">
@@ -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
@@ -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
@@ -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
@@ -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 +1,26 @@
/*
* 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 "ProjectTemplateInfo.h"
namespace O3DE::ProjectManager
{
ProjectTemplateInfo::ProjectTemplateInfo(const QString& path)
: m_path(path)
{
}
bool ProjectTemplateInfo::IsValid() const
{
return !m_path.isEmpty() && !m_name.isEmpty();
}
} // namespace O3DE::ProjectManager
@@ -0,0 +1,37 @@
/*
* 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 <QString>
#include <QStringList>
#endif
namespace O3DE::ProjectManager
{
class ProjectTemplateInfo
{
public:
ProjectTemplateInfo() = default;
ProjectTemplateInfo(const QString& path);
bool IsValid() const;
QString m_displayName;
QString m_name;
QString m_path;
QString m_summary;
QStringList m_canonicalTags;
QStringList m_userTags;
};
} // namespace O3DE::ProjectManager
@@ -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
@@ -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
@@ -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();
@@ -12,12 +12,11 @@
#include <PythonBindings.h>
// Qt defines slots, which interferes with the use here.
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#include <pybind11/functional.h>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>
#include <pybind11/eval.h>
#pragma pop_macro("slots")
@@ -51,6 +50,9 @@ namespace Platform
} // namespace Platform
#define Py_To_String(obj) obj.cast<std::string>().c_str()
#define Py_To_String_Optional(dict, key, default_string) dict.contains(key) ? Py_To_String(dict[key]) : default_string
namespace O3DE::ProjectManager
{
PythonBindings::PythonBindings(const AZ::IO::PathView& enginePath)
@@ -109,10 +111,13 @@ namespace O3DE::ProjectManager
result = PyRun_SimpleString(AZStd::string::format("sys.path.append('%s')", m_enginePath.c_str()).c_str());
AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed");
// import required modules
m_registration = pybind11::module::import("cmake.Tools.registration");
return result == 0 && !PyErr_Occurred();
} catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning("python", false, "Py_Initialize() failed with %s", e.what());
AZ_Warning("ProjectManagerWindow", false, "Py_Initialize() failed with %s", e.what());
return false;
}
}
@@ -125,31 +130,256 @@ namespace O3DE::ProjectManager
}
else
{
AZ_Warning("python", false, "Did not finalize since Py_IsInitialized() was false");
AZ_Warning("ProjectManagerWindow", false, "Did not finalize since Py_IsInitialized() was false");
}
return !PyErr_Occurred();
}
void PythonBindings::ExecuteWithLock(AZStd::function<void()> executionCallback)
bool PythonBindings::ExecuteWithLock(AZStd::function<void()> executionCallback)
{
AZStd::lock_guard<decltype(m_lock)> lock(m_lock);
pybind11::gil_scoped_release release;
pybind11::gil_scoped_acquire acquire;
executionCallback();
try
{
executionCallback();
return true;
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning("PythonBindings", false, "Python exception %s", e.what());
return false;
}
}
ProjectInfo PythonBindings::GetCurrentProject()
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
{
ProjectInfo project;
return AZ::Failure();
}
ExecuteWithLock([&] {
auto currentProjectTool = pybind11::module::import("cmake.Tools.current_project");
auto getCurrentProject = currentProjectTool.attr("get_current_project");
auto currentProject = getCurrentProject(m_enginePath.c_str());
bool PythonBindings::SetEngineInfo([[maybe_unused]] const EngineInfo& engineInfo)
{
return false;
}
project.m_path = currentProject.cast<std::string>().c_str();
AZ::Outcome<GemInfo> PythonBindings::GetGem(const QString& path)
{
GemInfo gemInfo = GemInfoFromPath(pybind11::str(path.toStdString()));
if (gemInfo.IsValid())
{
return AZ::Success(AZStd::move(gemInfo));
}
else
{
return AZ::Failure();
}
}
AZ::Outcome<QVector<GemInfo>> PythonBindings::GetGems()
{
QVector<GemInfo> gems;
bool result = ExecuteWithLock([&] {
// external gems
for (auto path : m_registration.attr("get_gems")())
{
gems.push_back(GemInfoFromPath(path));
}
// gems from the engine
for (auto path : m_registration.attr("get_engine_gems")())
{
gems.push_back(GemInfoFromPath(path));
}
});
return project;
if (!result)
{
return AZ::Failure();
}
else
{
return AZ::Success(AZStd::move(gems));
}
}
AZ::Outcome<ProjectInfo> PythonBindings::CreateProject([[maybe_unused]] const ProjectTemplateInfo& projectTemplate,[[maybe_unused]] const ProjectInfo& projectInfo)
{
return AZ::Failure();
}
AZ::Outcome<ProjectInfo> PythonBindings::GetProject(const QString& path)
{
ProjectInfo projectInfo = ProjectInfoFromPath(pybind11::str(path.toStdString()));
if (projectInfo.IsValid())
{
return AZ::Success(AZStd::move(projectInfo));
}
else
{
return AZ::Failure();
}
}
GemInfo PythonBindings::GemInfoFromPath(pybind11::handle path)
{
GemInfo gemInfo;
gemInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_gem_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
{
// required
gemInfo.m_name = Py_To_String(data["Name"]);
gemInfo.m_uuid = AZ::Uuid(Py_To_String(data["Uuid"]));
// optional
gemInfo.m_displayName = Py_To_String_Optional(data, "DisplayName", gemInfo.m_name);
gemInfo.m_summary = Py_To_String_Optional(data, "Summary", "");
gemInfo.m_version = Py_To_String_Optional(data, "Version", "");
if (data.contains("Dependencies"))
{
for (auto dependency : data["Dependencies"])
{
gemInfo.m_dependingGemUuids.push_back(AZ::Uuid(Py_To_String(dependency["Uuid"])));
}
}
if (data.contains("Tags"))
{
for (auto tag : data["Tags"])
{
gemInfo.m_features.push_back(Py_To_String(tag));
}
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning("PythonBindings", false, "Failed to get GemInfo for gem %s", Py_To_String(path));
}
}
return gemInfo;
}
ProjectInfo PythonBindings::ProjectInfoFromPath(pybind11::handle path)
{
ProjectInfo projectInfo;
projectInfo.m_path = Py_To_String(path);
auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(projectData))
{
try
{
// required fields
projectInfo.m_productName = Py_To_String(projectData["product_name"]);
projectInfo.m_projectName = Py_To_String(projectData["project_name"]);
projectInfo.m_projectId = AZ::Uuid(Py_To_String(projectData["project_id"]));
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning("PythonBindings", false, "Failed to get ProjectInfo for project %s", Py_To_String(path));
}
}
return projectInfo;
}
AZ::Outcome<QVector<ProjectInfo>> PythonBindings::GetProjects()
{
QVector<ProjectInfo> projects;
bool result = ExecuteWithLock([&] {
// external projects
for (auto path : m_registration.attr("get_projects")())
{
projects.push_back(ProjectInfoFromPath(path));
}
// projects from the engine
for (auto path : m_registration.attr("get_engine_projects")())
{
projects.push_back(ProjectInfoFromPath(path));
}
});
if (!result)
{
return AZ::Failure();
}
else
{
return AZ::Success(AZStd::move(projects));
}
}
bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo)
{
return false;
}
ProjectTemplateInfo PythonBindings::ProjectTemplateInfoFromPath(pybind11::handle path)
{
ProjectTemplateInfo templateInfo;
templateInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_template_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
{
// required
templateInfo.m_displayName = Py_To_String(data["display_name"]);
templateInfo.m_name = Py_To_String(data["template_name"]);
templateInfo.m_summary = Py_To_String(data["summary"]);
// optional
if (data.contains("canonical_tags"))
{
for (auto tag : data["canonical_tags"])
{
templateInfo.m_canonicalTags.push_back(Py_To_String(tag));
}
}
if (data.contains("user_tags"))
{
for (auto tag : data["user_tags"])
{
templateInfo.m_canonicalTags.push_back(Py_To_String(tag));
}
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning("PythonBindings", false, "Failed to get ProjectTemplateInfo for %s", Py_To_String(path));
}
}
return templateInfo;
}
AZ::Outcome<QVector<ProjectTemplateInfo>> PythonBindings::GetProjectTemplates()
{
QVector<ProjectTemplateInfo> templates;
bool result = ExecuteWithLock([&] {
for (auto path : m_registration.attr("get_project_templates")())
{
templates.push_back(ProjectTemplateInfoFromPath(path));
}
});
if (!result)
{
return AZ::Failure();
}
else
{
return AZ::Success(AZStd::move(templates));
}
}
}
@@ -15,6 +15,14 @@
#include <AzCore/IO/Path/Path.h>
#include <AzCore/std/parallel/semaphore.h>
// Qt defines slots, which interferes with the use here.
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#include <pybind11/pybind11.h>
#pragma pop_macro("slots")
namespace O3DE::ProjectManager
{
class PythonBindings
@@ -26,16 +34,35 @@ namespace O3DE::ProjectManager
~PythonBindings() override;
// PythonBindings overrides
ProjectInfo GetCurrentProject() override;
// Engine
AZ::Outcome<EngineInfo> GetEngineInfo() override;
bool SetEngineInfo(const EngineInfo& engineInfo) override;
// Gem
AZ::Outcome<GemInfo> GetGem(const QString& path) override;
AZ::Outcome<QVector<GemInfo>> GetGems() override;
// Project
AZ::Outcome<ProjectInfo> CreateProject(const ProjectTemplateInfo& projectTemplate, const ProjectInfo& projectInfo) override;
AZ::Outcome<ProjectInfo> GetProject(const QString& path) override;
AZ::Outcome<QVector<ProjectInfo>> GetProjects() override;
bool UpdateProject(const ProjectInfo& projectInfo) override;
// ProjectTemplate
AZ::Outcome<QVector<ProjectTemplateInfo>> GetProjectTemplates() override;
private:
AZ_DISABLE_COPY_MOVE(PythonBindings);
void ExecuteWithLock(AZStd::function<void()> executionCallback);
bool ExecuteWithLock(AZStd::function<void()> executionCallback);
GemInfo GemInfoFromPath(pybind11::handle path);
ProjectInfo ProjectInfoFromPath(pybind11::handle path);
ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path);
bool StartPython();
bool StopPython();
AZ::IO::FixedMaxPath m_enginePath;
AZStd::recursive_mutex m_lock;
pybind11::handle m_registration;
};
}
@@ -15,9 +15,12 @@
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/Outcome/Outcome.h>
#include <EngineInfo.h>
#include <GemCatalog/GemInfo.h>
#include <ProjectInfo.h>
#include <ProjectTemplateInfo.h>
namespace O3DE::ProjectManager
{
@@ -31,8 +34,76 @@ namespace O3DE::ProjectManager
IPythonBindings() = default;
virtual ~IPythonBindings() = default;
//! Get the current project
virtual ProjectInfo GetCurrentProject() = 0;
// Engine
/**
* Get info about the engine
* @return an outcome with EngineInfo on success
*/
virtual AZ::Outcome<EngineInfo> GetEngineInfo() = 0;
/**
* Set info about the engine
* @param engineInfo an EngineInfo object
*/
virtual bool SetEngineInfo(const EngineInfo& engineInfo) = 0;
// Gems
/**
* Get info about a Gem
* @param path the absolute path to the Gem
* @return an outcome with GemInfo on success
*/
virtual AZ::Outcome<GemInfo> GetGem(const QString& path) = 0;
/**
* Get info about all known Gems
* @return an outcome with GemInfos on success
*/
virtual AZ::Outcome<QVector<GemInfo>> GetGems() = 0;
// Projects
/**
* Create a project
* @param projectTemplate the project template to use
* @param projectInfo the project info to use
* @return an outcome with ProjectInfo on success
*/
virtual AZ::Outcome<ProjectInfo> CreateProject(const ProjectTemplateInfo& projectTemplate, const ProjectInfo& projectInfo) = 0;
/**
* Get info about a project
* @param path the absolute path to the project
* @return an outcome with ProjectInfo on success
*/
virtual AZ::Outcome<ProjectInfo> GetProject(const QString& path) = 0;
/**
* Get info about all known projects
* @return an outcome with ProjectInfos on success
*/
virtual AZ::Outcome<QVector<ProjectInfo>> GetProjects() = 0;
/**
* Update a project
* @param projectInfo the info to use to update the project
* @return true on success, false on failure
*/
virtual bool UpdateProject(const ProjectInfo& projectInfo) = 0;
// Project Templates
/**
* Get info about all known project templates
* @return an outcome with ProjectTemplateInfos on success
*/
virtual AZ::Outcome<QVector<ProjectTemplateInfo>> GetProjectTemplates() = 0;
};
using PythonBindingsInterface = AZ::Interface<IPythonBindings>;
@@ -13,9 +13,12 @@
namespace O3DE::ProjectManager
{
enum class ProjectManagerScreen
enum ProjectManagerScreen
{
Invalid = -1,
Empty,
FirstTimeUse,
NewProjectSettingsCore,
NewProjectSettings,
GemCatalog,
ProjectsHome,
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -15,36 +15,43 @@ 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/EngineInfo.h
Source/EngineInfo.cpp
Source/FirstTimeUseScreen.h
Source/FirstTimeUseScreen.cpp
Source/FirstTimeUseScreen.ui
Source/ProjectManagerWindow.h
Source/ProjectManagerWindow.cpp
Source/ProjectTemplateInfo.h
Source/ProjectTemplateInfo.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