Merge branch 'main' of https://github.com/aws-lumberyard/o3de into prism/LYN-2514

# Conflicts:
#	Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp
main
Benjamin Jillich 5 years ago
commit 1b96fc4361

@ -177,6 +177,11 @@ ly_add_target(
Legacy::EditorLib
ProjectManager
)
set_property(SOURCE
CryEdit.cpp
APPEND PROPERTY
COMPILE_DEFINITIONS LY_CMAKE_TARGET="Editor"
)
ly_add_translations(
TARGETS Editor
PREFIX Translations
@ -186,15 +191,8 @@ ly_add_translations(
)
ly_add_dependencies(Editor AssetProcessor)
if(TARGET Editor)
set_property(SOURCE
CryEdit.cpp
APPEND PROPERTY
COMPILE_DEFINITIONS LY_CMAKE_TARGET="Editor"
)
else()
message(FATAL_ERROR "Cannot set LY_CMAKE_TARGET define to Editor as the target doesn't exist anymore."
" Perhaps it has been renamed")
if(LY_FIRST_PROJECT_PATH)
set_property(TARGET Editor APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_FIRST_PROJECT_PATH}\"")
endif()
################################################################################

@ -125,6 +125,10 @@ ly_add_target(
AZ::AssetProcessorBatch.Static
)
if(LY_FIRST_PROJECT_PATH)
set_property(TARGET AssetProcessor AssetProcessorBatch APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_FIRST_PROJECT_PATH}\"")
endif()
# Adds the AssetProcessorBatch target as a C preprocessor define so that it can be used as a Settings Registry
# specialization in order to look up the generated .setreg which contains the dependencies
# specified for the target.

@ -25,7 +25,6 @@ ly_add_target(
OUTPUT_NAME o3de
NAMESPACE AZ
AUTOMOC
AUTOUIC
AUTORCC
FILES_CMAKE
project_manager_files.cmake

@ -232,6 +232,18 @@ QTabBar::tab:pressed
margin-left:30px;
}
#projectSettingsTab::tab-bar {
left: 60px;
}
#projectSettingsTabBar::tab {
height:50px;
}
#projectSettingsTopFrame {
background-color:#1E252F;
}
/************** Projects **************/
#firstTimeContent > #titleLabel {
font-size:60px;

