-#include
-
-namespace O3DE::ProjectManager
-{
- FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent)
- : ScreenWidget(parent)
- {
- QVBoxLayout* vLayout = new QVBoxLayout();
- setLayout(vLayout);
- vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins);
-
- QLabel* titleLabel = new QLabel(this);
- titleLabel->setText(tr("Ready. Set. Create!"));
- titleLabel->setStyleSheet("font-size: 60px");
- vLayout->addWidget(titleLabel);
-
- QLabel* introLabel = new QLabel(this);
- introLabel->setTextFormat(Qt::AutoText);
- introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project. Not sure what to create?
Explore what\342\200\231s available by downloading our sample project.
"));
- introLabel->setStyleSheet("font-size: 14px");
- vLayout->addWidget(introLabel);
-
- QHBoxLayout* buttonLayout = new QHBoxLayout();
- buttonLayout->setSpacing(s_buttonSpacing);
-
- m_createProjectButton = CreateLargeBoxButton(QIcon(":/Add.svg"), tr("Create Project"), this);
- m_createProjectButton->setIconSize(QSize(s_iconSize, s_iconSize));
- buttonLayout->addWidget(m_createProjectButton);
-
- m_addProjectButton = CreateLargeBoxButton(QIcon(":/Select_Folder.svg"), tr("Add a Project"), this);
- m_addProjectButton->setIconSize(QSize(s_iconSize, s_iconSize));
- buttonLayout->addWidget(m_addProjectButton);
-
- QSpacerItem* buttonSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum);
- buttonLayout->addItem(buttonSpacer);
-
- vLayout->addItem(buttonLayout);
-
- QSpacerItem* verticalSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Minimum, QSizePolicy::Expanding);
- vLayout->addItem(verticalSpacer);
-
- // 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_createProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleNewProjectButton);
- connect(m_addProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleAddProjectButton);
- }
-
- ProjectManagerScreen FirstTimeUseScreen::GetScreenEnum()
- {
- return ProjectManagerScreen::FirstTimeUse;
- }
-
- void FirstTimeUseScreen::HandleNewProjectButton()
- {
- emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
- emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
- }
- void FirstTimeUseScreen::HandleAddProjectButton()
- {
- emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome);
- }
-
- QPushButton* FirstTimeUseScreen::CreateLargeBoxButton(const QIcon& icon, const QString& text, QWidget* parent)
- {
- QPushButton* largeBoxButton = new QPushButton(icon, text, parent);
-
- largeBoxButton->setFixedSize(s_boxButtonWidth, s_boxButtonHeight);
- largeBoxButton->setFlat(true);
- largeBoxButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
- largeBoxButton->setStyleSheet("QPushButton { font-size: 14px; background-color: rgba(0, 0, 0, 191); }");
-
- return largeBoxButton;
- }
-
-} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h
deleted file mode 100644
index 80a2310d7a..0000000000
--- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h
+++ /dev/null
@@ -1,49 +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.
- *
- */
-#pragma once
-
-#if !defined(Q_MOC_RUN)
-#include
-#endif
-
-QT_FORWARD_DECLARE_CLASS(QIcon)
-QT_FORWARD_DECLARE_CLASS(QPushButton)
-
-namespace O3DE::ProjectManager
-{
- class FirstTimeUseScreen
- : public ScreenWidget
- {
- public:
- explicit FirstTimeUseScreen(QWidget* parent = nullptr);
- ~FirstTimeUseScreen() = default;
- ProjectManagerScreen GetScreenEnum() override;
-
- protected slots:
- void HandleNewProjectButton();
- void HandleAddProjectButton();
-
- private:
- QPushButton* CreateLargeBoxButton(const QIcon& icon, const QString& text, QWidget* parent = nullptr);
-
- 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/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
index ffbf1bf6fe..b57a2b35b2 100644
--- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
+++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
@@ -12,6 +12,9 @@
#include
#include
+#include
+#include
+#include
#include
#include
@@ -23,6 +26,7 @@
#include
#include
#include
+#include
namespace O3DE::ProjectManager
{
@@ -31,64 +35,81 @@ namespace O3DE::ProjectManager
NewProjectSettingsScreen::NewProjectSettingsScreen(QWidget* parent)
: ScreenWidget(parent)
{
- QHBoxLayout* hLayout = new QHBoxLayout();
- this->setLayout(hLayout);
+ 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);
- QLabel* projectNameLabel = new QLabel(tr("Project Name"), this);
- vLayout->addWidget(projectNameLabel);
-
- m_projectNameLineEdit = new QLineEdit(tr("New Project"), this);
- vLayout->addWidget(m_projectNameLineEdit);
-
- QLabel* projectPathLabel = new QLabel(tr("Project Location"), this);
- vLayout->addWidget(projectPathLabel);
-
+ // you cannot remove content margins in qss
+ vLayout->setContentsMargins(0,0,0,0);
+ vLayout->setAlignment(Qt::AlignTop);
{
- QHBoxLayout* projectPathLayout = new QHBoxLayout(this);
+ m_projectName = new FormLineEditWidget(tr("Project name"), tr("New Project"), this);
+ m_projectName->setErrorLabelText(
+ tr("A project with this name already exists at this location. Please choose a new name or location."));
+ vLayout->addWidget(m_projectName);
- m_projectPathLineEdit = new QLineEdit(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), this);
- projectPathLayout->addWidget(m_projectPathLineEdit);
+ m_projectPath =
+ new FormBrowseEditWidget(tr("Project Location"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), this);
+ m_projectPath->lineEdit()->setReadOnly(true);
+ m_projectPath->setErrorLabelText(tr("Please provide a valid path to a folder that exists"));
+ m_projectPath->lineEdit()->setValidator(new PathValidator(PathValidator::PathMode::ExistingFolder, this));
+ vLayout->addWidget(m_projectPath);
- QPushButton* browseButton = new QPushButton(tr("Browse"), this);
- connect(browseButton, &QPushButton::pressed, this, &NewProjectSettingsScreen::HandleBrowseButton);
- projectPathLayout->addWidget(browseButton);
-
- vLayout->addLayout(projectPathLayout);
- }
-
- QLabel* projectTemplateLabel = new QLabel(this);
- projectTemplateLabel->setText("Project Template");
- vLayout->addWidget(projectTemplateLabel);
-
- QHBoxLayout* templateLayout = new QHBoxLayout(this);
- vLayout->addItem(templateLayout);
-
- m_projectTemplateButtonGroup = new QButtonGroup(this);
- auto templatesResult = PythonBindingsInterface::Get()->GetProjectTemplates();
- if (templatesResult.IsSuccess() && !templatesResult.GetValue().isEmpty())
- {
- for (auto projectTemplate : templatesResult.GetValue())
+ // if we don't use a QFrame we cannot "contain" the widgets inside and move them around
+ // as a group
+ QFrame* projectTemplateWidget = new QFrame(this);
+ projectTemplateWidget->setObjectName("projectTemplate");
+ QVBoxLayout* containerLayout = new QVBoxLayout();
+ containerLayout->setAlignment(Qt::AlignTop);
{
- QRadioButton* radioButton = new QRadioButton(projectTemplate.m_name, this);
- radioButton->setProperty(k_pathProperty, projectTemplate.m_path);
- m_projectTemplateButtonGroup->addButton(radioButton);
+ QLabel* projectTemplateLabel = new QLabel(tr("Select a Project Template"));
+ projectTemplateLabel->setObjectName("projectTemplateLabel");
+ containerLayout->addWidget(projectTemplateLabel);
- templateLayout->addWidget(radioButton);
+ QLabel* projectTemplateDetailsLabel = new QLabel(tr("Project templates are pre-configured with relevant Gems that provide "
+ "additional functionality and content to the project."));
+ projectTemplateDetailsLabel->setWordWrap(true);
+ projectTemplateDetailsLabel->setObjectName("projectTemplateDetailsLabel");
+ containerLayout->addWidget(projectTemplateDetailsLabel);
+
+ QHBoxLayout* templateLayout = new QHBoxLayout(this);
+ containerLayout->addItem(templateLayout);
+
+ m_projectTemplateButtonGroup = new QButtonGroup(this);
+ m_projectTemplateButtonGroup->setObjectName("templateButtonGroup");
+ auto templatesResult = PythonBindingsInterface::Get()->GetProjectTemplates();
+ if (templatesResult.IsSuccess() && !templatesResult.GetValue().isEmpty())
+ {
+ for (auto projectTemplate : templatesResult.GetValue())
+ {
+ QRadioButton* radioButton = new QRadioButton(projectTemplate.m_name, this);
+ radioButton->setProperty(k_pathProperty, projectTemplate.m_path);
+ m_projectTemplateButtonGroup->addButton(radioButton);
+
+ containerLayout->addWidget(radioButton);
+ }
+
+ m_projectTemplateButtonGroup->buttons().first()->setChecked(true);
+ }
}
-
- m_projectTemplateButtonGroup->buttons().first()->setChecked(true);
+ projectTemplateWidget->setLayout(containerLayout);
+ vLayout->addWidget(projectTemplateWidget);
}
+ projectSettingsFrame->setLayout(vLayout);
- QSpacerItem* verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
- vLayout->addItem(verticalSpacer);
+ hLayout->addWidget(projectSettingsFrame);
- hLayout->addItem(vLayout);
+ QWidget* projectTemplateDetails = new QWidget(this);
+ projectTemplateDetails->setObjectName("projectTemplateDetails");
+ hLayout->addWidget(projectTemplateDetails);
- QWidget* gemsListPlaceholder = new QWidget(this);
- gemsListPlaceholder->setFixedWidth(250);
- hLayout->addWidget(gemsListPlaceholder);
+ this->setLayout(hLayout);
}
ProjectManagerScreen NewProjectSettingsScreen::GetScreenEnum()
@@ -96,26 +117,12 @@ namespace O3DE::ProjectManager
return ProjectManagerScreen::NewProjectSettings;
}
- void NewProjectSettingsScreen::HandleBrowseButton()
- {
- QString defaultPath = m_projectPathLineEdit->text();
- if (defaultPath.isEmpty())
- {
- defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
- }
-
- QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("New project path"), defaultPath));
- if (!directory.isEmpty())
- {
- m_projectPathLineEdit->setText(directory);
- }
- }
ProjectInfo NewProjectSettingsScreen::GetProjectInfo()
{
ProjectInfo projectInfo;
- projectInfo.m_projectName = m_projectNameLineEdit->text();
- projectInfo.m_path = QDir::toNativeSeparators(m_projectPathLineEdit->text() + "/" + projectInfo.m_projectName);
+ projectInfo.m_projectName = m_projectName->lineEdit()->text();
+ projectInfo.m_path = QDir::toNativeSeparators(m_projectPath->lineEdit()->text() + "/" + projectInfo.m_projectName);
return projectInfo;
}
@@ -127,18 +134,18 @@ namespace O3DE::ProjectManager
bool NewProjectSettingsScreen::Validate()
{
bool projectNameIsValid = true;
- if (m_projectNameLineEdit->text().isEmpty())
+ if (m_projectName->lineEdit()->text().isEmpty())
{
projectNameIsValid = false;
}
bool projectPathIsValid = true;
- if (m_projectPathLineEdit->text().isEmpty())
+ if (m_projectPath->lineEdit()->text().isEmpty())
{
projectPathIsValid = false;
}
- QDir path(QDir::toNativeSeparators(m_projectPathLineEdit->text() + "/" + m_projectNameLineEdit->text()));
+ QDir path(QDir::toNativeSeparators(m_projectPath->lineEdit()->text() + "/" + m_projectName->lineEdit()->text()));
if (path.exists() && !path.isEmpty())
{
projectPathIsValid = false;
diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
index 1cfd3c9c35..f0e9609fdc 100644
--- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
+++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
@@ -17,10 +17,12 @@
#endif
QT_FORWARD_DECLARE_CLASS(QButtonGroup)
-QT_FORWARD_DECLARE_CLASS(QLineEdit)
namespace O3DE::ProjectManager
{
+ QT_FORWARD_DECLARE_CLASS(FormLineEditWidget)
+ QT_FORWARD_DECLARE_CLASS(FormBrowseEditWidget)
+
class NewProjectSettingsScreen
: public ScreenWidget
{
@@ -38,8 +40,8 @@ namespace O3DE::ProjectManager
void HandleBrowseButton();
private:
- QLineEdit* m_projectNameLineEdit;
- QLineEdit* m_projectPathLineEdit;
+ FormLineEditWidget* m_projectName;
+ FormBrowseEditWidget* m_projectPath;
QButtonGroup* m_projectTemplateButtonGroup;
};
diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp
index dada54b1a2..4be876e79f 100644
--- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp
+++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp
@@ -31,6 +31,7 @@ namespace O3DE::ProjectManager
LabelButton::LabelButton(QWidget* parent)
: QLabel(parent)
{
+ setObjectName("labelButton");
m_overlayLabel = new QLabel("", this);
m_overlayLabel->setObjectName("labelButtonOverlay");
m_overlayLabel->setWordWrap(true);
@@ -75,6 +76,8 @@ namespace O3DE::ProjectManager
void ProjectButton::Setup()
{
+ setObjectName("projectButton");
+
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setSpacing(0);
vLayout->setContentsMargins(0, 0, 0, 0);
@@ -98,14 +101,21 @@ namespace O3DE::ProjectManager
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);
+ QFrame* footer = new QFrame(this);
+ QHBoxLayout* hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ footer->setLayout(hLayout);
+ {
+ QLabel* projectNameLabel = new QLabel(m_projectName, this);
+ hLayout->addWidget(projectNameLabel);
- setFixedSize(s_projectImageWidth, s_projectImageHeight + m_projectSettingsMenuButton->height());
+ QPushButton* projectMenuButton = new QPushButton(this);
+ projectMenuButton->setObjectName("projectMenuButton");
+ projectMenuButton->setMenu(newProjectMenu);
+ hLayout->addWidget(projectMenuButton);
+ }
+
+ vLayout->addWidget(footer);
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); });
connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); });
diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h
index 43efaa1136..671debf6d0 100644
--- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h
+++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h
@@ -73,7 +73,6 @@ namespace O3DE::ProjectManager
QString m_projectName;
QString m_projectImagePath;
LabelButton* m_projectImageLabel;
- QPushButton* m_projectSettingsMenuButton;
QAction* m_editProjectAction;
QAction* m_editProjectGemsAction;
QAction* m_copyProjectAction;
diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp
index eb79f2da1e..76bcc2eb99 100644
--- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp
+++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp
@@ -11,52 +11,46 @@
*/
#include
-#include
+#include
#include
#include
#include
-#include
-
namespace O3DE::ProjectManager
{
ProjectManagerWindow::ProjectManagerWindow(QWidget* parent, const AZ::IO::PathView& engineRootPath)
: QMainWindow(parent)
- , m_ui(new Ui::ProjectManagerWindowClass())
{
- m_ui->setupUi(this);
- QLayout* layout = m_ui->centralWidget->layout();
- layout->setMargin(0);
- layout->setSpacing(0);
- layout->setContentsMargins(0, 0, 0, 0);
-
m_pythonBindings = AZStd::make_unique(engineRootPath);
- m_screensCtrl = new ScreensCtrl();
- m_ui->verticalLayout->addWidget(m_screensCtrl);
+ setWindowTitle(tr("O3DE Project Manager"));
- connect(m_ui->projectsMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleProjectsMenu);
- connect(m_ui->engineMenu, &QMenu::aboutToShow, this, &ProjectManagerWindow::HandleEngineMenu);
+ ScreensCtrl* screensCtrl = new ScreensCtrl();
+ // currently the tab order on the home page is based on the order of this list
+ QVector screenEnums =
+ {
+ ProjectManagerScreen::Projects,
+ ProjectManagerScreen::EngineSettings,
+ ProjectManagerScreen::CreateProject,
+ ProjectManagerScreen::UpdateProject
+ };
+ screensCtrl->BuildScreens(screenEnums);
+
+ setCentralWidget(screensCtrl);
+
+ // setup stylesheets and hot reloading
QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast(engineRootPath.Native().size()));
const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/ProjectManager/Resources");
const auto qrcPath = QStringLiteral(":/ProjectManager/style");
AzQtComponents::StyleManager::addSearchPaths("style", pathOnDisk, qrcPath, engineRootPath);
+ // set stylesheet after creating the screens or their styles won't get updated
AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("style:ProjectManager.qss"));
- QVector screenEnums =
- {
- ProjectManagerScreen::FirstTimeUse,
- ProjectManagerScreen::CreateProject,
- ProjectManagerScreen::ProjectsHome,
- ProjectManagerScreen::UpdateProject,
- ProjectManagerScreen::EngineSettings
- };
- m_screensCtrl->BuildScreens(screenEnums);
- m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::FirstTimeUse, false);
+ screensCtrl->ForceChangeToScreen(ProjectManagerScreen::Projects, false);
}
ProjectManagerWindow::~ProjectManagerWindow()
@@ -64,13 +58,4 @@ namespace O3DE::ProjectManager
m_pythonBindings.reset();
}
- void ProjectManagerWindow::HandleProjectsMenu()
- {
- m_screensCtrl->ChangeToScreen(ProjectManagerScreen::ProjectsHome);
- }
- void ProjectManagerWindow::HandleEngineMenu()
- {
- m_screensCtrl->ChangeToScreen(ProjectManagerScreen::EngineSettings);
- }
-
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h
index d5c586e59b..74db3467c5 100644
--- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h
+++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h
@@ -13,17 +13,9 @@
#if !defined(Q_MOC_RUN)
#include
-
-#include
-
#include
#endif
-namespace Ui
-{
- class ProjectManagerWindowClass;
-}
-
namespace O3DE::ProjectManager
{
class ProjectManagerWindow
@@ -35,13 +27,7 @@ namespace O3DE::ProjectManager
explicit ProjectManagerWindow(QWidget* parent, const AZ::IO::PathView& engineRootPath);
~ProjectManagerWindow();
- protected slots:
- void HandleProjectsMenu();
- void HandleEngineMenu();
-
private:
- QScopedPointer m_ui;
- ScreensCtrl* m_screensCtrl;
AZStd::unique_ptr m_pythonBindings;
};
diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui
deleted file mode 100644
index 633cd61182..0000000000
--- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
- ProjectManagerWindowClass
-
-
-
- 0
- 0
- 1200
- 800
-
-
-
-
- 0
- 0
-
-
-
- O3DE Project Manager
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp
deleted file mode 100644
index 6c60685358..0000000000
--- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp
+++ /dev/null
@@ -1,206 +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
-
-#include
-#include
-#include
-#include
-#include
-#include
-#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)
- {
- QVBoxLayout* vLayout = new QVBoxLayout();
- setLayout(vLayout);
- vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins);
-
- 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()
- {
- return ProjectManagerScreen::ProjectsHome;
- }
-
- void ProjectsHomeScreen::HandleNewProjectButton()
- {
- emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
- emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
- }
- void ProjectsHomeScreen::HandleAddProjectButton()
- {
- // Do nothing for now
- }
- void ProjectsHomeScreen::HandleOpenProject(const QString& projectPath)
- {
- if (!projectPath.isEmpty())
- {
- AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
- AZStd::string executableFilename = "Editor";
- AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION);
- auto cmdPath = AZ::IO::FixedMaxPathString::format("%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), projectPath.toStdString().c_str());
-
- AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
- processLaunchInfo.m_commandlineParameters = cmdPath;
- bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
- if (!launchSucceeded)
- {
- AZ_Error("ProjectManager", false, "Failed to launch editor");
- QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid."));
- }
- else
- {
- // prevent the user from accidentally pressing the button while the editor is launching
- // and let them know what's happening
- ProjectButton* button = qobject_cast(sender());
- if (button)
- {
- button->SetButtonEnabled(false);
- button->SetButtonOverlayText(tr("Opening Editor..."));
- }
-
- // enable the button after 3 seconds
- constexpr int waitTimeInMs = 3000;
- QTimer::singleShot(waitTimeInMs, this, [this, button] {
- if (button)
- {
- button->SetButtonEnabled(true);
- }
- });
- }
- }
- else
- {
- AZ_Error("ProjectManager", false, "Cannot open editor because an empty project path was provided");
- QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor because the project path is invalid."));
- }
-
- }
- 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/ProjectsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp
new file mode 100644
index 0000000000..5f1c0e2b36
--- /dev/null
+++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp
@@ -0,0 +1,347 @@
+/*
+ * 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
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//#define DISPLAY_PROJECT_DEV_DATA true
+
+namespace O3DE::ProjectManager
+{
+ ProjectsScreen::ProjectsScreen(QWidget* parent)
+ : ScreenWidget(parent)
+ {
+ QVBoxLayout* vLayout = new QVBoxLayout();
+ vLayout->setAlignment(Qt::AlignTop);
+ vLayout->setContentsMargins(s_contentMargins, 0, s_contentMargins, 0);
+ setLayout(vLayout);
+
+ m_background.load(":/Backgrounds/FirstTimeBackgroundImage.jpg");
+
+ m_stack = new QStackedWidget(this);
+
+ m_firstTimeContent = CreateFirstTimeContent();
+ m_stack->addWidget(m_firstTimeContent);
+
+ m_projectsContent = CreateProjectsContent();
+ m_stack->addWidget(m_projectsContent);
+
+ vLayout->addWidget(m_stack);
+
+ connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleNewProjectButton);
+ connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleAddProjectButton);
+ }
+
+ QFrame* ProjectsScreen::CreateFirstTimeContent()
+ {
+ QFrame* frame = new QFrame(this);
+ frame->setObjectName("firstTimeContent");
+ {
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setAlignment(Qt::AlignTop);
+ frame->setLayout(layout);
+
+ QLabel* titleLabel = new QLabel(tr("Ready. Set. Create."), this);
+ titleLabel->setObjectName("titleLabel");
+ layout->addWidget(titleLabel);
+
+ QLabel* introLabel = new QLabel(this);
+ introLabel->setObjectName("introLabel");
+ introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project. Not sure what to create? \nExplore what's "
+ "available by downloading our sample project."));
+ layout->addWidget(introLabel);
+
+ QHBoxLayout* buttonLayout = new QHBoxLayout(this);
+ buttonLayout->setAlignment(Qt::AlignLeft);
+ buttonLayout->setSpacing(s_spacerSize);
+
+ // use a newline to force the text up
+ QPushButton* createProjectButton = new QPushButton(tr("Create a Project\n"), this);
+ createProjectButton->setObjectName("createProjectButton");
+ buttonLayout->addWidget(createProjectButton);
+
+ QPushButton* addProjectButton = new QPushButton(tr("Add a Project\n"), this);
+ addProjectButton->setObjectName("addProjectButton");
+ buttonLayout->addWidget(addProjectButton);
+
+ connect(createProjectButton, &QPushButton::clicked, this, &ProjectsScreen::HandleNewProjectButton);
+ connect(addProjectButton, &QPushButton::clicked, this, &ProjectsScreen::HandleAddProjectButton);
+
+ layout->addLayout(buttonLayout);
+ }
+
+ return frame;
+ }
+
+ QFrame* ProjectsScreen::CreateProjectsContent()
+ {
+ QFrame* frame = new QFrame(this);
+ frame->setObjectName("projectsContent");
+ {
+ QVBoxLayout* layout = new QVBoxLayout();
+ layout->setAlignment(Qt::AlignTop);
+ layout->setContentsMargins(0, 0, 0, 0);
+ frame->setLayout(layout);
+
+ QFrame* header = new QFrame(this);
+ QHBoxLayout* headerLayout = new QHBoxLayout();
+ {
+ QLabel* titleLabel = new QLabel(tr("My Projects"), this);
+ titleLabel->setObjectName("titleLabel");
+ headerLayout->addWidget(titleLabel);
+
+ QMenu* newProjectMenu = new QMenu(this);
+ m_createNewProjectAction = newProjectMenu->addAction("Create New Project");
+ m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project");
+
+ connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleNewProjectButton);
+ connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleAddProjectButton);
+
+ QPushButton* newProjectMenuButton = new QPushButton(tr("New Project..."), this);
+ newProjectMenuButton->setObjectName("newProjectButton");
+ newProjectMenuButton->setMenu(newProjectMenu);
+ newProjectMenuButton->setDefault(true);
+ headerLayout->addWidget(newProjectMenuButton);
+ }
+ header->setLayout(headerLayout);
+
+ layout->addWidget(header);
+
+ // 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();
+
+ FlowLayout* flowLayout = new FlowLayout(0, s_spacerSize, s_spacerSize);
+ scrollWidget->setLayout(flowLayout);
+
+ projectsScrollArea->setWidget(scrollWidget);
+ projectsScrollArea->setWidgetResizable(true);
+
+#ifndef DISPLAY_PROJECT_DEV_DATA
+ for (auto project : projectsResult.GetValue())
+#else
+ ProjectInfo project = projectsResult.GetValue().at(0);
+ for (int i = 0; i < 15; i++)
+#endif
+ {
+ 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);
+ }
+
+ flowLayout->addWidget(projectButton);
+
+ connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
+ connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
+
+ #ifdef DISPLAY_PROJECT_DEV_DATA
+ connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
+ connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
+ connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
+ connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
+ #endif
+ }
+
+ layout->addWidget(projectsScrollArea);
+ }
+ }
+
+ return frame;
+ }
+
+ ProjectManagerScreen ProjectsScreen::GetScreenEnum()
+ {
+ return ProjectManagerScreen::Projects;
+ }
+
+ bool ProjectsScreen::IsTab()
+ {
+ return true;
+ }
+
+ QString ProjectsScreen::GetTabText()
+ {
+ return tr("Projects");
+ }
+
+ void ProjectsScreen::paintEvent([[maybe_unused]] QPaintEvent* event)
+ {
+ // we paint the background here because qss does not support background cover scaling
+ QPainter painter(this);
+
+ auto winSize = size();
+ auto pixmapRatio = (float)m_background.width() / m_background.height();
+ auto windowRatio = (float)winSize.width() / winSize.height();
+
+ if (pixmapRatio > windowRatio)
+ {
+ auto newWidth = (int)(winSize.height() * pixmapRatio);
+ auto offset = (newWidth - winSize.width()) / -2;
+ painter.drawPixmap(offset, 0, newWidth, winSize.height(), m_background);
+ }
+ else
+ {
+ auto newHeight = (int)(winSize.width() / pixmapRatio);
+ painter.drawPixmap(0, 0, winSize.width(), newHeight, m_background);
+ }
+ }
+
+ void ProjectsScreen::HandleNewProjectButton()
+ {
+ emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
+ emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
+ }
+ void ProjectsScreen::HandleAddProjectButton()
+ {
+ // Do nothing for now
+ }
+ void ProjectsScreen::HandleOpenProject(const QString& projectPath)
+ {
+ if (!projectPath.isEmpty())
+ {
+ AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
+ AZStd::string executableFilename = "Editor";
+ AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION);
+ auto cmdPath = AZ::IO::FixedMaxPathString::format("%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), projectPath.toStdString().c_str());
+
+ AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
+ processLaunchInfo.m_commandlineParameters = cmdPath;
+ bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
+ if (!launchSucceeded)
+ {
+ AZ_Error("ProjectManager", false, "Failed to launch editor");
+ QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid."));
+ }
+ else
+ {
+ // prevent the user from accidentally pressing the button while the editor is launching
+ // and let them know what's happening
+ ProjectButton* button = qobject_cast(sender());
+ if (button)
+ {
+ button->SetButtonEnabled(false);
+ button->SetButtonOverlayText(tr("Opening Editor..."));
+ }
+
+ // enable the button after 3 seconds
+ constexpr int waitTimeInMs = 3000;
+ QTimer::singleShot(waitTimeInMs, this, [this, button] {
+ if (button)
+ {
+ button->SetButtonEnabled(true);
+ }
+ });
+ }
+ }
+ else
+ {
+ AZ_Error("ProjectManager", false, "Cannot open editor because an empty project path was provided");
+ QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor because the project path is invalid."));
+ }
+
+ }
+ 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([[maybe_unused]] const QString& projectPath)
+ {
+ // Open file dialog and choose location for copied project then register copy with O3DE
+ }
+ void ProjectsScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath)
+ {
+ // Unregister Project from O3DE
+ }
+ void ProjectsScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath)
+ {
+ // Remove project from 03DE and delete from disk
+ ProjectsScreen::HandleRemoveProject(projectPath);
+ }
+
+ void ProjectsScreen::NotifyCurrentScreen()
+ {
+ if (ShouldDisplayFirstTimeContent())
+ {
+ m_stack->setCurrentWidget(m_firstTimeContent);
+ }
+ else
+ {
+ m_stack->setCurrentWidget(m_projectsContent);
+ }
+ }
+
+ bool ProjectsScreen::ShouldDisplayFirstTimeContent()
+ {
+ auto projectsResult = PythonBindingsInterface::Get()->GetProjects();
+ if (!projectsResult.IsSuccess() || projectsResult.GetValue().isEmpty())
+ {
+ return true;
+ }
+
+ QSettings settings;
+ bool displayFirstTimeContent = settings.value("displayFirstTimeContent", true).toBool();
+ if (displayFirstTimeContent)
+ {
+ settings.setValue("displayFirstTimeContent", false);
+ }
+
+ return displayFirstTimeContent;
+ }
+
+} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h b/Code/Tools/ProjectManager/Source/ProjectsScreen.h
similarity index 69%
rename from Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h
rename to Code/Tools/ProjectManager/Source/ProjectsScreen.h
index e8d1ac4fb5..d88ba8398d 100644
--- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h
+++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.h
@@ -15,16 +15,26 @@
#include
#endif
+QT_FORWARD_DECLARE_CLASS(QPaintEvent)
+QT_FORWARD_DECLARE_CLASS(QFrame)
+QT_FORWARD_DECLARE_CLASS(QStackedWidget)
+
namespace O3DE::ProjectManager
{
- class ProjectsHomeScreen
+ class ProjectsScreen
: public ScreenWidget
{
public:
- explicit ProjectsHomeScreen(QWidget* parent = nullptr);
- ~ProjectsHomeScreen() = default;
+ explicit ProjectsScreen(QWidget* parent = nullptr);
+ ~ProjectsScreen() = default;
+
ProjectManagerScreen GetScreenEnum() override;
+ QString GetTabText() override;
+ bool IsTab() override;
+
+ protected:
+ void NotifyCurrentScreen() override;
protected slots:
void HandleNewProjectButton();
@@ -36,16 +46,24 @@ namespace O3DE::ProjectManager
void HandleRemoveProject(const QString& projectPath);
void HandleDeleteProject(const QString& projectPath);
+ void paintEvent(QPaintEvent* event) override;
+
private:
+ QFrame* CreateFirstTimeContent();
+ QFrame* CreateProjectsContent();
+ bool ShouldDisplayFirstTimeContent();
+
QAction* m_createNewProjectAction;
QAction* m_addExistingProjectAction;
+ QPixmap m_background;
+ QFrame* m_firstTimeContent;
+ QFrame* m_projectsContent;
+ QStackedWidget* m_stack;
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/ScreenDefs.h b/Code/Tools/ProjectManager/Source/ScreenDefs.h
index 13289e2481..46d243f677 100644
--- a/Code/Tools/ProjectManager/Source/ScreenDefs.h
+++ b/Code/Tools/ProjectManager/Source/ScreenDefs.h
@@ -17,11 +17,10 @@ namespace O3DE::ProjectManager
{
Invalid = -1,
Empty,
- FirstTimeUse,
CreateProject,
NewProjectSettings,
GemCatalog,
- ProjectsHome,
+ Projects,
UpdateProject,
ProjectSettings,
EngineSettings
diff --git a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp
index d37ccdb59f..b2b4376e14 100644
--- a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp
+++ b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp
@@ -11,12 +11,11 @@
*/
#include
-#include
#include
#include
#include
#include
-#include
+#include
#include
#include
@@ -28,9 +27,6 @@ namespace O3DE::ProjectManager
switch(screen)
{
- case (ProjectManagerScreen::FirstTimeUse):
- newScreen = new FirstTimeUseScreen(parent);
- break;
case (ProjectManagerScreen::CreateProject):
newScreen = new CreateProjectCtrl(parent);
break;
@@ -40,8 +36,8 @@ namespace O3DE::ProjectManager
case (ProjectManagerScreen::GemCatalog):
newScreen = new GemCatalogScreen(parent);
break;
- case (ProjectManagerScreen::ProjectsHome):
- newScreen = new ProjectsHomeScreen(parent);
+ case (ProjectManagerScreen::Projects):
+ newScreen = new ProjectsScreen(parent);
break;
case (ProjectManagerScreen::UpdateProject):
newScreen = new UpdateProjectCtrl(parent);
diff --git a/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.cpp b/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.cpp
new file mode 100644
index 0000000000..29b1eb6ff6
--- /dev/null
+++ b/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.cpp
@@ -0,0 +1,62 @@
+/*
+* 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
+
+namespace O3DE::ProjectManager
+{
+ ScreenHeader::ScreenHeader(QWidget* parent)
+ : QFrame(parent)
+ {
+ setObjectName("header");
+
+ QHBoxLayout* layout = new QHBoxLayout();
+ layout->setAlignment(Qt::AlignLeft);
+ layout->setContentsMargins(0,0,0,0);
+
+ m_backButton = new QPushButton();
+ m_backButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ layout->addWidget(m_backButton);
+
+ QVBoxLayout* titleLayout = new QVBoxLayout();
+ m_title = new QLabel();
+ m_title->setObjectName("headerTitle");
+ titleLayout->addWidget(m_title);
+
+ m_subTitle = new QLabel();
+ m_subTitle->setObjectName("headerSubTitle");
+ titleLayout->addWidget(m_subTitle);
+
+ layout->addLayout(titleLayout);
+
+ setLayout(layout);
+ }
+
+ void ScreenHeader::setTitle(const QString& text)
+ {
+ m_title->setText(text);
+ }
+
+ void ScreenHeader::setSubTitle(const QString& text)
+ {
+ m_subTitle->setText(text);
+ }
+
+ QPushButton* ScreenHeader::backButton()
+ {
+ return m_backButton;
+ }
+
+} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.h b/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.h
new file mode 100644
index 0000000000..c5fdb56195
--- /dev/null
+++ b/Code/Tools/ProjectManager/Source/ScreenHeaderWidget.h
@@ -0,0 +1,42 @@
+/*
+* 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
+#endif
+
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QPushButton)
+
+namespace O3DE::ProjectManager
+{
+ class ScreenHeader
+ : public QFrame
+ {
+ Q_OBJECT // AUTOMOC
+
+ public:
+ ScreenHeader(QWidget* parent = nullptr);
+
+ void setTitle(const QString& text);
+ void setSubTitle(const QString& text);
+
+ QPushButton* backButton();
+
+ private:
+ QLabel* m_title;
+ QLabel* m_subTitle;
+ QPushButton* m_backButton;
+ };
+} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h
index e80747d67b..2ad6d30201 100644
--- a/Code/Tools/ProjectManager/Source/ScreenWidget.h
+++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h
@@ -41,12 +41,27 @@ namespace O3DE::ProjectManager
{
return true;
}
+ virtual bool IsTab()
+ {
+ return false;
+ }
+ virtual QString GetTabText()
+ {
+ return tr("Missing");
+ }
+
+ //! Notify this screen it is the current screen
+ virtual void NotifyCurrentScreen()
+ {
+
+ }
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 a77c434026..7d31d02f6c 100644
--- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp
+++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp
@@ -14,6 +14,7 @@
#include
#include
+#include
#include
namespace O3DE::ProjectManager
@@ -21,17 +22,19 @@ namespace O3DE::ProjectManager
ScreensCtrl::ScreensCtrl(QWidget* parent)
: QWidget(parent)
{
+ setObjectName("ScreensCtrl");
+
QVBoxLayout* vLayout = new QVBoxLayout();
- vLayout->setMargin(0);
- vLayout->setSpacing(0);
vLayout->setContentsMargins(0, 0, 0, 0);
setLayout(vLayout);
m_screenStack = new QStackedWidget();
vLayout->addWidget(m_screenStack);
- //Track the bottom of the stack
- m_screenVisitOrder.push(ProjectManagerScreen::Invalid);
+ // add a tab widget at the bottom of the stack
+ m_tabWidget = new QTabWidget();
+ m_screenStack->addWidget(m_tabWidget);
+ connect(m_tabWidget, &QTabWidget::currentChanged, this, &ScreensCtrl::TabChanged);
}
void ScreensCtrl::BuildScreens(QVector screens)
@@ -57,7 +60,14 @@ namespace O3DE::ProjectManager
ScreenWidget* ScreensCtrl::GetCurrentScreen()
{
- return reinterpret_cast(m_screenStack->currentWidget());
+ if (m_screenStack->currentWidget() == m_tabWidget)
+ {
+ return reinterpret_cast(m_tabWidget->currentWidget());
+ }
+ else
+ {
+ return reinterpret_cast(m_screenStack->currentWidget());
+ }
}
bool ScreensCtrl::ChangeToScreen(ProjectManagerScreen screen)
@@ -79,13 +89,28 @@ namespace O3DE::ProjectManager
if (iterator != m_screenMap.end())
{
ScreenWidget* currentScreen = GetCurrentScreen();
- if (currentScreen != iterator.value())
+ ScreenWidget* newScreen = iterator.value();
+
+ if (currentScreen != newScreen)
{
if (addVisit)
{
- m_screenVisitOrder.push(currentScreen->GetScreenEnum());
+ ProjectManagerScreen oldScreen = currentScreen->GetScreenEnum();
+ m_screenVisitOrder.push(oldScreen);
}
- m_screenStack->setCurrentWidget(iterator.value());
+
+ if (newScreen->IsTab())
+ {
+ m_tabWidget->setCurrentWidget(newScreen);
+ m_screenStack->setCurrentWidget(m_tabWidget);
+ }
+ else
+ {
+ m_screenStack->setCurrentWidget(newScreen);
+ }
+
+ newScreen->NotifyCurrentScreen();
+
return true;
}
}
@@ -95,23 +120,46 @@ namespace O3DE::ProjectManager
bool ScreensCtrl::GotoPreviousScreen()
{
- // Don't go back if we are on the first set screen
- if (m_screenVisitOrder.top() != ProjectManagerScreen::Invalid)
+ if (!m_screenVisitOrder.isEmpty())
{
// 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);
+ ProjectManagerScreen previousScreen = m_screenVisitOrder.pop();
+ return ForceChangeToScreen(previousScreen, false);
}
return false;
}
void ScreensCtrl::ResetScreen(ProjectManagerScreen screen)
{
+ bool shouldRestoreCurrentScreen = false;
+ if (GetCurrentScreen() && GetCurrentScreen()->GetScreenEnum() == screen)
+ {
+ shouldRestoreCurrentScreen = true;
+ }
+
// Delete old screen if it exists to start fresh
DeleteScreen(screen);
// Add new screen
ScreenWidget* newScreen = BuildScreen(this, screen);
- m_screenStack->addWidget(newScreen);
+ if (newScreen->IsTab())
+ {
+ m_tabWidget->addTab(newScreen, newScreen->GetTabText());
+ if (shouldRestoreCurrentScreen)
+ {
+ m_tabWidget->setCurrentWidget(newScreen);
+ m_screenStack->setCurrentWidget(m_tabWidget);
+ }
+ }
+ else
+ {
+ m_screenStack->addWidget(newScreen);
+ if (shouldRestoreCurrentScreen)
+ {
+ m_screenStack->setCurrentWidget(newScreen);
+ }
+ }
+
m_screenMap.insert(screen, newScreen);
connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen);
@@ -134,8 +182,21 @@ namespace O3DE::ProjectManager
const auto iter = m_screenMap.find(screen);
if (iter != m_screenMap.end())
{
- m_screenStack->removeWidget(iter.value());
- iter.value()->deleteLater();
+ ScreenWidget* screenToDelete = iter.value();
+ if (screenToDelete->IsTab())
+ {
+ int tabIndex = m_tabWidget->indexOf(screenToDelete);
+ if (tabIndex > -1)
+ {
+ m_tabWidget->removeTab(tabIndex);
+ }
+ }
+ else
+ {
+ // if the screen we delete is the current widget, a new one will
+ // be selected automatically (randomly?)
+ m_screenStack->removeWidget(screenToDelete);
+ }
// Erase does not cause a rehash so interators remain valid
m_screenMap.erase(iter);
@@ -150,4 +211,12 @@ namespace O3DE::ProjectManager
}
}
+ void ScreensCtrl::TabChanged([[maybe_unused]] int index)
+ {
+ ScreenWidget* screen = reinterpret_cast(m_tabWidget->currentWidget());
+ if (screen)
+ {
+ screen->NotifyCurrentScreen();
+ }
+ }
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h
index a9d1023b4b..935fc78e25 100644
--- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h
+++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h
@@ -18,6 +18,8 @@
#include
#endif
+QT_FORWARD_DECLARE_CLASS(QTabWidget)
+
namespace O3DE::ProjectManager
{
class ScreenWidget;
@@ -46,11 +48,13 @@ namespace O3DE::ProjectManager
void ResetAllScreens();
void DeleteScreen(ProjectManagerScreen screen);
void DeleteAllScreens();
+ void TabChanged(int index);
private:
QStackedWidget* m_screenStack;
QHash m_screenMap;
QStack m_screenVisitOrder;
+ QTabWidget* m_tabWidget;
};
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp
index 84e3d8359d..b3180966ce 100644
--- a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp
+++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp
@@ -108,7 +108,7 @@ namespace O3DE::ProjectManager
auto result = PythonBindingsInterface::Get()->UpdateProject(m_projectInfo);
if (result)
{
- emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome);
+ emit ChangeScreenRequest(ProjectManagerScreen::Projects);
}
else
{
diff --git a/Code/Tools/ProjectManager/Source/main.cpp b/Code/Tools/ProjectManager/Source/main.cpp
index 3d8bb71a0c..cbeacbaf65 100644
--- a/Code/Tools/ProjectManager/Source/main.cpp
+++ b/Code/Tools/ProjectManager/Source/main.cpp
@@ -35,7 +35,6 @@ int main(int argc, char* argv[])
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware);
-
AZ::AllocatorInstance::Create();
int runSuccess = 0;
{
@@ -55,6 +54,12 @@ int main(int argc, char* argv[])
O3DE::ProjectManager::ProjectManagerWindow window(nullptr, engineRootPath);
window.show();
+ // somethings is preventing us from moving the window to the center of the
+ // primary screen - likely an Az style or component helper
+ constexpr int width = 1200;
+ constexpr int height = 800;
+ window.resize(width, height);
+
runSuccess = app.exec();
}
AZ::AllocatorInstance::Destroy();
diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake
index a41ddad21e..223465f3c8 100644
--- a/Code/Tools/ProjectManager/project_manager_files.cmake
+++ b/Code/Tools/ProjectManager/project_manager_files.cmake
@@ -21,8 +21,6 @@ set(FILES
Source/ScreenWidget.h
Source/EngineInfo.h
Source/EngineInfo.cpp
- Source/FirstTimeUseScreen.h
- Source/FirstTimeUseScreen.cpp
Source/FormLineEditWidget.h
Source/FormLineEditWidget.cpp
Source/FormBrowseEditWidget.h
@@ -33,7 +31,6 @@ set(FILES
Source/ProjectManagerWindow.cpp
Source/ProjectTemplateInfo.h
Source/ProjectTemplateInfo.cpp
- Source/ProjectManagerWindow.ui
Source/PythonBindings.h
Source/PythonBindings.cpp
Source/PythonBindingsInterface.h
@@ -45,8 +42,8 @@ set(FILES
Source/CreateProjectCtrl.cpp
Source/UpdateProjectCtrl.h
Source/UpdateProjectCtrl.cpp
- Source/ProjectsHomeScreen.h
- Source/ProjectsHomeScreen.cpp
+ Source/ProjectsScreen.h
+ Source/ProjectsScreen.cpp
Source/ProjectSettingsScreen.h
Source/ProjectSettingsScreen.cpp
Source/ProjectSettingsScreen.ui
@@ -54,6 +51,8 @@ set(FILES
Source/EngineSettingsScreen.cpp
Source/ProjectButtonWidget.h
Source/ProjectButtonWidget.cpp
+ Source/ScreenHeaderWidget.h
+ Source/ScreenHeaderWidget.cpp
Source/LinkWidget.h
Source/LinkWidget.cpp
Source/TagWidget.h
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
index fc58eb9f07..31eb089803 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
@@ -54,7 +54,6 @@
#include
-static const AZ::Vector2 UiDraw_TextSizeFactor = AZ::Vector2(12.0f, 12.0f);
static const int TabCharCount = 4;
// set buffer sizes to hold max characters that can be drawn in 1 DrawString call
static const size_t MaxVerts = 8 * 1024; // 2048 quads
@@ -1673,6 +1672,12 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T
{
ctx.m_drawTextFlags |= eDrawText_FixedSize;
}
+
+ if (params.m_useTransform)
+ {
+ ctx.m_drawTextFlags |= eDrawText_UseTransform;
+ ctx.SetTransform(AZMatrix3x4ToLYMatrix3x4(params.m_transform));
+ }
}
AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, AZStd::string_view text, bool forceCalculateSize)
@@ -1696,22 +1701,25 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te
}
internalParams.m_ctx.SetBaseState(GS_NODEPTHTEST);
internalParams.m_ctx.SetColor(AZColorToLYColorF(params.m_color));
+ internalParams.m_ctx.SetEffect(params.m_effectIndex);
internalParams.m_ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
internalParams.m_ctx.EnableFrame(false);
internalParams.m_ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
internalParams.m_ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
- internalParams.m_ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
+ internalParams.m_ctx.SetSize(AZVec2ToLYVec2(AZ::Vector2(params.m_textSizeFactor, params.m_textSizeFactor) * params.m_scale));
internalParams.m_ctx.SetLineSpacing(params.m_lineSpacing);
- if (params.m_monospace || !params.m_scaleWithWindow)
- {
- ScaleCoord(viewport, posX, posY);
- }
if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left ||
params.m_vAlign != AzFramework::TextVerticalAlignment::Top ||
forceCalculateSize)
{
+ // We align based on the size of the default font effect because we do not want the
+ // text to move when the font effect is changed
+ unsigned int effectIndex = internalParams.m_ctx.m_fxIdx;
+ internalParams.m_ctx.SetEffect(0);
Vec2 textSize = GetTextSizeUInternal(viewport, text.data(), params.m_multiline, internalParams.m_ctx);
+ internalParams.m_ctx.SetEffect(effectIndex);
+
// If we're using virtual 800x600 coordinates, convert the text size from
// pixels to that before using it as an offset.
if (internalParams.m_ctx.m_sizeIn800x600)
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.cpp
index bad7c2fe38..ef82792f32 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.cpp
@@ -32,32 +32,29 @@ namespace AZ
void ReleaseResourcesStep::Start()
{
- m_context->GetData()->m_defaultMaterialAsset.Release();
- m_context->GetData()->m_defaultModelAsset.Release();
- m_context->GetData()->m_materialAsset.Release();
- m_context->GetData()->m_modelAsset.Release();
+ auto data = m_context->GetData();
+
+ data->m_defaultMaterialAsset.Release();
+ data->m_defaultModelAsset.Release();
+ data->m_materialAsset.Release();
+ data->m_modelAsset.Release();
+ data->m_lightingPresetAsset.Release();
- if (m_context->GetData()->m_modelEntity)
+ if (data->m_modelEntity)
{
- AzFramework::EntityContextRequestBus::Event(m_context->GetData()->m_entityContext->GetContextId(),
- &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_context->GetData()->m_modelEntity);
- m_context->GetData()->m_modelEntity = nullptr;
+ AzFramework::EntityContextRequestBus::Event(data->m_entityContext->GetContextId(),
+ &AzFramework::EntityContextRequestBus::Events::DestroyEntity, data->m_modelEntity);
+ data->m_modelEntity = nullptr;
}
- m_context->GetData()->m_frameworkScene->UnsetSubsystem();
-
- m_context->GetData()->m_scene->Deactivate();
- m_context->GetData()->m_scene->RemoveRenderPipeline(m_context->GetData()->m_renderPipeline->GetId());
- RPI::RPISystemInterface::Get()->UnregisterScene(m_context->GetData()->m_scene);
-
- auto sceneSystem = AzFramework::SceneSystemInterface::Get();
- AZ_Assert(sceneSystem, "Thumbnail system failed to get scene system implementation.");
- [[maybe_unused]] bool sceneRemovedSuccessfully = sceneSystem->RemoveScene(m_context->GetData()->m_sceneName);
- AZ_Assert(
- sceneRemovedSuccessfully, "Thumbnail system was unable to remove scene '%s' from the scene system.",
- m_context->GetData()->m_sceneName.c_str());
- m_context->GetData()->m_scene = nullptr;
- m_context->GetData()->m_renderPipeline = nullptr;
+ data->m_scene->Deactivate();
+ data->m_scene->RemoveRenderPipeline(data->m_renderPipeline->GetId());
+ RPI::RPISystemInterface::Get()->UnregisterScene(data->m_scene);
+ data->m_frameworkScene->UnsetSubsystem(data->m_scene);
+ data->m_frameworkScene->UnsetSubsystem(data->m_entityContext.get());
+ data->m_scene = nullptr;
+ data->m_frameworkScene = nullptr;
+ data->m_renderPipeline = nullptr;
}
} // namespace Thumbnails
} // namespace LyIntegration
diff --git a/Gems/LyShine/Code/Editor/ViewportHelpers.cpp b/Gems/LyShine/Code/Editor/ViewportHelpers.cpp
index 428554a461..2195d2c9d4 100644
--- a/Gems/LyShine/Code/Editor/ViewportHelpers.cpp
+++ b/Gems/LyShine/Code/Editor/ViewportHelpers.cpp
@@ -30,6 +30,11 @@ namespace ViewportHelpers
return isControlledByParent;
}
+ float GetDpiScaledSize(float size)
+ {
+ return size * ViewportIcon::GetDpiScaleFactor();
+ }
+
bool IsHorizontallyFit(const AZ::Entity* element)
{
bool isHorizontallyFit = false;
@@ -332,11 +337,12 @@ namespace ViewportHelpers
AZ::Vector2 pivotPos;
EBUS_EVENT_ID_RESULT(pivotPos, element->GetId(), UiTransformBus, GetViewportSpacePivot);
- AZ::Vector2 rotationStringPos(pivotPos.GetX(), pivotPos.GetY() - ((viewportPivot->GetSize().GetY() * 0.5f) + 4.0f));
+ float offset = (viewportPivot->GetSize().GetY() * 0.5f) + (GetDpiScaledSize(4.0f));
+ AZ::Vector2 rotationStringPos(pivotPos.GetX(), pivotPos.GetY() - offset);
draw2d.SetTextAlignment(IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(0.0f);
- draw2d.DrawText(rotationString.toUtf8().data(), rotationStringPos, 16.0f, 1.0f);
+ draw2d.DrawText(rotationString.toUtf8().data(), rotationStringPos, GetDpiScaledSize(16.0f), 1.0f);
}
}
@@ -350,6 +356,6 @@ namespace ViewportHelpers
draw2d.SetTextAlignment(IDraw2d::HAlign::Left, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(0.0f);
- draw2d.DrawText(textLabel.c_str(), textPos, 16.0f, 1.0f);
+ draw2d.DrawText(textLabel.c_str(), textPos, GetDpiScaledSize(16.0f), 1.0f);
}
} // namespace ViewportHelpers
diff --git a/Gems/LyShine/Code/Editor/ViewportIcon.cpp b/Gems/LyShine/Code/Editor/ViewportIcon.cpp
index b1866efb00..4be06b2543 100644
--- a/Gems/LyShine/Code/Editor/ViewportIcon.cpp
+++ b/Gems/LyShine/Code/Editor/ViewportIcon.cpp
@@ -303,7 +303,7 @@ void ViewportIcon::DrawDistanceLine(Draw2dHelper& draw2d, AZ::Vector2 start, AZ:
draw2d.SetTextAlignment(IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(rotation);
- draw2d.DrawText(textBuf, textPos, 16.0f, 1.0f);
+ draw2d.DrawText(textBuf, textPos, 16.0f * ViewportIcon::GetDpiScaleFactor(), 1.0f);
}
void ViewportIcon::DrawAnchorLinesSplit(Draw2dHelper& draw2d, AZ::Vector2 anchorPos1, AZ::Vector2 anchorPos2,
diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Include/LyShine/Draw2d.h
index 8270461e73..b83ec4794b 100644
--- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h
+++ b/Gems/LyShine/Code/Include/LyShine/Draw2d.h
@@ -15,6 +15,7 @@
#include
#include
+#include
#include
#include
#include
@@ -256,9 +257,8 @@ protected: // types and constants
const Draw2dShaderData& shaderData,
AZ::RPI::ViewportContextPtr viewportContext) const override;
- STextDrawContext m_fontContext;
- IFFont* m_font;
- AZ::Vector2 m_position;
+ AzFramework::TextDrawParameters m_drawParameters;
+ AzFramework::FontId m_fontId;
std::string m_string;
};
@@ -288,7 +288,7 @@ protected: // member functions
void RotatePointsAboutPivot(AZ::Vector2* points, int numPoints, AZ::Vector2 pivot, float angle) const;
//! Helper function to render a text string
- void DrawTextInternal(const char* textString, IFFont* font, unsigned int effectIndex,
+ void DrawTextInternal(const char* textString, AzFramework::FontId fontId, unsigned int effectIndex,
AZ::Vector2 position, float pointSize, AZ::Color color, float rotation,
HAlign horizontalAlignment, VAlign verticalAlignment, int baseState);
@@ -298,6 +298,9 @@ protected: // member functions
//! Draw or defer a line
void DrawOrDeferLine(const DeferredLine* line);
+ //! Draw or defer a text string
+ void DrawOrDeferTextString(const DeferredText* text);
+
//! Draw or defer a rect outline
void DrawOrDeferRectOutline(const DeferredRectOutline* outlineRect);
@@ -491,7 +494,7 @@ public: // member functions
void SetImageBaseState(int state) { m_imageOptions.baseState = state; }
//! Set the text font.
- void SetTextFont(IFFont* font) { m_textOptions.font = font; }
+ void SetTextFont(AZStd::string_view fontName) { m_textOptions.fontName = fontName; }
//! Set the text font effect index.
void SetTextEffectIndex(unsigned int effectIndex) { m_textOptions.effectIndex = effectIndex; }
diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp
index 1a639ea299..6feb47419d 100644
--- a/Gems/LyShine/Code/Source/Draw2d.cpp
+++ b/Gems/LyShine/Code/Source/Draw2d.cpp
@@ -11,11 +11,13 @@
*/
#include "LyShine_precompiled.h"
#include "IFont.h"
+#include // for SVF_P3F_C4B_T2F which will be removed in a coming PR
#include
#include
#include
+#include
#include
#include
@@ -55,7 +57,7 @@ CDraw2d::CDraw2d(AZ::RPI::ViewportContextPtr viewportContext)
m_defaultImageOptions.pixelRounding = Rounding::Nearest;
m_defaultImageOptions.baseState = g_defaultBaseState;
- m_defaultTextOptions.font = (gEnv && gEnv->pCryFont != nullptr) ? gEnv->pCryFont->GetFont("default") : nullptr;
+ m_defaultTextOptions.fontName = "default";
m_defaultTextOptions.effectIndex = 0;
m_defaultTextOptions.color.Set(1.0f, 1.0f, 1.0f);
m_defaultTextOptions.horizontalAlignment = HAlign::Left;
@@ -283,13 +285,20 @@ void CDraw2d::DrawText(const char* textString, AZ::Vector2 position, float point
{
TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
+ AzFramework::FontId fontId = AzFramework::InvalidFontId;
+ AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface::Get();
+ if (fontQueryInterface)
+ {
+ fontId = fontQueryInterface->GetFontId(actualTextOptions->fontName);
+ }
+
// render the drop shadow, if needed
if ((actualTextOptions->dropShadowColor.GetA() > 0.0f) &&
(actualTextOptions->dropShadowOffset.GetX() || actualTextOptions->dropShadowOffset.GetY()))
{
// calculate the drop shadow pos and render it
AZ::Vector2 dropShadowPosition(position + actualTextOptions->dropShadowOffset);
- DrawTextInternal(textString, actualTextOptions->font, actualTextOptions->effectIndex,
+ DrawTextInternal(textString, fontId, actualTextOptions->effectIndex,
dropShadowPosition, pointSize, actualTextOptions->dropShadowColor,
actualTextOptions->rotation,
actualTextOptions->horizontalAlignment, actualTextOptions->verticalAlignment,
@@ -298,7 +307,7 @@ void CDraw2d::DrawText(const char* textString, AZ::Vector2 position, float point
// draw the text string
AZ::Color textColor = AZ::Color::CreateFromVector3AndFloat(actualTextOptions->color, opacity);
- DrawTextInternal(textString, actualTextOptions->font, actualTextOptions->effectIndex,
+ DrawTextInternal(textString, fontId, actualTextOptions->effectIndex,
position, pointSize, textColor,
actualTextOptions->rotation,
actualTextOptions->horizontalAlignment, actualTextOptions->verticalAlignment,
@@ -398,20 +407,35 @@ void CDraw2d::DrawRectOutlineTextured(AZ::Data::Instance image,
////////////////////////////////////////////////////////////////////////////////////////////////////
AZ::Vector2 CDraw2d::GetTextSize(const char* textString, float pointSize, TextOptions* textOptions)
{
- TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
-
- if (!actualTextOptions->font)
+ AzFramework::FontDrawInterface* fontDrawInterface = nullptr;
+ AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface::Get();
+ if (fontQueryInterface)
+ {
+ TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
+ AzFramework::FontId fontId = fontQueryInterface->GetFontId(actualTextOptions->fontName);
+ fontDrawInterface = fontQueryInterface->GetFontDrawInterface(fontId);
+ }
+ if (!fontDrawInterface)
{
return AZ::Vector2(0.0f, 0.0f);
}
- STextDrawContext fontContext;
- fontContext.SetEffect(actualTextOptions->effectIndex);
- fontContext.SetSizeIn800x600(false);
- fontContext.SetSize(vector2f(pointSize, pointSize));
+ // Set up draw parameters
+ AzFramework::TextDrawParameters drawParams;
+ drawParams.m_drawViewportId = GetViewportContext()->GetId();
+ drawParams.m_position = AZ::Vector3(0.0f, 0.0f, 1.0f);
+ drawParams.m_effectIndex = 0;
+ drawParams.m_textSizeFactor = pointSize;
+ drawParams.m_scale = AZ::Vector2(1.0f, 1.0f);
+ drawParams.m_lineSpacing = 1.0f;
+ drawParams.m_monospace = false;
+ drawParams.m_depthTest = false;
+ drawParams.m_virtual800x600ScreenSize = false;
+ drawParams.m_scaleWithWindow = false;
+ drawParams.m_multiline = true;
- Vec2 textSize = actualTextOptions->font->GetTextSize(textString, true, fontContext);
- return AZ::Vector2(textSize.x, textSize.y);
+ AZ::Vector2 textSize = fontDrawInterface->GetTextSize(drawParams, textString);
+ return textSize;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -559,100 +583,89 @@ void CDraw2d::RotatePointsAboutPivot(AZ::Vector2* points, [[maybe_unused]] int n
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-void CDraw2d::DrawTextInternal(const char* textString, IFFont* font, unsigned int effectIndex,
+void CDraw2d::DrawTextInternal(const char* textString, AzFramework::FontId fontId, unsigned int effectIndex,
AZ::Vector2 position, float pointSize, AZ::Color color, float rotation,
- HAlign horizontalAlignment, VAlign verticalAlignment, int baseState)
+ HAlign horizontalAlignment, VAlign verticalAlignment, [[maybe_unused]] int baseState)
{
- if (!font)
- {
- return;
- }
-
- STextDrawContext fontContext;
- fontContext.SetEffect(effectIndex);
- fontContext.SetSizeIn800x600(false);
- fontContext.SetSize(vector2f(pointSize, pointSize));
- fontContext.SetColor(ColorF(color.GetR(), color.GetG(), color.GetB(), color.GetA()));
- fontContext.m_baseState = baseState;
- fontContext.SetOverrideViewProjMatrices(false);
-
// FFont.cpp uses the alpha value of the color to decide whether to use the color, if the alpha value is zero
// (in a ColorB format) then the color set via SetColor is ignored and it usually ends up drawing with an alpha of 1.
// This is not what we want so in this case do not draw at all.
- if (!fontContext.IsColorOverridden())
+ if (AZ::IsClose(color.GetA(), 0.0f))
{
return;
}
- AZ::Vector2 alignedPosition;
- if (horizontalAlignment == HAlign::Left && verticalAlignment == VAlign::Top)
+ // Convert Draw2d alignment to text alignment
+ AzFramework::TextHorizontalAlignment hAlignment = AzFramework::TextHorizontalAlignment::Left;
+ switch (horizontalAlignment)
{
- alignedPosition = position;
- }
- else
- {
- // we align based on the size of the default font effect, because we do not want the
- // text to move when the font effect is changed
- unsigned int fontEffectIndex = fontContext.m_fxIdx;
- fontContext.SetEffect(0);
- Vec2 textSize = font->GetTextSize(textString, true, fontContext);
- fontContext.SetEffect(fontEffectIndex);
-
- alignedPosition = Align(position, AZ::Vector2(textSize.x, textSize.y), horizontalAlignment, verticalAlignment);
+ case HAlign::Left:
+ hAlignment = AzFramework::TextHorizontalAlignment::Left;
+ break;
+ case HAlign::Center:
+ hAlignment = AzFramework::TextHorizontalAlignment::Center;
+ break;
+ case HAlign::Right:
+ hAlignment = AzFramework::TextHorizontalAlignment::Right;
+ break;
+ default:
+ AZ_Assert(false, "Attempting to draw text with unsupported horizontal alignment.");
+ break;
}
- int flags = 0;
+ AzFramework::TextVerticalAlignment vAlignment = AzFramework::TextVerticalAlignment::Top;
+ switch (verticalAlignment)
+ {
+ case VAlign::Top:
+ vAlignment = AzFramework::TextVerticalAlignment::Top;
+ break;
+ case VAlign::Center:
+ vAlignment = AzFramework::TextVerticalAlignment::Center;
+ break;
+ case VAlign::Bottom:
+ vAlignment = AzFramework::TextVerticalAlignment::Bottom;
+ break;
+ default:
+ AZ_Assert(false, "Attempting to draw text with unsupported vertical alignment.");
+ break;
+ }
+
+ // Set up draw parameters for font interface
+ AzFramework::TextDrawParameters drawParams;
+ drawParams.m_drawViewportId = GetViewportContext()->GetId();
+ drawParams.m_position = AZ::Vector3(position.GetX(), position.GetY(), 1.0f);
+ drawParams.m_color = color;
+ drawParams.m_effectIndex = effectIndex;
+ drawParams.m_textSizeFactor = pointSize;
+ drawParams.m_scale = AZ::Vector2(1.0f, 1.0f);
+ drawParams.m_lineSpacing = 1.0f; //!< Spacing between new lines, as a percentage of m_scale.
+ drawParams.m_hAlign = hAlignment;
+ drawParams.m_vAlign = vAlignment;
+ drawParams.m_monospace = false;
+ drawParams.m_depthTest = false;
+ drawParams.m_virtual800x600ScreenSize = false;
+ drawParams.m_scaleWithWindow = false;
+ drawParams.m_multiline = true;
+
if (rotation != 0.0f)
{
// rotate around the position (if aligned to center will rotate about center etc)
float rotRad = DEG2RAD(rotation);
- Vec3 pivot(position.GetX(), position.GetY(), 0.0f);
- Matrix34A moveToPivotSpaceMat = Matrix34A::CreateTranslationMat(-pivot);
- Matrix34A rotMat = Matrix34A::CreateRotationZ(rotRad);
- Matrix34A moveFromPivotSpaceMat = Matrix34A::CreateTranslationMat(pivot);
+ AZ::Vector3 pivot(position.GetX(), position.GetY(), 0.0f);
+ AZ::Matrix3x4 moveToPivotSpaceMat = AZ::Matrix3x4::CreateTranslation(-pivot);
+ AZ::Matrix3x4 rotMat = AZ::Matrix3x4::CreateRotationZ(rotRad);
+ AZ::Matrix3x4 moveFromPivotSpaceMat = AZ::Matrix3x4::CreateTranslation(pivot);
- Matrix34A transform = moveFromPivotSpaceMat * rotMat * moveToPivotSpaceMat;
- fontContext.SetTransform(transform);
- flags |= eDrawText_UseTransform;
+ drawParams.m_transform = moveFromPivotSpaceMat * rotMat * moveToPivotSpaceMat;
+ drawParams.m_useTransform = true;
}
- // The font system uses these alignment flags to force text to be in the safe zone
- // depending on overscan etc
- if (horizontalAlignment == HAlign::Center)
- {
- flags |= eDrawText_Center;
- }
- else if (horizontalAlignment == HAlign::Right)
- {
- flags |= eDrawText_Right;
- }
+ DeferredText newText;
+ newText.m_drawParameters = drawParams;
+ newText.m_fontId = fontId;
+ newText.m_string = textString;
- if (verticalAlignment == VAlign::Center)
- {
- flags |= eDrawText_CenterV;
- }
- else if (verticalAlignment == VAlign::Bottom)
- {
- flags |= eDrawText_Bottom;
- }
-
- fontContext.SetFlags(flags);
-
- if (m_deferCalls)
- {
- DeferredText* newText = new DeferredText;
-
- newText->m_fontContext = fontContext;
- newText->m_font = font;
- newText->m_position = alignedPosition;
- newText->m_string = textString;
-
- m_deferredPrimitives.push_back(newText);
- }
- else
- {
- font->DrawString(alignedPosition.GetX(), alignedPosition.GetY(), textString, true, fontContext);
- }
+ DrawOrDeferTextString(&newText);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -685,6 +698,20 @@ void CDraw2d::DrawOrDeferLine(const DeferredLine* line)
}
}
+void CDraw2d::DrawOrDeferTextString(const DeferredText* text)
+{
+ if (m_deferCalls)
+ {
+ DeferredText* newText = new DeferredText;
+ *newText = *text;
+ m_deferredPrimitives.push_back(newText);
+ }
+ else
+ {
+ text->Draw(m_dynamicDraw, m_shaderData, GetViewportContext());
+ }
+}
+
void CDraw2d::DrawOrDeferRectOutline(const DeferredRectOutline* rectOutline)
{
if (m_deferCalls)
@@ -919,6 +946,15 @@ void CDraw2d::DeferredText::Draw([[maybe_unused]] AZ::RHI::PtrDrawString(m_position.GetX(), m_position.GetY(), m_string.c_str(), true, m_fontContext);
+ AzFramework::FontDrawInterface* fontDrawInterface = nullptr;
+ AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface::Get();
+ if (fontQueryInterface)
+ {
+ fontDrawInterface = fontQueryInterface->GetFontDrawInterface(m_fontId);
+ if (fontDrawInterface)
+ {
+ fontDrawInterface->DrawScreenAlignedText2d(m_drawParameters, m_string.c_str());
+ }
+ }
}
diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp
index 679cae3421..fb6dcb2628 100644
--- a/Gems/LyShine/Code/Source/LyShine.cpp
+++ b/Gems/LyShine/Code/Source/LyShine.cpp
@@ -454,7 +454,6 @@ void CLyShine::Render()
GetUiRenderer()->EndUiFrameRender();
-#ifdef LYSHINE_ATOM_TODO // convert debug info to Atom
#ifndef _RELEASE
if (CV_ui_DisplayElemBounds)
{
@@ -474,7 +473,6 @@ void CLyShine::Render()
m_uiCanvasManager->DebugDisplayDrawCallData();
}
#endif
-#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Gems/LyShine/Code/Source/LyShineDebug.cpp b/Gems/LyShine/Code/Source/LyShineDebug.cpp
index 76b4030106..44e0e187ec 100644
--- a/Gems/LyShine/Code/Source/LyShineDebug.cpp
+++ b/Gems/LyShine/Code/Source/LyShineDebug.cpp
@@ -12,6 +12,7 @@
#include "LyShine_precompiled.h"
#include "LyShineDebug.h"
#include "IConsole.h"
+#include "IRenderer.h"
#include
#include
@@ -392,15 +393,15 @@ static void DebugDrawColoredBox(AZ::Vector2 pos, AZ::Vector2 size, AZ::Color col
////////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined(_RELEASE)
-static void DebugDrawStringWithSizeBox(IFFont* font, unsigned int effectIndex, const char* sizeString,
+static void DebugDrawStringWithSizeBox(AZStd::string_view font, unsigned int effectIndex, const char* sizeString,
const char* testString, AZ::Vector2 pos, float spacing, float size)
{
CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d();
IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions();
- if (font)
+ if (!font.empty())
{
- textOptions.font = font;
+ textOptions.fontName = font;
}
textOptions.effectIndex = effectIndex;
@@ -427,7 +428,7 @@ static void DebugDrawStringWithSizeBox(IFFont* font, unsigned int effectIndex, c
////////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined(_RELEASE)
-static void DebugDraw2dFontSizes(IFFont* font, unsigned int effectIndex, const char* fontName)
+static void DebugDraw2dFontSizes(AZStd::string_view font, unsigned int effectIndex)
{
CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d();
@@ -436,7 +437,7 @@ static void DebugDraw2dFontSizes(IFFont* font, unsigned int effectIndex, const c
float xSpacing = 20.0f;
char buffer[32];
- sprintf_s(buffer, "Font = %s, effect = %d", fontName, effectIndex);
+ sprintf_s(buffer, "Font = %s, effect = %d", font.data(), effectIndex);
draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), 32);
yOffset += 40.0f;
draw2d->DrawText("NOTE: if the effect includes a drop shadow baked into font then the pixel size",
@@ -1441,10 +1442,10 @@ void LyShineDebug::RenderDebug()
switch (CV_r_DebugUIDraw2dFont)
{
case 1: // test font sizes (default font, effect 0)
- DebugDraw2dFontSizes(0, 0, "default");
+ DebugDraw2dFontSizes("default", 0);
break;
case 2: // test font sizes (default font, effect 1)
- DebugDraw2dFontSizes(0, 1, "default");
+ DebugDraw2dFontSizes("default", 1);
break;
case 3: // test font alignment
DebugDraw2dFontAlignment();
diff --git a/Gems/LyShine/Code/Source/LyShineDebug.h b/Gems/LyShine/Code/Source/LyShineDebug.h
index ed03fd10b2..e50689710a 100644
--- a/Gems/LyShine/Code/Source/LyShineDebug.h
+++ b/Gems/LyShine/Code/Source/LyShineDebug.h
@@ -14,7 +14,9 @@
#ifndef _RELEASE
#include
-class ITexture;
+#include
+#include
+
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -66,7 +68,7 @@ public: // static member functions
struct DebugInfoTextureUsage
{
- ITexture* m_texture;
+ AZ::Data::Instance m_texture;
bool m_isClampTextureUsage;
int m_numCanvasesUsed;
int m_numDrawCallsUsed;
diff --git a/Gems/LyShine/Code/Source/RenderGraph.cpp b/Gems/LyShine/Code/Source/RenderGraph.cpp
index e5ac6c7b8f..d5a1df7b15 100644
--- a/Gems/LyShine/Code/Source/RenderGraph.cpp
+++ b/Gems/LyShine/Code/Source/RenderGraph.cpp
@@ -18,6 +18,7 @@
#include
#ifndef _RELEASE
+#include
#include
#endif
@@ -1115,7 +1116,7 @@ namespace LyShine
m_wasBuiltThisFrame = false;
- AZStd::set uniqueTextures;
+ AZStd::set> uniqueTextures;
// If we are rendering to the render targets this frame then record the stats for doing that
if (m_renderToRenderTargetCount < 2)
@@ -1144,13 +1145,11 @@ namespace LyShine
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- void RenderGraph::GetDebugInfoRenderNodeList(const AZStd::vector& renderNodeList, LyShineDebug::DebugInfoRenderGraph& info, AZStd::set& uniqueTextures) const
+ void RenderGraph::GetDebugInfoRenderNodeList(
+ const AZStd::vector& renderNodeList,
+ LyShineDebug::DebugInfoRenderGraph& info,
+ AZStd::set>& uniqueTextures) const
{
- AZ_UNUSED(renderNodeList);
- AZ_UNUSED(info);
- AZ_UNUSED(uniqueTextures);
-
-#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (convert debug info to use Atom)
const PrimitiveListRenderNode* prevPrimListNode = nullptr;
bool isFirstNode = true;
bool wasLastNodeAMask = false;
@@ -1235,7 +1234,6 @@ namespace LyShine
isFirstNode = false;
}
-#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1290,13 +1288,6 @@ namespace LyShine
void* context,
const AZStd::string& indent) const
{
- AZ_UNUSED(renderNodeList);
- AZ_UNUSED(fileHandle);
- AZ_UNUSED(reportInfo);
- AZ_UNUSED(context);
- AZ_UNUSED(indent);
-
-#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (convert debug info to use Atom)
AZStd::string logLine;
bool previousNodeAlreadyCounted = false;
@@ -1355,10 +1346,10 @@ namespace LyShine
{
for (int i = 0; i < prevPrimListNode->GetNumTextures(); ++i)
{
- ITexture* texture = prevPrimListNode->GetTexture(i);
+ AZ::Data::Instance texture = prevPrimListNode->GetTexture(i);
if (!texture)
{
- texture = gEnv->pRenderer->GetWhiteTexture();
+ texture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White);
}
bool isClampTextureUsage = prevPrimListNode->GetTextureIsClampMode(i);
@@ -1405,17 +1396,19 @@ namespace LyShine
for (int i = 0; i < primListRenderNode->GetNumTextures(); ++i)
{
- ITexture* texture = primListRenderNode->GetTexture(i);
+ AZ::Data::Instance texture = primListRenderNode->GetTexture(i);
if (!texture)
{
- texture = gEnv->pRenderer->GetWhiteTexture();
+ texture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White);
}
bool isClampTextureUsage = primListRenderNode->GetTextureIsClampMode(i);
LyShineDebug::DebugInfoTextureUsage* matchingTextureUsage = nullptr;
// Write line to logfile for this texture
- logLine = AZStd::string::format("%s %s\r\n", indent.c_str(), texture->GetName());
+ AZStd::string textureName;
+ AZ::Data::AssetCatalogRequestBus::BroadcastResult(textureName, &AZ::Data::AssetCatalogRequests::GetAssetPathById, texture->GetAssetId());
+ logLine = AZStd::string::format("%s %s\r\n", indent.c_str(), textureName.c_str());
AZ::IO::LocalFileIO::GetInstance()->Write(fileHandle, logLine.c_str(), logLine.size());
// see if texture is in reportInfo
@@ -1459,7 +1452,6 @@ namespace LyShine
prevPrimListNode = primListRenderNode;
}
}
-#endif
}
#endif
diff --git a/Gems/LyShine/Code/Source/RenderGraph.h b/Gems/LyShine/Code/Source/RenderGraph.h
index f9d16cf8b7..2f1586e857 100644
--- a/Gems/LyShine/Code/Source/RenderGraph.h
+++ b/Gems/LyShine/Code/Source/RenderGraph.h
@@ -13,7 +13,6 @@
#pragma once
#include
-#include
#include
#include
#include
@@ -294,7 +293,10 @@ namespace LyShine
void ValidateGraph();
void GetDebugInfoRenderGraph(LyShineDebug::DebugInfoRenderGraph& info) const;
- void GetDebugInfoRenderNodeList(const AZStd::vector& renderNodeList, LyShineDebug::DebugInfoRenderGraph& info, AZStd::set& uniqueTextures) const;
+ void GetDebugInfoRenderNodeList(
+ const AZStd::vector& renderNodeList,
+ LyShineDebug::DebugInfoRenderGraph& info,
+ AZStd::set>& uniqueTextures) const;
void DebugReportDrawCalls(AZ::IO::HandleType fileHandle, LyShineDebug::DebugInfoDrawCallReport& reportInfo, void* context) const;
void DebugReportDrawCallsRenderNodeList(const AZStd::vector& renderNodeList, AZ::IO::HandleType fileHandle,
diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp
index 4115feaf22..b64a13280f 100644
--- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp
+++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp
@@ -1425,7 +1425,8 @@ void UiCanvasManager::DebugReportDrawCalls(const AZStd::string& name) const
if (reportTextureUsage.m_numCanvasesUsed > 1 &&
reportTextureUsage.m_numDrawCallsWhereExceedingMaxTextures)
{
- AZStd::string textureName = reportTextureUsage.m_texture->GetName();
+ AZStd::string textureName;
+ AZ::Data::AssetCatalogRequestBus::BroadcastResult(textureName, &AZ::Data::AssetCatalogRequests::GetAssetPathById, reportTextureUsage.m_texture->GetAssetId());
if (textureName.compare(0, fontTexturePrefix.length(), fontTexturePrefix) != 0)
{
logLine = AZStd::string::format("%s\r\n", textureName.c_str());
@@ -1457,7 +1458,8 @@ void UiCanvasManager::DebugReportDrawCalls(const AZStd::string& name) const
reportTextureUsage.m_lastContextUsed == canvas &&
reportTextureUsage.m_numDrawCallsWhereExceedingMaxTextures)
{
- AZStd::string textureName = reportTextureUsage.m_texture->GetName();
+ AZStd::string textureName;
+ AZ::Data::AssetCatalogRequestBus::BroadcastResult(textureName, &AZ::Data::AssetCatalogRequests::GetAssetPathById, reportTextureUsage.m_texture->GetAssetId());
// exclude font textures
if (textureName.compare(0, fontTexturePrefix.length(), fontTexturePrefix) != 0)
diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp
index 2a2c950e82..57acbed5d5 100644
--- a/Gems/LyShine/Code/Source/UiRenderer.cpp
+++ b/Gems/LyShine/Code/Source/UiRenderer.cpp
@@ -12,6 +12,7 @@
#include "LyShine_precompiled.h"
#include "UiRenderer.h"
+#include
#include
#include
#include
@@ -24,7 +25,7 @@
#include
#include
-#include
+#include
////////////////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC MEMBER FUNCTIONS
@@ -353,7 +354,6 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption)
{
if (recordingOption > 0)
{
-#ifdef LYSHINE_ATOM_TODO
// compute the total area of all the textures, also create a vector that we can sort by area
AZStd::vector textures;
int totalArea = 0;
@@ -374,15 +374,14 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption)
return lhs->GetDataSize() > rhs->GetDataSize();
});
- IDraw2d* draw2d = Draw2dHelper::GetDraw2d();
+ CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d();
// setup to render lines of text for the debug display
- draw2d->BeginDraw2d(false);
float xOffset = 20.0f;
float yOffset = 20.0f;
- int blackTexture = gEnv->pRenderer->GetBlackTextureId();
+ auto blackTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Black);
float textOpacity = 1.0f;
float backgroundRectOpacity = 0.75f;
const float lineSpacing = 20.0f;
@@ -432,9 +431,6 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption)
texture->GetWidth(), texture->GetHeight(), texture->GetDataSize(), texture->GetFormatName(), texture->GetName());
WriteLine(buffer, white);
}
-
- draw2d->EndDraw2d();
-#endif
}
}
diff --git a/Gems/LyShine/Code/Source/UiRenderer.h b/Gems/LyShine/Code/Source/UiRenderer.h
index 260bd8278c..888c88586a 100644
--- a/Gems/LyShine/Code/Source/UiRenderer.h
+++ b/Gems/LyShine/Code/Source/UiRenderer.h
@@ -20,6 +20,8 @@
#include
#endif
+class ITexture;
+
////////////////////////////////////////////////////////////////////////////////////////////////////
//! UI render interface
//
@@ -136,8 +138,6 @@ protected: // attributes
#ifndef _RELEASE
int m_debugTextureDataRecordLevel = 0;
-#ifdef LYSHINE_ATOM_TODO // Convert debug code to Atom
- AZStd::unordered_set m_texturesUsedInFrame;
-#endif
+ AZStd::unordered_set m_texturesUsedInFrame; // LYSHINE_ATOM_TODO - convert to RPI::Image
#endif
};
diff --git a/Registry/AssetProcessorPlatformConfig.setreg b/Registry/AssetProcessorPlatformConfig.setreg
index 7407fb18db..2147842da7 100644
--- a/Registry/AssetProcessorPlatformConfig.setreg
+++ b/Registry/AssetProcessorPlatformConfig.setreg
@@ -42,10 +42,10 @@
// 'enabled' is AUTOMATICALLY TRUE for the current platform that you are running on, so it is not necessary to force it to true for that platform
// To enable any additional platform, just uncomment the appropriate line below.
"Platforms": {
- "pc": "enabled",
+ //"pc": "enabled",
//"android": "enabled",
//"ios": "enabled",
- "mac": "enabled",
+ //"mac": "enabled",
//"server": "enabled"
},
// ---- The number of worker jobs, 0 means use the number of Logical Cores
diff --git a/Templates/DefaultProject/Template/preview.png b/Templates/DefaultProject/Template/preview.png
index 2191a0ebc2..3d4fe78063 100644
--- a/Templates/DefaultProject/Template/preview.png
+++ b/Templates/DefaultProject/Template/preview.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a18fae4040a22d2bb359a8ca642b97bb8f6468eeb52e2826b3b029bd8f1350b6
-size 5466
+oid sha256:40949893ed7009eeaa90b7ce6057cb6be9dfaf7b162e3c26ba9dadf985939d7d
+size 2038