Merge branch 'main' into transform-float-scale-3
This commit is contained in:
@@ -336,4 +336,31 @@ QTabBar::tab:pressed
|
||||
max-width:210px;;
|
||||
min-height:278px;
|
||||
max-height:278px;
|
||||
}
|
||||
}
|
||||
|
||||
/************** Gem Catalog **************/
|
||||
|
||||
#GemCatalogTitle {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/************** Gem Catalog (Inspector) **************/
|
||||
|
||||
#GemCatalogInspector {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/************** Gem Catalog (Filter/left pane) **************/
|
||||
|
||||
#GemCatalogFilterWidget {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
#GemCatalogHeaderWidget {
|
||||
background-color: #1E252F;
|
||||
}
|
||||
|
||||
#GemCatalogFilterCategoryTitle {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ namespace O3DE::ProjectManager
|
||||
hLayout->setMargin(0);
|
||||
setLayout(hLayout);
|
||||
|
||||
setStyleSheet("background-color: #1E252F;");
|
||||
setObjectName("GemCatalogHeaderWidget");
|
||||
|
||||
hLayout->addSpacing(7);
|
||||
|
||||
QLabel* titleLabel = new QLabel(tr("Gem Catalog"));
|
||||
titleLabel->setStyleSheet("font-size: 21px;");
|
||||
titleLabel->setObjectName("GemCatalogTitle");
|
||||
hLayout->addWidget(titleLabel);
|
||||
|
||||
hLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
|
||||
@@ -42,7 +44,7 @@ namespace O3DE::ProjectManager
|
||||
hLayout->addWidget(filterLineEdit);
|
||||
|
||||
hLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
|
||||
hLayout->addSpacerItem(new QSpacerItem(220, 0, QSizePolicy::Fixed));
|
||||
hLayout->addSpacerItem(new QSpacerItem(140, 0, QSizePolicy::Fixed));
|
||||
|
||||
setFixedHeight(60);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace O3DE::ProjectManager
|
||||
m_collapseButton->setFlat(true);
|
||||
m_collapseButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_collapseButton->setFixedWidth(s_collapseButtonSize);
|
||||
m_collapseButton->setStyleSheet("border: 0px; border-radius: 0px;");
|
||||
connect(m_collapseButton, &QPushButton::clicked, this, [=]()
|
||||
{
|
||||
UpdateCollapseState();
|
||||
@@ -52,7 +51,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
// Category title
|
||||
QLabel* headerLabel = new QLabel(header);
|
||||
headerLabel->setStyleSheet("font-size: 11pt;");
|
||||
headerLabel->setObjectName("GemCatalogFilterCategoryTitle");
|
||||
collapseLayout->addWidget(headerLabel);
|
||||
vLayout->addLayout(collapseLayout);
|
||||
|
||||
@@ -79,14 +78,14 @@ namespace O3DE::ProjectManager
|
||||
elementWidget->setLayout(elementLayout);
|
||||
|
||||
QCheckBox* checkbox = new QCheckBox(elementNames[i]);
|
||||
checkbox->setStyleSheet("font-size: 11pt;");
|
||||
checkbox->setStyleSheet("font-size: 12px;");
|
||||
m_buttonGroup->addButton(checkbox);
|
||||
elementLayout->addWidget(checkbox);
|
||||
|
||||
elementLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
|
||||
|
||||
QLabel* countLabel = new QLabel(QString::number(elementCounts[i]));
|
||||
countLabel->setStyleSheet("font-size: 11pt; background-color: #333333; border-radius: 3px; color: #94D2FF;");
|
||||
countLabel->setStyleSheet("font-size: 12px; background-color: #333333; border-radius: 3px; color: #94D2FF;");
|
||||
elementLayout->addWidget(countLabel);
|
||||
|
||||
m_elementWidgets.push_back(elementWidget);
|
||||
@@ -110,6 +109,8 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
vLayout->addSpacing(5);
|
||||
|
||||
// Separating line
|
||||
QFrame* hLine = new QFrame();
|
||||
hLine->setFrameShape(QFrame::HLine);
|
||||
@@ -181,6 +182,8 @@ namespace O3DE::ProjectManager
|
||||
: QScrollArea(parent)
|
||||
, m_filterProxyModel(filterProxyModel)
|
||||
{
|
||||
setObjectName("GemCatalogFilterWidget");
|
||||
|
||||
m_gemModel = m_filterProxyModel->GetSourceModel();
|
||||
|
||||
setWidgetResizable(true);
|
||||
@@ -195,7 +198,7 @@ namespace O3DE::ProjectManager
|
||||
mainWidget->setLayout(m_mainLayout);
|
||||
|
||||
QLabel* filterByLabel = new QLabel("Filter by");
|
||||
filterByLabel->setStyleSheet("font-size: 15pt;");
|
||||
filterByLabel->setStyleSheet("font-size: 16px;");
|
||||
m_mainLayout->addWidget(filterByLabel);
|
||||
|
||||
AddGemOriginFilter();
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace O3DE::ProjectManager
|
||||
: QScrollArea(parent)
|
||||
, m_model(model)
|
||||
{
|
||||
setObjectName("GemCatalogInspector");
|
||||
setWidgetResizable(true);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
@@ -85,7 +86,7 @@ namespace O3DE::ProjectManager
|
||||
QLabel* GemInspector::CreateStyledLabel(QLayout* layout, int fontSize, const QString& colorCodeString)
|
||||
{
|
||||
QLabel* result = new QLabel();
|
||||
result->setStyleSheet(QString("font-size: %1pt; color: %2;").arg(QString::number(fontSize), colorCodeString));
|
||||
result->setStyleSheet(QString("font-size: %1px; color: %2;").arg(QString::number(fontSize), colorCodeString));
|
||||
layout->addWidget(result);
|
||||
return result;
|
||||
}
|
||||
@@ -93,13 +94,13 @@ namespace O3DE::ProjectManager
|
||||
void GemInspector::InitMainWidget()
|
||||
{
|
||||
// Gem name, creator and summary
|
||||
m_nameLabel = CreateStyledLabel(m_mainLayout, 17, s_headerColor);
|
||||
m_nameLabel = CreateStyledLabel(m_mainLayout, 18, s_headerColor);
|
||||
m_creatorLabel = CreateStyledLabel(m_mainLayout, 12, s_creatorColor);
|
||||
m_mainLayout->addSpacing(5);
|
||||
|
||||
// TODO: QLabel seems to have issues determining the right sizeHint() for our font with the given font size.
|
||||
// This results into squeezed elements in the layout in case the text is a little longer than a sentence.
|
||||
m_summaryLabel = new QLabel();//CreateLabel(m_mainLayout, 12, s_textColor);
|
||||
m_summaryLabel = CreateStyledLabel(m_mainLayout, 12, s_textColor);
|
||||
m_mainLayout->addWidget(m_summaryLabel);
|
||||
m_summaryLabel->setWordWrap(true);
|
||||
m_mainLayout->addSpacing(5);
|
||||
@@ -146,9 +147,9 @@ namespace O3DE::ProjectManager
|
||||
QLabel* additionalInfoLabel = CreateStyledLabel(m_mainLayout, 14, s_headerColor);
|
||||
additionalInfoLabel->setText("Additional Information");
|
||||
|
||||
m_versionLabel = CreateStyledLabel(m_mainLayout, 11, s_textColor);
|
||||
m_lastUpdatedLabel = CreateStyledLabel(m_mainLayout, 11, s_textColor);
|
||||
m_binarySizeLabel = CreateStyledLabel(m_mainLayout, 11, s_textColor);
|
||||
m_versionLabel = CreateStyledLabel(m_mainLayout, 12, s_textColor);
|
||||
m_lastUpdatedLabel = CreateStyledLabel(m_mainLayout, 12, s_textColor);
|
||||
m_binarySizeLabel = CreateStyledLabel(m_mainLayout, 12, s_textColor);
|
||||
}
|
||||
|
||||
GemInspector::GemsSubWidget::GemsSubWidget(QWidget* parent)
|
||||
@@ -159,8 +160,8 @@ namespace O3DE::ProjectManager
|
||||
m_layout->setMargin(0);
|
||||
setLayout(m_layout);
|
||||
|
||||
m_titleLabel = GemInspector::CreateStyledLabel(m_layout, 15, s_headerColor);
|
||||
m_textLabel = GemInspector::CreateStyledLabel(m_layout, 9, s_textColor);
|
||||
m_titleLabel = GemInspector::CreateStyledLabel(m_layout, 16, s_headerColor);
|
||||
m_textLabel = GemInspector::CreateStyledLabel(m_layout, 10, s_textColor);
|
||||
m_textLabel->setWordWrap(true);
|
||||
|
||||
m_tagWidget = new TagContainerWidget();
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace O3DE::ProjectManager
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QRect fullRect, itemRect, contentRect;
|
||||
CalcRects(options, modelIndex, fullRect, itemRect, contentRect);
|
||||
CalcRects(options, fullRect, itemRect, contentRect);
|
||||
|
||||
QFont standardFont(options.font);
|
||||
standardFont.setPixelSize(s_fontSize);
|
||||
@@ -99,7 +99,7 @@ namespace O3DE::ProjectManager
|
||||
painter->drawText(gemCreatorRect, Qt::TextSingleLine, gemCreator);
|
||||
|
||||
// Gem summary
|
||||
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 4, contentRect.height());
|
||||
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 3, contentRect.height());
|
||||
const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize);
|
||||
|
||||
painter->setFont(standardFont);
|
||||
@@ -134,12 +134,10 @@ namespace O3DE::ProjectManager
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, modelIndex);
|
||||
}
|
||||
|
||||
void GemItemDelegate::CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const
|
||||
void GemItemDelegate::CalcRects(const QStyleOptionViewItem& option, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const
|
||||
{
|
||||
const bool isFirst = modelIndex.row() == 0;
|
||||
|
||||
outFullRect = QRect(option.rect);
|
||||
outItemRect = QRect(outFullRect.adjusted(s_itemMargins.left(), isFirst ? s_itemMargins.top() * 2 : s_itemMargins.top(), -s_itemMargins.right(), -s_itemMargins.bottom()));
|
||||
outItemRect = QRect(outFullRect.adjusted(s_itemMargins.left(), s_itemMargins.top(), -s_itemMargins.right(), -s_itemMargins.bottom()));
|
||||
outContentRect = QRect(outItemRect.adjusted(s_contentMargins.left(), s_contentMargins.top(), -s_contentMargins.right(), -s_contentMargins.bottom()));
|
||||
}
|
||||
|
||||
@@ -194,12 +192,12 @@ namespace O3DE::ProjectManager
|
||||
painter->setBrush(m_buttonEnabledColor);
|
||||
painter->setPen(m_buttonEnabledColor);
|
||||
|
||||
circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius, 1);
|
||||
circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius + 1, 1);
|
||||
buttonText = "Added";
|
||||
}
|
||||
else
|
||||
{
|
||||
circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius + 1, 1);
|
||||
circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius, 1);
|
||||
buttonText = "Get";
|
||||
}
|
||||
|
||||
|
||||
@@ -45,25 +45,25 @@ namespace O3DE::ProjectManager
|
||||
const QColor m_buttonEnabledColor = QColor("#00B931");
|
||||
|
||||
// Item
|
||||
inline constexpr static int s_height = 135; // Gem item total height
|
||||
inline constexpr static qreal s_gemNameFontSize = 16.0;
|
||||
inline constexpr static qreal s_fontSize = 15.0;
|
||||
inline constexpr static int s_summaryStartX = 200;
|
||||
inline constexpr static int s_height = 105; // Gem item total height
|
||||
inline constexpr static qreal s_gemNameFontSize = 13.0;
|
||||
inline constexpr static qreal s_fontSize = 12.0;
|
||||
inline constexpr static int s_summaryStartX = 150;
|
||||
|
||||
// Margin and borders
|
||||
inline constexpr static QMargins s_itemMargins = QMargins(/*left=*/20, /*top=*/10, /*right=*/20, /*bottom=*/10); // Item border distances
|
||||
inline constexpr static QMargins s_contentMargins = QMargins(/*left=*/15, /*top=*/12, /*right=*/12, /*bottom=*/12); // Distances of the elements within an item to the item borders
|
||||
inline constexpr static QMargins s_itemMargins = QMargins(/*left=*/16, /*top=*/8, /*right=*/16, /*bottom=*/8); // Item border distances
|
||||
inline constexpr static QMargins s_contentMargins = QMargins(/*left=*/20, /*top=*/12, /*right=*/15, /*bottom=*/12); // Distances of the elements within an item to the item borders
|
||||
inline constexpr static int s_borderWidth = 4;
|
||||
|
||||
// Button
|
||||
inline constexpr static int s_buttonWidth = 70;
|
||||
inline constexpr static int s_buttonHeight = 24;
|
||||
inline constexpr static int s_buttonBorderRadius = 12;
|
||||
inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 3;
|
||||
inline constexpr static qreal s_buttonFontSize = 12.0;
|
||||
inline constexpr static int s_buttonWidth = 55;
|
||||
inline constexpr static int s_buttonHeight = 18;
|
||||
inline constexpr static int s_buttonBorderRadius = 9;
|
||||
inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 2;
|
||||
inline constexpr static qreal s_buttonFontSize = 10.0;
|
||||
|
||||
private:
|
||||
void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const;
|
||||
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;
|
||||
@@ -73,7 +73,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
// Platform icons
|
||||
void AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath);
|
||||
inline constexpr static int s_platformIconSize = 16;
|
||||
inline constexpr static int s_platformIconSize = 12;
|
||||
QHash<GemInfo::Platform, QPixmap> m_platformIcons;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace O3DE::ProjectManager
|
||||
topLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
|
||||
|
||||
QLabel* showCountLabel = new QLabel();
|
||||
showCountLabel->setStyleSheet("font-size: 11pt; font: italic;");
|
||||
showCountLabel->setStyleSheet("font-size: 12px; font: italic;");
|
||||
topLayout->addWidget(showCountLabel);
|
||||
connect(proxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=]
|
||||
{
|
||||
@@ -61,16 +61,17 @@ namespace O3DE::ProjectManager
|
||||
QHBoxLayout* columnHeaderLayout = new QHBoxLayout();
|
||||
columnHeaderLayout->setAlignment(Qt::AlignLeft);
|
||||
|
||||
columnHeaderLayout->addSpacing(31);
|
||||
const int gemNameStartX = GemItemDelegate::s_itemMargins.left() + GemItemDelegate::s_contentMargins.left() - 3;
|
||||
columnHeaderLayout->addSpacing(gemNameStartX);
|
||||
|
||||
QLabel* gemNameLabel = new QLabel(tr("Gem Name"));
|
||||
gemNameLabel->setStyleSheet("font-size: 11pt;");
|
||||
gemNameLabel->setStyleSheet("font-size: 12px;");
|
||||
columnHeaderLayout->addWidget(gemNameLabel);
|
||||
|
||||
columnHeaderLayout->addSpacing(111);
|
||||
columnHeaderLayout->addSpacing(77);
|
||||
|
||||
QLabel* gemSummaryLabel = new QLabel(tr("Gem Summary"));
|
||||
gemSummaryLabel->setStyleSheet("font-size: 11pt;");
|
||||
gemSummaryLabel->setStyleSheet("font-size: 12px;");
|
||||
columnHeaderLayout->addWidget(gemSummaryLabel);
|
||||
|
||||
vLayout->addLayout(columnHeaderLayout);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void LinkLabel::enterEvent([[maybe_unused]] QEvent* event)
|
||||
{
|
||||
setStyleSheet("font-size: 9pt; color: #94D2FF; text-decoration: underline;");
|
||||
setStyleSheet("font-size: 10px; color: #94D2FF; text-decoration: underline;");
|
||||
}
|
||||
|
||||
void LinkLabel::leaveEvent([[maybe_unused]] QEvent* event)
|
||||
@@ -52,6 +52,6 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void LinkLabel::SetDefaultStyle()
|
||||
{
|
||||
setStyleSheet("font-size: 9pt; color: #94D2FF;");
|
||||
setStyleSheet("font-size: 10px; color: #94D2FF;");
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QResizeEvent>
|
||||
@@ -58,19 +59,15 @@ namespace O3DE::ProjectManager
|
||||
m_overlayLabel->setText(text);
|
||||
}
|
||||
|
||||
ProjectButton::ProjectButton(const QString& projectName, QWidget* parent)
|
||||
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_projectName(projectName)
|
||||
, m_projectImagePath(":/Resources/DefaultProjectImage.png")
|
||||
, m_projectInfo(projectInfo)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
if (m_projectInfo.m_imagePath.isEmpty())
|
||||
{
|
||||
m_projectInfo.m_imagePath = ":/DefaultProjectImage.png";
|
||||
}
|
||||
|
||||
ProjectButton::ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_projectName(projectName)
|
||||
, m_projectImagePath(projectImage)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
@@ -85,20 +82,22 @@ namespace O3DE::ProjectManager
|
||||
|
||||
m_projectImageLabel = new LabelButton(this);
|
||||
m_projectImageLabel->setFixedSize(s_projectImageWidth, s_projectImageHeight);
|
||||
m_projectImageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
vLayout->addWidget(m_projectImageLabel);
|
||||
|
||||
m_projectImageLabel->setPixmap(QPixmap(m_projectImagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding));
|
||||
m_projectImageLabel->setPixmap(
|
||||
QPixmap(m_projectInfo.m_imagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding));
|
||||
|
||||
QMenu* newProjectMenu = new QMenu(this);
|
||||
m_editProjectAction = newProjectMenu->addAction(tr("Edit Project Settings..."));
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems..."));
|
||||
newProjectMenu->addSeparator();
|
||||
m_copyProjectAction = newProjectMenu->addAction(tr("Duplicate"));
|
||||
newProjectMenu->addSeparator();
|
||||
m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE"));
|
||||
m_deleteProjectAction = newProjectMenu->addAction(tr("Delete the Project"));
|
||||
m_deleteProjectAction = newProjectMenu->addAction(tr("Delete this Project"));
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems..."));
|
||||
#endif
|
||||
|
||||
QFrame* footer = new QFrame(this);
|
||||
@@ -106,7 +105,7 @@ namespace O3DE::ProjectManager
|
||||
hLayout->setContentsMargins(0, 0, 0, 0);
|
||||
footer->setLayout(hLayout);
|
||||
{
|
||||
QLabel* projectNameLabel = new QLabel(m_projectName, this);
|
||||
QLabel* projectNameLabel = new QLabel(m_projectInfo.m_displayName, this);
|
||||
hLayout->addWidget(projectNameLabel);
|
||||
|
||||
QPushButton* projectMenuButton = new QPushButton(this);
|
||||
@@ -117,14 +116,14 @@ namespace O3DE::ProjectManager
|
||||
|
||||
vLayout->addWidget(footer);
|
||||
|
||||
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); });
|
||||
connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); });
|
||||
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectInfo.m_path); });
|
||||
connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectInfo.m_path); });
|
||||
connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectInfo.m_path); });
|
||||
connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectInfo.m_path); });
|
||||
connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectInfo.m_path); });
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectName); });
|
||||
connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectName); });
|
||||
connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectName); });
|
||||
connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectName); });
|
||||
connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QFrame>
|
||||
#include <ProjectInfo.h>
|
||||
|
||||
#include <QLabel>
|
||||
#endif
|
||||
|
||||
@@ -52,8 +53,7 @@ namespace O3DE::ProjectManager
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
explicit ProjectButton(const QString& projectName, QWidget* parent = nullptr);
|
||||
explicit ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent = nullptr);
|
||||
explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr);
|
||||
~ProjectButton() = default;
|
||||
|
||||
void SetButtonEnabled(bool enabled);
|
||||
@@ -70,8 +70,7 @@ namespace O3DE::ProjectManager
|
||||
private:
|
||||
void Setup();
|
||||
|
||||
QString m_projectName;
|
||||
QString m_projectImagePath;
|
||||
ProjectInfo m_projectInfo;
|
||||
LabelButton* m_projectImageLabel;
|
||||
QAction* m_editProjectAction;
|
||||
QAction* m_editProjectGemsAction;
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 <ProjectUtils.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
namespace ProjectUtils
|
||||
{
|
||||
static bool WarnDirectoryOverwrite(const QString& path, QWidget* parent)
|
||||
{
|
||||
if (!QDir(path).isEmpty())
|
||||
{
|
||||
QMessageBox::StandardButton warningResult = QMessageBox::warning(
|
||||
parent,
|
||||
QObject::tr("Overwrite Directory"),
|
||||
QObject::tr("Directory is not empty! Are you sure you want to overwrite it?"),
|
||||
QMessageBox::No | QMessageBox::Yes
|
||||
);
|
||||
|
||||
if (warningResult != QMessageBox::Yes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsDirectoryDescedent(const QString& possibleAncestorPath, const QString& possibleDecedentPath)
|
||||
{
|
||||
QDir ancestor(possibleAncestorPath);
|
||||
QDir descendent(possibleDecedentPath);
|
||||
|
||||
do
|
||||
{
|
||||
if (ancestor == descendent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
descendent.cdUp();
|
||||
}
|
||||
while (!descendent.isRoot());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CopyDirectory(const QString& origPath, const QString& newPath)
|
||||
{
|
||||
QDir original(origPath);
|
||||
if (!original.exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (QString directory : original.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
||||
{
|
||||
QString newDirectoryPath = newPath + QDir::separator() + directory;
|
||||
original.mkpath(newDirectoryPath);
|
||||
|
||||
if (!CopyDirectory(origPath + QDir::separator() + directory, newDirectoryPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (QString file : original.entryList(QDir::Files))
|
||||
{
|
||||
if (!QFile::copy(origPath + QDir::separator() + file, newPath + QDir::separator() + file))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddProjectDialog(QWidget* parent)
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent, QObject::tr("Select Project Directory")));
|
||||
if (!path.isEmpty())
|
||||
{
|
||||
return RegisterProject(path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterProject(const QString& path)
|
||||
{
|
||||
return PythonBindingsInterface::Get()->AddProject(path);
|
||||
}
|
||||
|
||||
bool UnregisterProject(const QString& path)
|
||||
{
|
||||
return PythonBindingsInterface::Get()->RemoveProject(path);
|
||||
}
|
||||
|
||||
bool CopyProjectDialog(const QString& origPath, QWidget* parent)
|
||||
{
|
||||
bool copyResult = false;
|
||||
|
||||
QDir parentOrigDir(origPath);
|
||||
parentOrigDir.cdUp();
|
||||
QString newPath = QDir::toNativeSeparators(
|
||||
QFileDialog::getExistingDirectory(parent, QObject::tr("Select New Project Directory"), parentOrigDir.path()));
|
||||
if (!newPath.isEmpty())
|
||||
{
|
||||
if (!WarnDirectoryOverwrite(newPath, parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Block UX and Notify User they need to wait
|
||||
|
||||
copyResult = CopyProject(origPath, newPath);
|
||||
}
|
||||
|
||||
return copyResult;
|
||||
}
|
||||
|
||||
bool CopyProject(const QString& origPath, const QString& newPath)
|
||||
{
|
||||
// Disallow copying from or into subdirectory
|
||||
if (!IsDirectoryDescedent(origPath, newPath) || !IsDirectoryDescedent(newPath, origPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CopyDirectory(origPath, newPath))
|
||||
{
|
||||
// Cleanup whatever mess was made
|
||||
DeleteProjectFiles(newPath, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!RegisterProject(newPath))
|
||||
{
|
||||
DeleteProjectFiles(newPath, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeleteProjectFiles(const QString& path, bool force)
|
||||
{
|
||||
QDir projectDirectory(path);
|
||||
if (projectDirectory.exists())
|
||||
{
|
||||
// Check if there is an actual project hereor just force it
|
||||
if (force || PythonBindingsInterface::Get()->GetProject(path).IsSuccess())
|
||||
{
|
||||
return projectDirectory.removeRecursively();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MoveProject(const QString& origPath, const QString& newPath, QWidget* parent)
|
||||
{
|
||||
if (!WarnDirectoryOverwrite(newPath, parent) || !UnregisterProject(origPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir directory;
|
||||
if (directory.rename(origPath, newPath))
|
||||
{
|
||||
return directory.rename(origPath, newPath);
|
||||
}
|
||||
|
||||
if (!RegisterProject(newPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ProjectUtils
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
namespace ProjectUtils
|
||||
{
|
||||
bool AddProjectDialog(QWidget* parent = nullptr);
|
||||
bool RegisterProject(const QString& path);
|
||||
bool UnregisterProject(const QString& path);
|
||||
bool CopyProjectDialog(const QString& origPath, QWidget* parent = nullptr);
|
||||
bool CopyProject(const QString& origPath, const QString& newPath);
|
||||
bool DeleteProjectFiles(const QString& path, bool force = false);
|
||||
bool MoveProject(const QString& origPath, const QString& newPath, QWidget* parent = nullptr);
|
||||
} // namespace ProjectUtils
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <ProjectUtils.h>
|
||||
|
||||
#include <AzQtComponents/Components/FlowLayout.h>
|
||||
#include <AzCore/Platform.h>
|
||||
@@ -65,9 +66,6 @@ namespace O3DE::ProjectManager
|
||||
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()
|
||||
@@ -167,28 +165,27 @@ namespace O3DE::ProjectManager
|
||||
#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);
|
||||
project.m_imagePath = projectPreviewPath;
|
||||
}
|
||||
|
||||
projectButton = new ProjectButton(project, 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
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
|
||||
#endif
|
||||
}
|
||||
|
||||
layout->addWidget(projectsScrollArea);
|
||||
@@ -242,7 +239,11 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
void ProjectsScreen::HandleAddProjectButton()
|
||||
{
|
||||
// Do nothing for now
|
||||
if (ProjectUtils::AddProjectDialog(this))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleOpenProject(const QString& projectPath)
|
||||
{
|
||||
@@ -300,18 +301,36 @@ namespace O3DE::ProjectManager
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
|
||||
}
|
||||
void ProjectsScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleCopyProject(const QString& projectPath)
|
||||
{
|
||||
// Open file dialog and choose location for copied project then register copy with O3DE
|
||||
if (ProjectUtils::CopyProjectDialog(projectPath, this))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleRemoveProject(const QString& projectPath)
|
||||
{
|
||||
// Unregister Project from O3DE
|
||||
// Unregister Project from O3DE and reload projects
|
||||
if (ProjectUtils::UnregisterProject(projectPath))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleDeleteProject(const QString& projectPath)
|
||||
{
|
||||
// Remove project from 03DE and delete from disk
|
||||
ProjectsScreen::HandleRemoveProject(projectPath);
|
||||
QMessageBox::StandardButton warningResult = QMessageBox::warning(
|
||||
this, tr("Delete Project"), tr("Are you sure?\nProject will be removed from O3DE and directory will be deleted!"),
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
|
||||
if (warningResult == QMessageBox::Yes)
|
||||
{
|
||||
// Remove project from O3DE and delete from disk
|
||||
HandleRemoveProject(projectPath);
|
||||
ProjectUtils::DeleteProjectFiles(projectPath);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::NotifyCurrentScreen()
|
||||
|
||||
@@ -379,13 +379,13 @@ namespace O3DE::ProjectManager
|
||||
pybind11::str defaultTemplatesFolder = engineInfo.m_defaultTemplatesFolder.toStdString();
|
||||
|
||||
auto registrationResult = m_registration.attr("register")(
|
||||
enginePath, // engine_path
|
||||
pybind11::none(), // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
enginePath, // engine_path
|
||||
pybind11::none(), // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
defaultProjectsFolder,
|
||||
defaultGemsFolder,
|
||||
defaultTemplatesFolder
|
||||
@@ -456,6 +456,51 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
bool PythonBindings::AddProject(const QString& path)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
bool result = ExecuteWithLock(
|
||||
[&]
|
||||
{
|
||||
pybind11::str projectPath = path.toStdString();
|
||||
auto pythonRegistrationResult = m_registration.attr("register")(pybind11::none(), projectPath);
|
||||
|
||||
// Returns an exit code so boolify it then invert result
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
return result && registrationResult;
|
||||
}
|
||||
|
||||
bool PythonBindings::RemoveProject(const QString& path)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
bool result = ExecuteWithLock(
|
||||
[&]
|
||||
{
|
||||
pybind11::str projectPath = path.toStdString();
|
||||
auto pythonRegistrationResult = m_registration.attr("register")(
|
||||
pybind11::none(), // engine_path
|
||||
projectPath, // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
pybind11::none(), // default_gems_folder
|
||||
pybind11::none(), // default_templates_folder
|
||||
pybind11::none(), // default_restricted_folder
|
||||
pybind11::none(), // default_restricted_folder
|
||||
true // remove
|
||||
);
|
||||
|
||||
// Returns an exit code so boolify it then invert result
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
return result && registrationResult;
|
||||
}
|
||||
|
||||
AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo)
|
||||
{
|
||||
ProjectInfo createdProjectInfo;
|
||||
@@ -600,7 +645,7 @@ namespace O3DE::ProjectManager
|
||||
pybind11::none(), // gem_target
|
||||
pybind11::none(), // project_name
|
||||
pyProjectPath
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
return result;
|
||||
@@ -618,7 +663,7 @@ namespace O3DE::ProjectManager
|
||||
pybind11::none(), // gem_target
|
||||
pybind11::none(), // project_name
|
||||
pyProjectPath
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace O3DE::ProjectManager
|
||||
AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override;
|
||||
AZ::Outcome<ProjectInfo> GetProject(const QString& path) override;
|
||||
AZ::Outcome<QVector<ProjectInfo>> GetProjects() override;
|
||||
bool AddProject(const QString& path) override;
|
||||
bool RemoveProject(const QString& path) override;
|
||||
bool UpdateProject(const ProjectInfo& projectInfo) override;
|
||||
bool AddGemToProject(const QString& gemPath, const QString& projectPath) override;
|
||||
bool RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override;
|
||||
|
||||
@@ -88,6 +88,20 @@ namespace O3DE::ProjectManager
|
||||
* @return an outcome with ProjectInfos on success
|
||||
*/
|
||||
virtual AZ::Outcome<QVector<ProjectInfo>> GetProjects() = 0;
|
||||
|
||||
/**
|
||||
* Adds existing project on disk
|
||||
* @param path the absolute path to the project
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
virtual bool AddProject(const QString& path) = 0;
|
||||
|
||||
/**
|
||||
* Adds existing project on disk
|
||||
* @param path the absolute path to the project
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
virtual bool RemoveProject(const QString& path) = 0;
|
||||
|
||||
/**
|
||||
* Update a project
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace O3DE::ProjectManager
|
||||
TagWidget::TagWidget(const QString& text, QWidget* parent)
|
||||
: QLabel(text, parent)
|
||||
{
|
||||
setFixedHeight(35);
|
||||
setFixedHeight(24);
|
||||
setMargin(5);
|
||||
setStyleSheet("font-size: 12pt; background-color: #333333; border-radius: 4px;");
|
||||
setStyleSheet("font-size: 12px; background-color: #333333; border-radius: 3px;");
|
||||
}
|
||||
|
||||
TagContainerWidget::TagContainerWidget(QWidget* parent)
|
||||
@@ -35,7 +35,7 @@ namespace O3DE::ProjectManager
|
||||
void TagContainerWidget::Update(const QStringList& tags)
|
||||
{
|
||||
QWidget* parentWidget = qobject_cast<QWidget*>(parent());
|
||||
int width = 250;
|
||||
int width = 200;
|
||||
if (parentWidget)
|
||||
{
|
||||
width = parentWidget->width();
|
||||
|
||||
@@ -36,6 +36,8 @@ set(FILES
|
||||
Source/PythonBindingsInterface.h
|
||||
Source/ProjectInfo.h
|
||||
Source/ProjectInfo.cpp
|
||||
Source/ProjectUtils.h
|
||||
Source/ProjectUtils.cpp
|
||||
Source/NewProjectSettingsScreen.h
|
||||
Source/NewProjectSettingsScreen.cpp
|
||||
Source/CreateProjectCtrl.h
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace AssImpSDKWrapper
|
||||
@@ -34,10 +41,31 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
void signal_handler(int signal)
|
||||
{
|
||||
AZ_TracePrintf(
|
||||
SceneAPI::Utilities::ErrorWindow,
|
||||
"Failed to import scene with Asset Importer library. An %s has occured in the library, this scene file cannot be parsed by the library.",
|
||||
signal == SIGABRT ? "assert" : "unknown error");
|
||||
}
|
||||
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
|
||||
bool AssImpSceneWrapper::LoadSceneFromFile(const char* fileName)
|
||||
{
|
||||
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "AssImpSceneWrapper::LoadSceneFromFile %s", fileName);
|
||||
AZ_TraceContext("Filename", fileName);
|
||||
|
||||
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
// Turn off the abort popup because it can disrupt automation.
|
||||
// AssImp calls abort when asserts are enabled, and an assert is encountered.
|
||||
#ifdef _WRITE_ABORT_MSG
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||
#endif // #ifdef _WRITE_ABORT_MSG
|
||||
// Instead, capture any calls to abort with a signal handler, and report them.
|
||||
auto previous_handler = std::signal(SIGABRT, signal_handler);
|
||||
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
|
||||
// aiProcess_JoinIdenticalVertices is not enabled because O3DE has a mesh optimizer that also does this,
|
||||
// this flag is disabled to keep AssImp output similar to FBX SDK to reduce downstream bugs for the initial AssImp release.
|
||||
// There's currently a minimum of properties and flags set to maximize compatibility with the existing node graph.
|
||||
@@ -49,6 +77,15 @@ namespace AZ
|
||||
| aiProcess_LimitBoneWeights //Limits the number of bones that can affect a vertex to a maximum value
|
||||
//dropping the least important and re-normalizing
|
||||
| aiProcess_GenNormals); //Generate normals for meshes
|
||||
|
||||
#if AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
// Reset abort behavior for anything else that may call abort.
|
||||
std::signal(SIGABRT, previous_handler);
|
||||
#ifdef _WRITE_ABORT_MSG
|
||||
_set_abort_behavior(1, _WRITE_ABORT_MSG);
|
||||
#endif // #ifdef _WRITE_ABORT_MSG
|
||||
#endif // AZ_TRAIT_COMPILER_SUPPORT_CSIGNAL
|
||||
|
||||
if (!m_assImpScene)
|
||||
{
|
||||
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to import Asset Importer Scene. Error returned: %s", m_importer.GetErrorString());
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
return SavePrefab(templateId);
|
||||
return SavePrefab(outputPath, templateId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace AZ
|
||||
nestedPrefabPath.ReplaceExtension("prefab");
|
||||
|
||||
auto prefabLoaderInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
|
||||
nestedPrefabPath = prefabLoaderInterface->GetRelativePathToProject(nestedPrefabPath);
|
||||
nestedPrefabPath = prefabLoaderInterface->GenerateRelativePath(nestedPrefabPath);
|
||||
|
||||
AzToolsFramework::Prefab::TemplateId nestedTemplateId =
|
||||
prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath);
|
||||
@@ -439,17 +439,31 @@ namespace AZ
|
||||
AZ::Debug::Trace::Instance().Output("", "\n");
|
||||
}
|
||||
|
||||
bool SliceConverter::SavePrefab(AzToolsFramework::Prefab::TemplateId templateId)
|
||||
bool SliceConverter::SavePrefab(AZ::IO::PathView outputPath, AzToolsFramework::Prefab::TemplateId templateId)
|
||||
{
|
||||
auto prefabLoaderInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
|
||||
|
||||
if (!prefabLoaderInterface->SaveTemplate(templateId))
|
||||
AZStd::string out;
|
||||
if (prefabLoaderInterface->SaveTemplateToString(templateId, out))
|
||||
{
|
||||
AZ_Printf("Convert-Slice", " Could not save prefab - internal error (Json write operation failure).\n");
|
||||
return false;
|
||||
IO::SystemFile outputFile;
|
||||
if (!outputFile.Open(
|
||||
AZStd::string(outputPath.Native()).c_str(),
|
||||
IO::SystemFile::OpenMode::SF_OPEN_CREATE |
|
||||
IO::SystemFile::OpenMode::SF_OPEN_CREATE_PATH |
|
||||
IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY))
|
||||
{
|
||||
AZ_Error("Convert-Slice", false, " Unable to create output file '%.*s'.", AZ_STRING_ARG(outputPath.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
outputFile.Write(out.data(), out.size());
|
||||
outputFile.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
AZ_Printf("Convert-Slice", " Could not save prefab - internal error (Json write operation failure).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SliceConverter::ConnectToAssetProcessor()
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace AZ
|
||||
AZ::SliceComponent::SliceInstance& instance, AZ::Data::Asset<AZ::SliceAsset>& sliceAsset,
|
||||
AzToolsFramework::Prefab::TemplateReference nestedTemplate, AzToolsFramework::Prefab::Instance* topLevelInstance);
|
||||
static void PrintPrefab(AzToolsFramework::Prefab::TemplateId templateId);
|
||||
static bool SavePrefab(AzToolsFramework::Prefab::TemplateId templateId);
|
||||
static bool SavePrefab(AZ::IO::PathView outputPath, AzToolsFramework::Prefab::TemplateId templateId);
|
||||
};
|
||||
} // namespace SerializeContextTools
|
||||
} // namespace AZ
|
||||
|
||||
Reference in New Issue
Block a user