@ -34,33 +34,13 @@ namespace O3DE::ProjectManager
constexpr const char* k_pathProperty = "Path";
NewProjectSettingsScreen::NewProjectSettingsScreen(QWidget* parent)
: ScreenWidget(parent)
{
QHBoxLayout* hLayout = new QHBoxLayout(this);
hLayout->setAlignment(Qt::AlignLeft);
hLayout->setContentsMargins(0,0,0,0);
// if we don't provide a parent for this box layout the stylesheet doesn't take
// if we don't set this in a frame (just use a sub-layout) all the content will align incorrectly horizontally
QFrame* projectSettingsFrame = new QFrame(this);
projectSettingsFrame->setObjectName("projectSettings");
QVBoxLayout* vLayout = new QVBoxLayout(this);
// you cannot remove content margins in qss
vLayout->setContentsMargins(0,0,0,0);
vLayout->setAlignment(Qt::AlignTop);
: ProjectSettingsScreen(parent)
{
const QString defaultName{ "NewProject" };
const QString defaultPath = QDir::toNativeSeparators(GetDefaultProjectPath() + "/" + defaultName);
m_projectName = new FormLineEditWidget(tr("Project name"), defaultName, this);
connect(m_projectName->lineEdit(), &QLineEdit::textChanged, this, &NewProjectSettingsScreen::ValidateProjectPath);
vLayout->addWidget(m_projectName);
m_projectPath = new FormBrowseEditWidget(tr("Project Location"), defaultPath, this);
m_projectPath->lineEdit()->setReadOnly(true);
connect(m_projectPath->lineEdit(), &QLineEdit::textChanged, this, &NewProjectSettingsScreen::ValidateProjectPath);
vLayout->addWidget(m_projectPath);
m_projectName->lineEdit()->setText(defaultName);
m_projectPath->lineEdit()->setText(defaultPath);
// if we don't use a QFrame we cannot "contain" the widgets inside and move them around
// as a group
@ -87,7 +67,7 @@ namespace O3DE::ProjectManager
auto templatesResult = PythonBindingsInterface::Get()->GetProjectTemplates();
if (templatesResult.IsSuccess() && !templatesResult.GetValue().isEmpty())
{
for (auto projectTemplate : templatesResult.GetValue())
for (const ProjectTemplateInfo& projectTemplate : templatesResult.GetValue())
{
QRadioButton* radioButton = new QRadioButton(projectTemplate.m_name, this);
radioButton->setProperty(k_pathProperty, projectTemplate.m_path);
@ -100,17 +80,11 @@ namespace O3DE::ProjectManager
}
}
projectTemplateWidget->setLayout(containerLayout);
vLayout->addWidget(projectTemplateWidget);
}
projectSettingsFrame->setLayout(vLayout);
hLayout->addWidget(projectSettingsFrame);
m_verticalLayout->addWidget(projectTemplateWidget);
QWidget* projectTemplateDetails = new QWidget(this);
projectTemplateDetails->setObjectName("projectTemplateDetails");
hLayout->addWidget(projectTemplateDetails);
this->setLayout(hLayout);
m_horizontalLayout->addWidget(projectTemplateDetails);
}
QString NewProjectSettingsScreen::GetDefaultProjectPath()
@ -133,69 +107,13 @@ namespace O3DE::ProjectManager
return ProjectManagerScreen::NewProjectSettings;
}
void NewProjectSettingsScreen::ValidateProjectPath()
{
Validate();
}
void NewProjectSettingsScreen::NotifyCurrentScreen()
{
Validate();
}
ProjectInfo NewProjectSettingsScreen::GetProjectInfo()
{
ProjectInfo projectInfo;
projectInfo.m_projectName = m_projectName->lineEdit()->text();
projectInfo.m_path = m_projectPath->lineEdit()->text();
return projectInfo;
}
QString NewProjectSettingsScreen::GetProjectTemplatePath()
{
return m_projectTemplateButtonGroup->checkedButton()->property(k_pathProperty).toString();
}
bool NewProjectSettingsScreen::Validate()
{
bool projectPathIsValid = true;
if (m_projectPath->lineEdit()->text().isEmpty())
{
projectPathIsValid = false;
m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
}
else
{
QDir path(m_projectPath->lineEdit()->text());
if (path.exists() && !path.isEmpty())
{
projectPathIsValid = false;
m_projectPath->setErrorLabelText(tr("This folder exists and isn't empty. Please choose a different location."));
}
}
bool projectNameIsValid = true;
if (m_projectName->lineEdit()->text().isEmpty())
{
projectNameIsValid = false;
m_projectName->setErrorLabelText(tr("Please provide a project name."));
}
else
{
// this validation should roughly match the utils.validate_identifier which the cli
// uses to validate project names
QRegExp validProjectNameRegex("[A-Za-z][A-Za-z0-9_-]{0,63}");
const bool result = validProjectNameRegex.exactMatch(m_projectName->lineEdit()->text());
if (!result)
{
projectNameIsValid = false;
m_projectName->setErrorLabelText(tr("Project names must start with a letter and consist of up to 64 letter, number, '_' or '-' characters"));
}
}
m_projectName->setErrorLabelVisible(!projectNameIsValid);
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
return projectNameIsValid && projectPathIsValid;
}
} // namespace O3DE::ProjectManager

