merge stabilization/2106 into development

Signed-off-by: hultonha <hultonha@amazon.co.uk>
This commit is contained in:
hultonha
2021-07-06 17:34:04 +01:00
377 changed files with 6549 additions and 9214 deletions
@@ -2548,7 +2548,7 @@ namespace AssetProcessor
jobdetail.m_jobParam[AZ_CRC(AutoFailReasonKey)] = AZStd::string::format(
"Source file ( %s ) contains non ASCII characters.\n"
"Open 3D Engine currently only supports file paths having ASCII characters and therefore asset processor will not be able to process this file.\n"
"O3DE currently only supports file paths having ASCII characters and therefore asset processor will not be able to process this file.\n"
"Please rename the source file to fix this error.\n",
normalizedPath.toUtf8().data());
@@ -10,6 +10,7 @@
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/IO/FileIOEventBus.h>
#include <AzCore/Utils/Utils.h>
#include "BaseAssetProcessorTest.h"
#include <native/utilities/BatchApplicationManager.h>
@@ -67,11 +68,19 @@ namespace AssetProcessor
static char** paramStringArray = &namePtr;
auto registry = AZ::SettingsRegistry::Get();
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
auto bootstrapKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
auto projectPathKey = bootstrapKey + "/project_path";
registry->Set(projectPathKey, "AutomatedTesting");
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
// Forcing the branch token into settings registry before starting the application manager.
// This avoids writing the asset_processor.setreg file which can cause fileIO errors.
AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
auto branchTokenKey = bootstrapKey + "/assetProcessor_branch_token";
AZStd::string token;
AzFramework::StringFunc::AssetPath::CalculateBranchToken(enginePath.c_str(), token);
registry->Set(branchTokenKey, token.c_str());
m_application.reset(new UnitTestAppManager(&numParams, &paramStringArray));
ASSERT_EQ(m_application->BeforeRun(), ApplicationManager::Status_Success);
ASSERT_TRUE(m_application->PrepareForTests());
@@ -17,7 +17,7 @@
</size>
</property>
<property name="windowTitle">
<string>Asset Processor</string>
<string>O3DE Asset Processor</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_1" stretch="0,1">
@@ -478,7 +478,7 @@ void ApplicationManagerBase::InitConnectionManager()
result = QObject::connect(GetRCController(), &AssetProcessor::RCController::JobStarted, this,
[](QString inputFile, QString platform)
{
QString msg = QCoreApplication::translate("Asset Processor", "Processing %1 (%2)...\n", "%1 is the name of the file, and %2 is the platform to process it for").arg(inputFile, platform);
QString msg = QCoreApplication::translate("O3DE Asset Processor", "Processing %1 (%2)...\n", "%1 is the name of the file, and %2 is the platform to process it for").arg(inputFile, platform);
AZ_Printf(AssetProcessor::ConsoleChannel, "%s", msg.toUtf8().constData());
AssetNotificationMessage message(inputFile.toUtf8().constData(), AssetNotificationMessage::JobStarted, AZ::Data::s_invalidAssetType, platform.toUtf8().constData());
EBUS_EVENT(AssetProcessor::ConnectionBus, SendPerPlatform, 0, message, platform);
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:342c3eaccf68a178dfd8c2b1792a93a8c9197c8184dca11bf90706d7481df087
size 1611268
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7088e902885d98953f6a1715efab319c063a4ab8918fd0e810251c8ed82b8514
size 542983
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:797794816e4b1702f1ae1f32b408c95c79eb1f8a95aba43cfad9cccc181b0bda
size 1135182
@@ -26,12 +26,13 @@
<file>o3de.svg</file>
<file>menu.svg</file>
<file>menu_hover.svg</file>
<file>Backgrounds/FirstTimeBackgroundImage.jpg</file>
<file>ArrowDownLine.svg</file>
<file>ArrowUpLine.svg</file>
<file>CarrotArrowDown.svg</file>
<file>Summary.svg</file>
<file>WindowClose.svg</file>
<file>Warning.svg</file>
<file>Backgrounds/DefaultBackground.jpg</file>
<file>Backgrounds/FtueBackground.jpg</file>
</qresource>
</RCC>
@@ -11,7 +11,6 @@
#include <ProjectInfo.h>
#endif
// due to current limitations, customizing template Gems is disabled
#define TEMPLATE_GEM_CONFIGURATION_ENABLED
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
@@ -61,8 +61,8 @@ namespace O3DE::ProjectManager
{
switch (origin)
{
case O3DEFoundation:
return "Open 3D Foundation";
case Open3DEEngine:
return "Open 3D Engine";
case Local:
return "Local";
default:
@@ -43,7 +43,7 @@ namespace O3DE::ProjectManager
enum GemOrigin
{
O3DEFoundation = 1 << 0,
Open3DEEngine = 1 << 0,
Local = 1 << 1,
NumGemOrigins = 2
};
@@ -99,7 +99,13 @@ namespace O3DE::ProjectManager
painter->drawText(gemCreatorRect, Qt::TextSingleLine, gemCreator);
// Gem summary
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 3, contentRect.height());
// In case there are feature tags displayed at the bottom, decrease the size of the summary text field.
const QStringList featureTags = GemModel::GetFeatures(modelIndex);
const int summaryHeight = contentRect.height() - (!featureTags.empty() * 30);
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 3,
summaryHeight);
const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize);
painter->setFont(standardFont);
@@ -108,9 +114,9 @@ namespace O3DE::ProjectManager
const QString summary = GemModel::GetSummary(modelIndex);
painter->drawText(summaryRect, Qt::AlignLeft | Qt::TextWordWrap, summary);
DrawButton(painter, contentRect, modelIndex);
DrawPlatformIcons(painter, contentRect, modelIndex);
DrawFeatureTags(painter, contentRect, featureTags, standardFont, summaryRect);
painter->restore();
}
@@ -206,6 +212,46 @@ namespace O3DE::ProjectManager
}
}
void GemItemDelegate::DrawFeatureTags(QPainter* painter, const QRect& contentRect, const QStringList& featureTags, const QFont& standardFont, const QRect& summaryRect) const
{
QFont gemFeatureTagFont(standardFont);
gemFeatureTagFont.setPixelSize(s_featureTagFontSize);
gemFeatureTagFont.setBold(false);
painter->setFont(gemFeatureTagFont);
int x = s_summaryStartX;
for (const QString& featureTag : featureTags)
{
QRect featureTagRect = GetTextRect(gemFeatureTagFont, featureTag, s_featureTagFontSize);
featureTagRect.moveTo(contentRect.left() + x + s_featureTagBorderMarginX,
contentRect.top() + 47);
featureTagRect = painter->boundingRect(featureTagRect, Qt::TextSingleLine, featureTag);
QRect backgroundRect = featureTagRect;
backgroundRect = backgroundRect.adjusted(/*left=*/-s_featureTagBorderMarginX,
/*top=*/-s_featureTagBorderMarginY,
/*right=*/s_featureTagBorderMarginX,
/*bottom=*/s_featureTagBorderMarginY);
// Skip drawing all following feature tags as there is no more space available.
if (backgroundRect.right() > summaryRect.right())
{
break;
}
// Draw border.
painter->setPen(m_textColor);
painter->setBrush(Qt::NoBrush);
painter->drawRect(backgroundRect);
// Draw text within the border.
painter->setPen(m_textColor);
painter->drawText(featureTagRect, Qt::TextSingleLine, featureTag);
x += backgroundRect.width() + s_featureTagSpacing;
}
}
void GemItemDelegate::DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const
{
painter->save();
@@ -57,12 +57,19 @@ namespace O3DE::ProjectManager
inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 2;
inline constexpr static qreal s_buttonFontSize = 10.0;
// Feature tags
inline constexpr static int s_featureTagFontSize = 10;
inline constexpr static int s_featureTagBorderMarginX = 3;
inline constexpr static int s_featureTagBorderMarginY = 3;
inline constexpr static int s_featureTagSpacing = 7;
protected:
void CalcRects(const QStyleOptionViewItem& option, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const;
QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const;
QRect CalcButtonRect(const QRect& contentRect) const;
void DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const;
void DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const;
void DrawFeatureTags(QPainter* painter, const QRect& contentRect, const QStringList& featureTags, const QFont& standardFont, const QRect& summaryRect) const;
QAbstractItemModel* m_model = nullptr;
@@ -97,10 +97,21 @@ namespace O3DE::ProjectManager
{
m_templates = templatesResult.GetValue();
// sort alphabetically by display name because they could be in any order
// sort alphabetically by display name (but putting Standard first) because they could be in any order
std::sort(m_templates.begin(), m_templates.end(), [](const ProjectTemplateInfo& arg1, const ProjectTemplateInfo& arg2)
{
return arg1.m_displayName.toLower() < arg2.m_displayName.toLower();
if (arg1.m_displayName == "Standard")
{
return true;
}
else if (arg2.m_displayName == "Standard")
{
return false;
}
else
{
return arg1.m_displayName.toLower() < arg2.m_displayName.toLower();
}
});
for (int index = 0; index < m_templates.size(); ++index)
@@ -19,6 +19,7 @@ QT_FORWARD_DECLARE_CLASS(QFrame)
namespace O3DE::ProjectManager
{
QT_FORWARD_DECLARE_CLASS(TagContainerWidget)
class NewProjectSettingsScreen
: public ProjectSettingsScreen
{
@@ -92,10 +92,18 @@ namespace O3DE::ProjectManager
// Open application assigned to this file type
QDesktopServices::openUrl(QUrl("file:///" + m_worker->GetLogFilePath()));
}
m_projectInfo.m_buildFailed = true;
m_projectInfo.m_logUrl = QUrl("file:///" + m_worker->GetLogFilePath());
emit NotifyBuildProject(m_projectInfo);
}
else
{
QMessageBox::critical(m_parent, tr("Project Failed to Build!"), result);
m_projectInfo.m_buildFailed = true;
m_projectInfo.m_logUrl = QUrl();
emit NotifyBuildProject(m_projectInfo);
}
emit Done(false);
@@ -38,6 +38,7 @@ namespace O3DE::ProjectManager
signals:
void Done(bool success = true);
void NotifyBuildProject(const ProjectInfo& projectInfo);
private:
ProjectInfo m_projectInfo;
@@ -14,7 +14,7 @@
namespace O3DE::ProjectManager
{
const QString ProjectBuilderWorker::BuildCancelled = ProjectBuilderWorker::tr("Build Cancelled.");
const QString ProjectBuilderWorker::BuildCancelled = QObject::tr("Build Cancelled.");
ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo)
: QObject()
@@ -11,6 +11,7 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QEvent>
#include <QResizeEvent>
#include <QLabel>
#include <QPushButton>
@@ -20,6 +21,7 @@
#include <QProgressBar>
#include <QDir>
#include <QFileInfo>
#include <QDesktopServices>
namespace O3DE::ProjectManager
{
@@ -40,8 +42,57 @@ namespace O3DE::ProjectManager
m_overlayLabel->setVisible(false);
vLayout->addWidget(m_overlayLabel);
m_buildOverlayLayout = new QVBoxLayout();
m_buildOverlayLayout->addSpacing(10);
QHBoxLayout* horizontalMessageLayout = new QHBoxLayout();
horizontalMessageLayout->addSpacing(10);
m_warningIcon = new QLabel(this);
m_warningIcon->setPixmap(QIcon(":/Warning.svg").pixmap(20, 20));
m_warningIcon->setAlignment(Qt::AlignTop);
m_warningIcon->setVisible(false);
horizontalMessageLayout->addWidget(m_warningIcon);
horizontalMessageLayout->addSpacing(10);
m_warningText = new QLabel("", this);
m_warningText->setObjectName("projectWarningOverlay");
m_warningText->setWordWrap(true);
m_warningText->setAlignment(Qt::AlignLeft);
m_warningText->setVisible(false);
connect(m_warningText, &QLabel::linkActivated, this, &LabelButton::OnLinkActivated);
horizontalMessageLayout->addWidget(m_warningText);
QSpacerItem* textSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
horizontalMessageLayout->addSpacerItem(textSpacer);
m_buildOverlayLayout->addLayout(horizontalMessageLayout);
QSpacerItem* buttonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
m_buildOverlayLayout->addSpacerItem(buttonSpacer);
QHBoxLayout* horizontalOpenEditorButtonLayout = new QHBoxLayout();
horizontalOpenEditorButtonLayout->addSpacing(34);
m_openEditorButton = new QPushButton(tr("Open Editor"), this);
m_openEditorButton->setObjectName("openEditorButton");
m_openEditorButton->setDefault(true);
m_openEditorButton->setVisible(false);
horizontalOpenEditorButtonLayout->addWidget(m_openEditorButton);
horizontalOpenEditorButtonLayout->addSpacing(34);
m_buildOverlayLayout->addLayout(horizontalOpenEditorButtonLayout);
QHBoxLayout* horizontalButtonLayout = new QHBoxLayout();
horizontalButtonLayout->addSpacing(34);
m_actionButton = new QPushButton(tr("Project Action"), this);
m_actionButton->setVisible(false);
horizontalButtonLayout->addWidget(m_actionButton);
horizontalButtonLayout->addSpacing(34);
m_buildOverlayLayout->addLayout(horizontalButtonLayout);
m_buildOverlayLayout->addSpacing(16);
vLayout->addItem(m_buildOverlayLayout);
m_progressBar = new QProgressBar(this);
m_progressBar->setObjectName("labelButtonProgressBar");
@@ -73,16 +124,41 @@ namespace O3DE::ProjectManager
return m_overlayLabel;
}
void LabelButton::SetLogUrl(const QUrl& url)
{
m_logUrl = url;
}
QProgressBar* LabelButton::GetProgressBar()
{
return m_progressBar;
}
QPushButton* LabelButton::GetOpenEditorButton()
{
return m_openEditorButton;
}
QPushButton* LabelButton::GetActionButton()
{
return m_actionButton;
}
QLabel* LabelButton::GetWarningLabel()
{
return m_warningText;
}
QLabel* LabelButton::GetWarningIcon()
{
return m_warningIcon;
}
void LabelButton::OnLinkActivated(const QString& /*link*/)
{
QDesktopServices::openUrl(m_logUrl);
}
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent, bool processing)
: QFrame(parent)
, m_projectInfo(projectInfo)
@@ -110,7 +186,6 @@ namespace O3DE::ProjectManager
m_projectImageLabel = new LabelButton(this);
m_projectImageLabel->setFixedSize(ProjectPreviewImageWidth, ProjectPreviewImageHeight);
m_projectImageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectInfo.m_path); });
vLayout->addWidget(m_projectImageLabel);
QString projectPreviewPath = QDir(m_projectInfo.m_path).filePath(m_projectInfo.m_iconPath);
@@ -145,6 +220,8 @@ namespace O3DE::ProjectManager
void ProjectButton::ReadySetup()
{
connect(m_projectImageLabel->GetOpenEditorButton(), &QPushButton::clicked, [this](){ emit OpenProject(m_projectInfo.m_path); });
QMenu* menu = new QMenu(this);
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
@@ -170,9 +247,6 @@ namespace O3DE::ProjectManager
QPushButton* projectActionButton = m_projectImageLabel->GetActionButton();
if (!m_actionButtonConnection)
{
QSpacerItem* buttonSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
m_projectImageLabel->layout()->addItem(buttonSpacer);
m_projectImageLabel->layout()->addWidget(projectActionButton);
projectActionButton->setVisible(true);
}
else
@@ -186,6 +260,27 @@ namespace O3DE::ProjectManager
void ProjectButton::SetProjectBuildButtonAction()
{
m_projectImageLabel->GetWarningLabel()->setText(tr("Building project required."));
m_projectImageLabel->GetWarningIcon()->setVisible(true);
m_projectImageLabel->GetWarningLabel()->setVisible(true);
SetProjectButtonAction(tr("Build Project"), [this]() { emit BuildProject(m_projectInfo); });
}
void ProjectButton::ShowBuildFailed(bool show, const QUrl& logUrl)
{
if (!logUrl.isEmpty())
{
m_projectImageLabel->GetWarningLabel()->setText(tr("Failed to build. Click to <a href=\"logs\">view logs</a>."));
}
else
{
m_projectImageLabel->GetWarningLabel()->setText(tr("Project failed to build."));
}
m_projectImageLabel->GetWarningLabel()->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
m_projectImageLabel->GetWarningIcon()->setVisible(show);
m_projectImageLabel->GetWarningLabel()->setVisible(show);
m_projectImageLabel->SetLogUrl(logUrl);
SetProjectButtonAction(tr("Build Project"), [this]() { emit BuildProject(m_projectInfo); });
}
@@ -209,6 +304,16 @@ namespace O3DE::ProjectManager
m_projectImageLabel->GetProgressBar()->setValue(progress);
}
void ProjectButton::enterEvent(QEvent* /*event*/)
{
m_projectImageLabel->GetOpenEditorButton()->setVisible(true);
}
void ProjectButton::leaveEvent(QEvent* /*event*/)
{
m_projectImageLabel->GetOpenEditorButton()->setVisible(false);
}
LabelButton* ProjectButton::GetLabelButton()
{
return m_projectImageLabel;
@@ -20,6 +20,9 @@
QT_FORWARD_DECLARE_CLASS(QPixmap)
QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QProgressBar)
QT_FORWARD_DECLARE_CLASS(QLayout)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
QT_FORWARD_DECLARE_CLASS(QEvent)
namespace O3DE::ProjectManager
{
@@ -34,21 +37,32 @@ namespace O3DE::ProjectManager
void SetEnabled(bool enabled);
void SetOverlayText(const QString& text);
void SetLogUrl(const QUrl& url);
QLabel* GetOverlayLabel();
QProgressBar* GetProgressBar();
QPushButton* GetOpenEditorButton();
QPushButton* GetActionButton();
QLabel* GetWarningLabel();
QLabel* GetWarningIcon();
QLayout* GetBuildOverlayLayout();
signals:
void triggered();
public slots:
void mousePressEvent(QMouseEvent* event) override;
void OnLinkActivated(const QString& link);
private:
QVBoxLayout* m_buildOverlayLayout;
QLabel* m_overlayLabel;
QProgressBar* m_progressBar;
QPushButton* m_openEditorButton;
QPushButton* m_actionButton;
QLabel* m_warningText;
QLabel* m_warningIcon;
QUrl m_logUrl;
bool m_enabled = true;
};
@@ -63,6 +77,7 @@ namespace O3DE::ProjectManager
void SetProjectButtonAction(const QString& text, AZStd::function<void()> lambda);
void SetProjectBuildButtonAction();
void ShowBuildFailed(bool show, const QUrl& logUrl);
void SetLaunchButtonEnabled(bool enabled);
void SetButtonOverlayText(const QString& text);
@@ -81,11 +96,14 @@ namespace O3DE::ProjectManager
void BaseSetup();
void ProcessingSetup();
void ReadySetup();
void enterEvent(QEvent* event) override;
void leaveEvent(QEvent* event) override;
void BuildThisProject();
ProjectInfo m_projectInfo;
LabelButton* m_projectImageLabel;
QFrame* m_projectFooter;
QLayout* m_requiresBuildLayout;
QMetaObject::Connection m_actionButtonConnection;
};
@@ -9,6 +9,7 @@
#if !defined(Q_MOC_RUN)
#include <AzCore/Math/Uuid.h>
#include <QUrl>
#include <QString>
#include <QStringList>
#endif
@@ -54,5 +55,7 @@ namespace O3DE::ProjectManager
// Used in project creation
bool m_needsBuild = false; //! Does this project need to be built
bool m_buildFailed = false;
QUrl m_logUrl;
};
} // namespace O3DE::ProjectManager
@@ -53,8 +53,6 @@ namespace O3DE::ProjectManager
vLayout->setContentsMargins(s_contentMargins, 0, s_contentMargins, 0);
setLayout(vLayout);
m_background.load(":/Backgrounds/FirstTimeBackgroundImage.jpg");
m_stack = new QStackedWidget(this);
m_firstTimeContent = CreateFirstTimeContent();
@@ -117,6 +115,8 @@ namespace O3DE::ProjectManager
QFrame* ProjectsScreen::CreateProjectsContent(QString buildProjectPath, ProjectButton** projectButton)
{
RemoveInvalidProjects();
QFrame* frame = new QFrame(this);
frame->setObjectName("projectsContent");
{
@@ -193,7 +193,19 @@ namespace O3DE::ProjectManager
}
else if (RequiresBuildProjectIterator(project.m_path) != m_requiresBuild.end())
{
projectButtonWidget->SetProjectBuildButtonAction();
auto buildProjectIterator = RequiresBuildProjectIterator(project.m_path);
if (buildProjectIterator != m_requiresBuild.end())
{
if (buildProjectIterator->m_buildFailed)
{
projectButtonWidget->ShowBuildFailed(true, buildProjectIterator->m_logUrl);
}
else
{
projectButtonWidget->SetProjectBuildButtonAction();
}
}
}
}
@@ -232,6 +244,8 @@ namespace O3DE::ProjectManager
m_projectsContent->deleteLater();
}
m_background.load(":/Backgrounds/DefaultBackground.jpg");
// Make sure to update builder with latest Project Button
if (m_currentBuilder)
{
@@ -269,21 +283,30 @@ namespace O3DE::ProjectManager
// 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();
const QSize winSize = size();
const float pixmapRatio = (float)m_background.width() / m_background.height();
const float windowRatio = (float)winSize.width() / winSize.height();
QRect backgroundRect;
if (pixmapRatio > windowRatio)
{
auto newWidth = (int)(winSize.height() * pixmapRatio);
auto offset = (newWidth - winSize.width()) / -2;
painter.drawPixmap(offset, 0, newWidth, winSize.height(), m_background);
const int newWidth = (int)(winSize.height() * pixmapRatio);
const int offset = (newWidth - winSize.width()) / -2;
backgroundRect = QRect(offset, 0, newWidth, winSize.height());
}
else
{
auto newHeight = (int)(winSize.width() / pixmapRatio);
painter.drawPixmap(0, 0, winSize.width(), newHeight, m_background);
const int newHeight = (int)(winSize.width() / pixmapRatio);
backgroundRect = QRect(0, 0, winSize.width(), newHeight);
}
// Draw the background image.
painter.drawPixmap(backgroundRect, m_background);
// Draw a semi-transparent overlay to darken down the colors.
painter.setCompositionMode (QPainter::CompositionMode_DestinationIn);
const float overlayTransparency = 0.7f;
painter.fillRect(backgroundRect, QColor(0, 0, 0, static_cast<int>(255.0f * overlayTransparency)));
}
void ProjectsScreen::HandleNewProjectButton()
@@ -407,7 +430,7 @@ namespace O3DE::ProjectManager
void ProjectsScreen::SuggestBuildProjectMsg(const ProjectInfo& projectInfo, bool showMessage)
{
if (RequiresBuildProjectIterator(projectInfo.m_path) == m_requiresBuild.end())
if (RequiresBuildProjectIterator(projectInfo.m_path) == m_requiresBuild.end() || projectInfo.m_buildFailed)
{
m_requiresBuild.append(projectInfo);
}
@@ -459,6 +482,7 @@ namespace O3DE::ProjectManager
{
if (ShouldDisplayFirstTimeContent())
{
m_background.load(":/Backgrounds/FtueBackground.jpg");
m_stack->setCurrentWidget(m_firstTimeContent);
}
else
@@ -485,6 +509,11 @@ namespace O3DE::ProjectManager
return displayFirstTimeContent;
}
bool ProjectsScreen::RemoveInvalidProjects()
{
return PythonBindingsInterface::Get()->RemoveInvalidProjects();
}
bool ProjectsScreen::StartProjectBuild(const ProjectInfo& projectInfo)
{
if (ProjectUtils::IsVS2019Installed())
@@ -500,6 +529,7 @@ namespace O3DE::ProjectManager
m_currentBuilder = new ProjectBuilderController(projectInfo, nullptr, this);
ResetProjectsContent();
connect(m_currentBuilder, &ProjectBuilderController::Done, this, &ProjectsScreen::ProjectBuildDone);
connect(m_currentBuilder, &ProjectBuilderController::NotifyBuildProject, this, &ProjectsScreen::SuggestBuildProject);
m_currentBuilder->Start();
}
@@ -62,6 +62,7 @@ namespace O3DE::ProjectManager
ProjectButton* CreateProjectButton(ProjectInfo& project, QLayout* flowLayout, bool processing = false);
void ResetProjectsContent();
bool ShouldDisplayFirstTimeContent();
bool RemoveInvalidProjects();
bool StartProjectBuild(const ProjectInfo& projectInfo);
QList<ProjectInfo>::iterator RequiresBuildProjectIterator(const QString& projectPath);
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -23,6 +23,8 @@
#include <AzCore/std/string/conversions.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <QDir>
namespace Platform
{
bool InsertPythonLibraryPath(
@@ -42,7 +44,7 @@ namespace Platform
return false;
}
// Implemented in each different platform's PAL implentation files, as it differs per platform.
// Implemented in each different platform's PAL implementation files, as it differs per platform.
AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot);
} // namespace Platform
@@ -650,6 +652,12 @@ namespace O3DE::ProjectManager
gemInfo.m_summary = Py_To_String_Optional(data, "summary", "");
gemInfo.m_version = "";
gemInfo.m_requirement = Py_To_String_Optional(data, "requirements", "");
gemInfo.m_creator = Py_To_String_Optional(data, "origin", "");
if (gemInfo.m_creator.contains("Open 3D Engine"))
{
gemInfo.m_gemOrigin = GemInfo::GemOrigin::Open3DEEngine;
}
if (data.contains("user_tags"))
{
@@ -769,6 +777,21 @@ namespace O3DE::ProjectManager
});
}
bool PythonBindings::RemoveInvalidProjects()
{
bool removalResult = false;
bool result = ExecuteWithLock(
[&]
{
auto pythonRemovalResult = m_register.attr("remove_invalid_o3de_projects")();
// Returns an exit code so boolify it then invert result
removalResult = !pythonRemovalResult.cast<bool>();
});
return result && removalResult;
}
AZ::Outcome<void, AZStd::string> PythonBindings::UpdateProject(const ProjectInfo& projectInfo)
{
bool updateProjectSucceeded = false;
@@ -836,11 +859,19 @@ namespace O3DE::ProjectManager
templateInfo.m_canonicalTags.push_back(Py_To_String(tag));
}
}
if (data.contains("included_gems"))
QString templateProjectPath = QDir(templateInfo.m_path).filePath("Template");
auto enabledGemNames = GetEnabledGemNames(templateProjectPath);
if (enabledGemNames)
{
for (auto gem : data["included_gems"])
for (auto gem : enabledGemNames.GetValue())
{
templateInfo.m_includedGems.push_back(Py_To_String(gem));
// Exclude the template ${Name} placeholder for the list of included gems
// That Gem gets created with the project
if (!gem.contains("${Name}"))
{
templateInfo.m_includedGems.push_back(Py_To_String(gem.c_str()));
}
}
}
}
@@ -50,6 +50,7 @@ namespace O3DE::ProjectManager
AZ::Outcome<void, AZStd::string> UpdateProject(const ProjectInfo& projectInfo) override;
AZ::Outcome<void, AZStd::string> AddGemToProject(const QString& gemPath, const QString& projectPath) override;
AZ::Outcome<void, AZStd::string> RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override;
bool RemoveInvalidProjects() override;
// ProjectTemplate
AZ::Outcome<QVector<ProjectTemplateInfo>> GetProjectTemplates(const QString& projectPath = {}) override;
@@ -141,6 +141,11 @@ namespace O3DE::ProjectManager
*/
virtual AZ::Outcome<void, AZStd::string> RemoveGemFromProject(const QString& gemPath, const QString& projectPath) = 0;
/**
* Removes invalid projects from the manifest
*/
virtual bool RemoveInvalidProjects() = 0;
// Project Templates