@ -12,41 +12,28 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <ScreenWidget.h>
#include <ProjectInfo.h>
#include <ProjectSettingsScreen.h>
#endif
QT_FORWARD_DECLARE_CLASS(QButtonGroup)
namespace O3DE::ProjectManager
{
QT_FORWARD_DECLARE_CLASS(FormLineEditWidget)
QT_FORWARD_DECLARE_CLASS(FormBrowseEditWidget)
class NewProjectSettingsScreen
: public ScreenWidget
: public ProjectSettingsScreen
{
public:
explicit NewProjectSettingsScreen(QWidget* parent = nullptr);
~NewProjectSettingsScreen() = default;
ProjectManagerScreen GetScreenEnum() override;
ProjectInfo GetProjectInfo();
QString GetProjectTemplatePath();
bool Validate();
void NotifyCurrentScreen() override;
protected slots:
void HandleBrowseButton();
void ValidateProjectPath();
private:
QString GetDefaultProjectPath();
FormLineEditWidget* m_projectName;
FormBrowseEditWidget* m_projectPath;
QButtonGroup* m_projectTemplateButtonGroup;
};

@ -22,8 +22,6 @@
#include <QMenu>
#include <QSpacerItem>
//#define SHOW_ALL_PROJECT_ACTIONS
namespace O3DE::ProjectManager
{
inline constexpr static int s_projectImageWidth = 210;
@ -96,10 +94,6 @@ namespace O3DE::ProjectManager
m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE"));
m_deleteProjectAction = newProjectMenu->addAction(tr("Delete this Project"));
#ifdef SHOW_ALL_PROJECT_ACTIONS
m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems..."));
#endif
QFrame* footer = new QFrame(this);
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->setContentsMargins(0, 0, 0, 0);
@ -121,10 +115,6 @@ namespace O3DE::ProjectManager
connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectInfo.m_path); });
connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectInfo.m_path); });
connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectInfo.m_path); });
#ifdef SHOW_ALL_PROJECT_ACTIONS
connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
#endif
}
void ProjectButton::SetButtonEnabled(bool enabled)

@ -62,7 +62,6 @@ namespace O3DE::ProjectManager
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);
@ -73,7 +72,6 @@ namespace O3DE::ProjectManager
ProjectInfo m_projectInfo;
LabelButton* m_projectImageLabel;
QAction* m_editProjectAction;
QAction* m_editProjectGemsAction;
QAction* m_copyProjectAction;
QAction* m_removeProjectAction;
QAction* m_deleteProjectAction;

@ -25,6 +25,19 @@ namespace O3DE::ProjectManager
{
}
bool ProjectInfo::operator==(const ProjectInfo& rhs)
{
return m_path == rhs.m_path
&& m_projectName == rhs.m_projectName
&& m_imagePath == rhs.m_imagePath
&& m_backgroundImagePath == rhs.m_backgroundImagePath;
}
bool ProjectInfo::operator!=(const ProjectInfo& rhs)
{
return !operator==(rhs);
}
bool ProjectInfo::IsValid() const
{
return !m_path.isEmpty() && !m_projectName.isEmpty();

@ -25,6 +25,8 @@ namespace O3DE::ProjectManager
ProjectInfo() = default;
ProjectInfo(const QString& path, const QString& projectName, const QString& displayName,
const QString& imagePath, const QString& backgroundImagePath, bool isNew);
bool operator==(const ProjectInfo& rhs);
bool operator!=(const ProjectInfo& rhs);
bool IsValid() const;

@ -11,45 +11,131 @@
*/
#include <ProjectSettingsScreen.h>
#include <FormBrowseEditWidget.h>
#include <FormLineEditWidget.h>
#include <PathValidator.h>
#include <PythonBindingsInterface.h>
#include <Source/ui_ProjectSettingsScreen.h>
#include <QFileDialog>
#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QStandardPaths>
namespace O3DE::ProjectManager
{
ProjectSettingsScreen::ProjectSettingsScreen(QWidget* parent)
: ScreenWidget(parent)
, m_ui(new Ui::ProjectSettingsClass())
{
m_ui->setupUi(this);
m_horizontalLayout = new QHBoxLayout(this);
m_horizontalLayout->setAlignment(Qt::AlignLeft);
m_horizontalLayout->setContentsMargins(0, 0, 0, 0);
connect(m_ui->gemsButton, &QPushButton::pressed, this, &ProjectSettingsScreen::HandleGemsButton);
// if we don't provide a parent for this box layout the stylesheet doesn't take
// if we don't set this in a frame (just use a sub-layout) all the content will align incorrectly horizontally
QFrame* projectSettingsFrame = new QFrame(this);
projectSettingsFrame->setObjectName("projectSettings");
m_verticalLayout = new QVBoxLayout(this);
// you cannot remove content margins in qss
m_verticalLayout->setContentsMargins(0, 0, 0, 0);
m_verticalLayout->setAlignment(Qt::AlignTop);
m_projectName = new FormLineEditWidget(tr("Project name"), "", this);
connect(m_projectName->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::ValidateProjectName);
m_verticalLayout->addWidget(m_projectName);
m_projectPath = new FormBrowseEditWidget(tr("Project Location"), "", this);
m_projectPath->lineEdit()->setReadOnly(true);
connect(m_projectPath->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::Validate);
m_verticalLayout->addWidget(m_projectPath);
projectSettingsFrame->setLayout(m_verticalLayout);
m_horizontalLayout->addWidget(projectSettingsFrame);
setLayout(m_horizontalLayout);
}
ProjectManagerScreen ProjectSettingsScreen::GetScreenEnum()
{
return ProjectManagerScreen::ProjectSettings;
return ProjectManagerScreen::Invalid;
}
ProjectInfo ProjectSettingsScreen::GetProjectInfo()
QString ProjectSettingsScreen::GetDefaultProjectPath()
{
QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
if (engineInfoResult.IsSuccess())
{
// Impl pending next PR
return ProjectInfo();
QDir path(QDir::toNativeSeparators(engineInfoResult.GetValue().m_defaultProjectsFolder));
if (path.exists())
{
defaultPath = path.absolutePath();
}
}
return defaultPath;
}
void ProjectSettingsScreen::SetProjectInfo()
ProjectInfo ProjectSettingsScreen::GetProjectInfo()
{
// Impl pending next PR
ProjectInfo projectInfo;
projectInfo.m_projectName = m_projectName->lineEdit()->text();
projectInfo.m_path = m_projectPath->lineEdit()->text();
return projectInfo;
}
bool ProjectSettingsScreen::Validate()
bool ProjectSettingsScreen::ValidateProjectName()
{
bool projectNameIsValid = true;
if (m_projectName->lineEdit()->text().isEmpty())
{
// Impl pending next PR
return true;
projectNameIsValid = false;
m_projectName->setErrorLabelText(tr("Please provide a project name."));
}
else
{
// this validation should roughly match the utils.validate_identifier which the cli
// uses to validate project names
QRegExp validProjectNameRegex("[A-Za-z][A-Za-z0-9_-]{0,63}");
const bool result = validProjectNameRegex.exactMatch(m_projectName->lineEdit()->text());
if (!result)
{
projectNameIsValid = false;
m_projectName->setErrorLabelText(
tr("Project names must start with a letter and consist of up to 64 letter, number, '_' or '-' characters"));
}
}
void ProjectSettingsScreen::HandleGemsButton()
m_projectName->setErrorLabelVisible(!projectNameIsValid);
return projectNameIsValid;
}
bool ProjectSettingsScreen::ValidateProjectPath()
{
bool projectPathIsValid = true;
if (m_projectPath->lineEdit()->text().isEmpty())
{
projectPathIsValid = false;
m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
}
else
{
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
QDir path(m_projectPath->lineEdit()->text());
if (path.exists() && !path.isEmpty())
{
projectPathIsValid = false;
m_projectPath->setErrorLabelText(tr("This folder exists and isn't empty. Please choose a different location."));
}
}
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
return projectPathIsValid;
}
bool ProjectSettingsScreen::Validate()
{
return ValidateProjectName() && ValidateProjectPath();
}
} // namespace O3DE::ProjectManager

@ -12,17 +12,18 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <ScreenWidget.h>
#include <ProjectInfo.h>
#include <ScreenWidget.h>
#endif
namespace Ui
{
class ProjectSettingsClass;
}
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
namespace O3DE::ProjectManager
{
QT_FORWARD_DECLARE_CLASS(FormLineEditWidget)
QT_FORWARD_DECLARE_CLASS(FormBrowseEditWidget)
class ProjectSettingsScreen
: public ScreenWidget
{
@ -32,15 +33,20 @@ namespace O3DE::ProjectManager
ProjectManagerScreen GetScreenEnum() override;
ProjectInfo GetProjectInfo();
void SetProjectInfo();
bool Validate();
protected slots:
void HandleGemsButton();
virtual bool ValidateProjectName();
virtual bool ValidateProjectPath();
protected:
QString GetDefaultProjectPath();
private:
QScopedPointer<Ui::ProjectSettingsClass> m_ui;
QHBoxLayout* m_horizontalLayout;
QVBoxLayout* m_verticalLayout;
FormLineEditWidget* m_projectName;
FormBrowseEditWidget* m_projectPath;
};
} // namespace O3DE::ProjectManager

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectSettingsClass</class>
<widget class="QWidget" name="ProjectSettingsClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>782</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="projectSettingsButton">
<property name="text">
<string>Project Settings</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="gemsButton">
<property name="text">
<string>Gems</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>761</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Project Name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Project Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Project Image Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_3"/>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Project Background Image Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_4"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -182,10 +182,6 @@ namespace O3DE::ProjectManager
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
#ifdef SHOW_ALL_PROJECT_ACTIONS
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
#endif
}
layout->addWidget(projectsScrollArea);
@ -293,14 +289,8 @@ namespace O3DE::ProjectManager
void ProjectsScreen::HandleEditProject(const QString& projectPath)
{
emit NotifyCurrentProject(projectPath);
emit ResetScreenRequest(ProjectManagerScreen::UpdateProject);
emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject);
}
void ProjectsScreen::HandleEditProjectGems(const QString& projectPath)
{
emit NotifyCurrentProject(projectPath);
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
}
void ProjectsScreen::HandleCopyProject(const QString& projectPath)
{
// Open file dialog and choose location for copied project then register copy with O3DE

@ -41,7 +41,6 @@ namespace O3DE::ProjectManager
void HandleAddProjectButton();
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);

@ -26,7 +26,7 @@ namespace O3DE::ProjectManager
GemCatalog,
Projects,
UpdateProject,
ProjectSettings,
UpdateProjectSettings,
EngineSettings
};
@ -37,7 +37,7 @@ namespace O3DE::ProjectManager
{ "GemCatalog", ProjectManagerScreen::GemCatalog},
{ "Projects", ProjectManagerScreen::Projects},
{ "UpdateProject", ProjectManagerScreen::UpdateProject},
{ "ProjectSettings", ProjectManagerScreen::ProjectSettings},
{ "UpdateProjectSettings", ProjectManagerScreen::UpdateProjectSettings},
{ "EngineSettings", ProjectManagerScreen::EngineSettings}
};

@ -16,7 +16,7 @@
#include <NewProjectSettingsScreen.h>
#include <GemCatalog/GemCatalogScreen.h>
#include <ProjectsScreen.h>
#include <ProjectSettingsScreen.h>
#include <UpdateProjectSettingsScreen.h>
#include <EngineSettingsScreen.h>
namespace O3DE::ProjectManager
@ -42,8 +42,8 @@ namespace O3DE::ProjectManager
case (ProjectManagerScreen::UpdateProject):
newScreen = new UpdateProjectCtrl(parent);
break;
case (ProjectManagerScreen::ProjectSettings):
newScreen = new ProjectSettingsScreen(parent);
case (ProjectManagerScreen::UpdateProjectSettings):
newScreen = new UpdateProjectSettingsScreen(parent);
break;
case (ProjectManagerScreen::EngineSettings):
newScreen = new EngineSettingsScreen(parent);

@ -13,6 +13,7 @@
#include <ScreensCtrl.h>
#include <ScreenFactory.h>
#include <ScreenWidget.h>
#include <UpdateProjectCtrl.h>
#include <QTabWidget>
#include <QVBoxLayout>

@ -10,16 +10,19 @@
*
*/
#include <UpdateProjectCtrl.h>
#include <ScreensCtrl.h>
#include <PythonBindingsInterface.h>
#include <ProjectSettingsScreen.h>
#include <GemCatalog/GemCatalogScreen.h>
#include <PythonBindingsInterface.h>
#include <ScreenHeaderWidget.h>
#include <ScreensCtrl.h>
#include <UpdateProjectCtrl.h>
#include <UpdateProjectSettingsScreen.h>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QPushButton>
#include <QStackedWidget>
#include <QTabWidget>
#include <QVBoxLayout>
namespace O3DE::ProjectManager
{
@ -27,32 +30,57 @@ namespace O3DE::ProjectManager
: ScreenWidget(parent)
{
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setMargin(0);
setLayout(vLayout);
vLayout->setContentsMargins(0, 0, 0, 0);
m_header = new ScreenHeader(this);
m_header->setTitle(tr(""));
m_header->setSubTitle(tr("Edit Project Settings:"));
connect(m_header->backButton(), &QPushButton::clicked, this, &UpdateProjectCtrl::HandleBackButton);
vLayout->addWidget(m_header);
m_updateSettingsScreen = new UpdateProjectSettingsScreen();
m_gemCatalogScreen = new GemCatalogScreen();
m_stack = new QStackedWidget(this);
m_stack->setObjectName("body");
m_stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
vLayout->addWidget(m_stack);
QFrame* topBarFrameWidget = new QFrame(this);
topBarFrameWidget->setObjectName("projectSettingsTopFrame");
QHBoxLayout* topBarHLayout = new QHBoxLayout();
topBarHLayout->setContentsMargins(0, 0, 0, 0);
topBarFrameWidget->setLayout(topBarHLayout);
QTabWidget* tabWidget = new QTabWidget();
tabWidget->setObjectName("projectSettingsTab");
tabWidget->tabBar()->setObjectName("projectSettingsTabBar");
tabWidget->addTab(m_updateSettingsScreen, tr("General"));
QPushButton* gemsButton = new QPushButton(tr("Add More Gems"), this);
topBarHLayout->addWidget(gemsButton);
tabWidget->setCornerWidget(gemsButton);
m_screensCtrl = new ScreensCtrl();
vLayout->addWidget(m_screensCtrl);
topBarHLayout->addWidget(tabWidget);
m_stack->addWidget(topBarFrameWidget);
m_stack->addWidget(m_gemCatalogScreen);
QDialogButtonBox* backNextButtons = new QDialogButtonBox();
backNextButtons->setObjectName("footer");
vLayout->addWidget(backNextButtons);
m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole);
m_backButton->setProperty("secondary", true);
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(gemsButton, &QPushButton::clicked, this, &UpdateProjectCtrl::HandleGemsButton);
connect(m_backButton, &QPushButton::clicked, this, &UpdateProjectCtrl::HandleBackButton);
connect(m_nextButton, &QPushButton::clicked, this, &UpdateProjectCtrl::HandleNextButton);
connect(reinterpret_cast<ScreensCtrl*>(parent), &ScreensCtrl::NotifyCurrentProject, this, &UpdateProjectCtrl::UpdateCurrentProject);
m_screensOrder =
{
ProjectManagerScreen::ProjectSettings,
ProjectManagerScreen::GemCatalog
};
m_screensCtrl->BuildScreens(m_screensOrder);
m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::ProjectSettings, false);
UpdateNextButtonText();
Update();
setLayout(vLayout);
}
ProjectManagerScreen UpdateProjectCtrl::GetScreenEnum()
@ -60,85 +88,80 @@ namespace O3DE::ProjectManager
return ProjectManagerScreen::UpdateProject;
}
void UpdateProjectCtrl::HandleBackButton()
{
if (!m_screensCtrl->GotoPreviousScreen())
void UpdateProjectCtrl::NotifyCurrentScreen()
{
emit GotoPreviousScreenRequest();
m_stack->setCurrentIndex(ScreenOrder::Settings);
Update();
}
else
void UpdateProjectCtrl::HandleGemsButton()
{
UpdateNextButtonText();
}
// The next page is the gem catalog. Gather the available gems that will be shown in the gem catalog.
m_gemCatalogScreen->ReinitForProject(m_projectInfo.m_path, /*isNewProject=*/false);
m_stack->setCurrentWidget(m_gemCatalogScreen);
Update();
}
void UpdateProjectCtrl::HandleNextButton()
void UpdateProjectCtrl::HandleBackButton()
{
ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen();
ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum();
auto screenOrderIter = m_screensOrder.begin();
for (; screenOrderIter != m_screensOrder.end(); ++screenOrderIter)
if (m_stack->currentIndex() > 0)
{
if (*screenOrderIter == screenEnum)
m_stack->setCurrentIndex(m_stack->currentIndex() - 1);
Update();
}
else
{
++screenOrderIter;
break;
emit GotoPreviousScreenRequest();
}
}
if (screenEnum == ProjectManagerScreen::ProjectSettings)
void UpdateProjectCtrl::HandleNextButton()
{
auto projectScreen = reinterpret_cast<ProjectSettingsScreen*>(currentScreen);
if (projectScreen)
if (m_stack->currentIndex() == ScreenOrder::Settings)
{
if (!projectScreen->Validate())
if (m_updateSettingsScreen)
{
if (!m_updateSettingsScreen->Validate())
{
QMessageBox::critical(this, tr("Invalid project settings"), tr("Invalid project settings"));
return;
}
m_projectInfo = projectScreen->GetProjectInfo();
ProjectInfo newProjectSettings = m_updateSettingsScreen->GetProjectInfo();
// The next page is the gem catalog. Gather the available gems that will be shown in the gem catalog.
auto* gemCatalogScreen = reinterpret_cast<GemCatalogScreen*>(m_screensCtrl->FindScreen(ProjectManagerScreen::GemCatalog));
if (gemCatalogScreen)
// Update project if settings changed
if (m_projectInfo != newProjectSettings)
{
gemCatalogScreen->ReinitForProject(m_projectInfo.m_path, /*isNewProject=*/false);
}
else
bool result = PythonBindingsInterface::Get()->UpdateProject(newProjectSettings);
if (!result)
{
QMessageBox::critical(this, tr("Operation failed"), tr("Cannot find gem catalog screen."));
}
QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project."));
return;
}
}
if (screenOrderIter != m_screensOrder.end())
{
m_screensCtrl->ChangeToScreen(*screenOrderIter);
UpdateNextButtonText();
}
else
// Check if project path has changed and move it
if (newProjectSettings.m_path != m_projectInfo.m_path)
{
auto result = PythonBindingsInterface::Get()->UpdateProject(m_projectInfo);
if (result)
if (!ProjectUtils::MoveProject(m_projectInfo.m_path, newProjectSettings.m_path))
{
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
QMessageBox::critical(this, tr("Project move failed"), tr("Failed to move project."));
return;
}
else
{
QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project."));
}
// Enable or disable the gems that got adjusted in the gem catalog and apply them to the given project.
auto* gemCatalogScreen = reinterpret_cast<GemCatalogScreen*>(m_screensCtrl->FindScreen(ProjectManagerScreen::GemCatalog));
if (gemCatalogScreen)
{
gemCatalogScreen->EnableDisableGemsForProject(m_projectInfo.m_path);
m_projectInfo = newProjectSettings;
}
else
{
QMessageBox::critical(this, tr("Operation failed"), tr("Cannot find gem catalog screen."));
}
if (m_stack->currentIndex() == ScreenOrder::Gems && m_gemCatalogScreen)
{
// Enable or disable the gems that got adjusted in the gem catalog and apply them to the given project.
m_gemCatalogScreen->EnableDisableGemsForProject(m_projectInfo.m_path);
}
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
}
void UpdateProjectCtrl::UpdateCurrentProject(const QString& projectPath)
@ -148,16 +171,28 @@ namespace O3DE::ProjectManager
{
m_projectInfo = projectResult.GetValue();
}
Update();
UpdateSettingsScreen();
}
void UpdateProjectCtrl::UpdateNextButtonText()
void UpdateProjectCtrl::Update()
{
QString nextButtonText = tr("Continue");
if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog)
if (m_stack->currentIndex() == ScreenOrder::Gems)
{
m_header->setSubTitle(QString(tr("Add More Gems to \"%1\"")).arg(m_projectInfo.m_projectName));
m_nextButton->setText(tr("Confirm"));
}
else
{
nextButtonText = tr("Update Project");
m_header->setSubTitle(QString(tr("Edit Project Settings: \"%1\"")).arg(m_projectInfo.m_projectName));
m_nextButton->setText(tr("Save"));
}
}
m_nextButton->setText(nextButtonText);
void UpdateProjectCtrl::UpdateSettingsScreen()
{
m_updateSettingsScreen->SetProjectInfo(m_projectInfo);
}
} // namespace O3DE::ProjectManager

@ -12,40 +12,57 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include "ProjectInfo.h"
#include <ProjectInfo.h>
#include <ScreenWidget.h>
#include <ScreensCtrl.h>
#include <QPushButton>
#endif
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
QT_FORWARD_DECLARE_CLASS(QTabWidget)
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QFrame)
namespace O3DE::ProjectManager
{
class UpdateProjectCtrl
: public ScreenWidget
QT_FORWARD_DECLARE_CLASS(ScreenHeader)
QT_FORWARD_DECLARE_CLASS(UpdateProjectSettingsScreen)
QT_FORWARD_DECLARE_CLASS(GemCatalogScreen)
class UpdateProjectCtrl : public ScreenWidget
{
public:
explicit UpdateProjectCtrl(QWidget* parent = nullptr);
~UpdateProjectCtrl() = default;
ProjectManagerScreen GetScreenEnum() override;
protected:
void NotifyCurrentScreen() override;
protected slots:
void HandleBackButton();
void HandleNextButton();
void HandleGemsButton();
void UpdateCurrentProject(const QString& projectPath);
private:
void UpdateNextButtonText();
void Update();
void UpdateSettingsScreen();
enum ScreenOrder
{
Settings,
Gems
};
ScreenHeader* m_header = nullptr;
QStackedWidget* m_stack = nullptr;
UpdateProjectSettingsScreen* m_updateSettingsScreen = nullptr;
GemCatalogScreen* m_gemCatalogScreen = nullptr;
ScreensCtrl* m_screensCtrl;
QPushButton* m_backButton;
QPushButton* m_nextButton;
QPushButton* m_backButton = nullptr;
QPushButton* m_nextButton = nullptr;
QVector<ProjectManagerScreen> m_screensOrder;
ProjectInfo m_projectInfo;
ProjectManagerScreen m_screenEnum;
};
} // 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 <UpdateProjectSettingsScreen.h>
#include <FormBrowseEditWidget.h>
#include <FormLineEditWidget.h>
#include <QLineEdit>
#include <QDir>
namespace O3DE::ProjectManager
{
UpdateProjectSettingsScreen::UpdateProjectSettingsScreen(QWidget* parent)
: ProjectSettingsScreen(parent)
{
}
ProjectManagerScreen UpdateProjectSettingsScreen::GetScreenEnum()
{
return ProjectManagerScreen::UpdateProjectSettings;
}
void UpdateProjectSettingsScreen::SetProjectInfo(const ProjectInfo& projectInfo)
{
m_projectName->lineEdit()->setText(projectInfo.m_projectName);
m_projectPath->lineEdit()->setText(projectInfo.m_path);
}
bool UpdateProjectSettingsScreen::ValidateProjectPath()
{
bool projectPathIsValid = true;
if (m_projectPath->lineEdit()->text().isEmpty())
{
projectPathIsValid = false;
m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
}
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
return projectPathIsValid;
}
} // namespace O3DE::ProjectManager

@ -0,0 +1,34 @@
/*
* 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 <ProjectSettingsScreen.h>
#endif
namespace O3DE::ProjectManager
{
class UpdateProjectSettingsScreen
: public ProjectSettingsScreen
{
public:
explicit UpdateProjectSettingsScreen(QWidget* parent = nullptr);
~UpdateProjectSettingsScreen() = default;
ProjectManagerScreen GetScreenEnum() override;
void SetProjectInfo(const ProjectInfo& projectInfo);
protected:
bool ValidateProjectPath() override;
};
} // namespace O3DE::ProjectManager

@ -38,6 +38,8 @@ set(FILES
Source/ProjectInfo.cpp
Source/ProjectUtils.h
Source/ProjectUtils.cpp
Source/UpdateProjectSettingsScreen.h
Source/UpdateProjectSettingsScreen.cpp
Source/NewProjectSettingsScreen.h
Source/NewProjectSettingsScreen.cpp
Source/CreateProjectCtrl.h
@ -48,7 +50,6 @@ set(FILES
Source/ProjectsScreen.cpp
Source/ProjectSettingsScreen.h
Source/ProjectSettingsScreen.cpp
Source/ProjectSettingsScreen.ui
Source/EngineSettingsScreen.h
Source/EngineSettingsScreen.cpp
Source/ProjectButtonWidget.h

@ -42,7 +42,7 @@ namespace AZ
}
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
void signal_handler(int signal)
void signal_handler([[maybe_unused]] int signal)
{
AZ_TracePrintf(
SceneAPI::Utilities::ErrorWindow,

@ -167,6 +167,9 @@ endfunction()
# Add the projects here so the above function is found
foreach(project ${LY_PROJECTS})
file(REAL_PATH ${project} full_directory_path BASE_DIRECTORY ${CMAKE_SOURCE_DIR})
if(NOT LY_FIRST_PROJECT)
ly_set(LY_FIRST_PROJECT_PATH ${full_directory_path})
endif()
string(SHA256 full_directory_hash ${full_directory_path})
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit

Loading…
Cancel
Save