[LYN-2515] Project Manager Gem List (#642)

* [LYN-2515] Project Manager Gem List Base

* Added gem model based on a standard item model
* Added list view using the gem model
* Added item delegate for a gem according to the UX design
* Removed th gem catalog ui file and replaced it with code
* Moved the gem catalog files into a sub folder
* Added drawing the Added/Get button and the platform icons
This commit is contained in:
Benjamin Jillich
2021-05-10 11:32:13 +02:00
committed by GitHub
parent 727bedf18d
commit d03f946609
12 changed files with 178 additions and 23 deletions
@@ -21,8 +21,6 @@ namespace O3DE::ProjectManager
GemCatalog::GemCatalog(ProjectManagerWindow* window)
: ScreenWidget(window)
{
ConnectSlotsAndSignals();
m_gemModel = new GemModel(this);
QVBoxLayout* vLayout = new QVBoxLayout();
@@ -56,36 +54,36 @@ namespace O3DE::ProjectManager
m_gemModel->AddGem(GemInfo("EMotion FX",
"O3DE Foundation",
"EMFX is a real-time character animation system. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
(GemInfo::Android | GemInfo::iOS | GemInfo::Windows | GemInfo::Linux),
(GemInfo::Android | GemInfo::iOS | GemInfo::macOS | GemInfo::Windows | GemInfo::Linux),
true));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Atom",
"O3DE Foundation",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::Android | GemInfo::Windows | GemInfo::Linux,
GemInfo::Android | GemInfo::Windows | GemInfo::Linux | GemInfo::macOS,
true));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("PhysX",
"O3DE Foundation",
"O3DE London",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::Android | GemInfo::Linux,
GemInfo::Android | GemInfo::Linux | GemInfo::macOS,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Certificate Manager",
"O3DE Foundation",
"O3DE Irvine",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::Windows,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Cloud Gem Framework",
"O3DE Foundation",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"O3DE Seattle",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::iOS | GemInfo::Linux,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Achievements",
"O3DE Foundation",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
GemInfo::Android | GemInfo::Windows | GemInfo::Linux,
false));
}
@@ -26,11 +26,12 @@ namespace O3DE::ProjectManager
public:
enum Platform
{
Android = 0x0,
iOS = 0x1,
Linux = 0x2,
macOS = 0x3,
Windows = 0x4
Android = 1 << 0,
iOS = 1 << 1,
Linux = 1 << 2,
macOS = 1 << 3,
Windows = 1 << 4,
NumPlatforms = 5
};
Q_DECLARE_FLAGS(Platforms, Platform)
@@ -22,6 +22,18 @@ namespace O3DE::ProjectManager
: QStyledItemDelegate(parent)
, m_gemModel(gemModel)
{
AddPlatformIcon(GemInfo::Android, ":/Resources/Android.svg");
AddPlatformIcon(GemInfo::iOS, ":/Resources/iOS.svg");
AddPlatformIcon(GemInfo::Linux, ":/Resources/Linux.svg");
AddPlatformIcon(GemInfo::macOS, ":/Resources/macOS.svg");
AddPlatformIcon(GemInfo::Windows, ":/Resources/Windows.svg");
}
void GemItemDelegate::AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath)
{
QPixmap pixmap(iconPath);
qreal aspectRatio = static_cast<qreal>(pixmap.width()) / pixmap.height();
m_platformIcons.insert(platform, QIcon(iconPath).pixmap(s_platformIconSize * aspectRatio, s_platformIconSize));
}
void GemItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const
@@ -87,7 +99,7 @@ namespace O3DE::ProjectManager
painter->drawText(gemCreatorRect, Qt::TextSingleLine, gemCreator);
// Gem summary
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_itemMargins.right() * 4, contentRect.height());
const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 4, contentRect.height());
const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize);
painter->setFont(standardFont);
@@ -96,6 +108,10 @@ namespace O3DE::ProjectManager
const QString summary = m_gemModel->GetSummary(modelIndex);
painter->drawText(summaryRect, Qt::AlignLeft | Qt::TextWordWrap, summary);
DrawButton(painter, contentRect, modelIndex);
DrawPlatformIcons(painter, contentRect, modelIndex);
painter->restore();
}
@@ -105,7 +121,7 @@ namespace O3DE::ProjectManager
initStyleOption(&options, modelIndex);
int marginsHorizontal = s_itemMargins.left() + s_itemMargins.right() + s_contentMargins.left() + s_contentMargins.right();
return QSize(marginsHorizontal + s_summaryStartX, s_height);
return QSize(marginsHorizontal + s_buttonWidth + s_summaryStartX, s_height);
}
bool GemItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex)
@@ -132,4 +148,85 @@ namespace O3DE::ProjectManager
font.setPixelSize(fontSize);
return QFontMetrics(font).boundingRect(text);
}
QRect GemItemDelegate::CalcButtonRect(const QRect& contentRect) const
{
const QPoint topLeft = QPoint(contentRect.right() - s_buttonWidth - s_itemMargins.right(), contentRect.top() + contentRect.height() / 2 - s_buttonHeight / 2);
const QSize size = QSize(s_buttonWidth, s_buttonHeight);
return QRect(topLeft, size);
}
void GemItemDelegate::DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const
{
const GemInfo::Platforms platforms = m_gemModel->GetPlatforms(modelIndex);
int startX = 0;
// Iterate and draw the platforms in the order they are defined in the enum.
for (int i = 0; i < GemInfo::NumPlatforms; ++i)
{
// Check if the platform is supported by the given gem.
const GemInfo::Platform platform = static_cast<GemInfo::Platform>(1 << i);
if (platforms & platform)
{
// Get the icon for the platform and draw it.
const auto iterator = m_platformIcons.find(platform);
if (iterator != m_platformIcons.end())
{
const QPixmap& pixmap = iterator.value();
painter->drawPixmap(contentRect.left() + startX, contentRect.bottom() - s_platformIconSize, pixmap);
qreal aspectRatio = static_cast<qreal>(pixmap.width()) / pixmap.height();
startX += s_platformIconSize * aspectRatio + s_platformIconSize / 2.5;
}
}
}
}
void GemItemDelegate::DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const
{
painter->save();
const QRect buttonRect = CalcButtonRect(contentRect);
QPoint circleCenter;
QString buttonText;
const bool isAdded = m_gemModel->IsAdded(modelIndex);
if (isAdded)
{
painter->setBrush(m_buttonEnabledColor);
painter->setPen(m_buttonEnabledColor);
circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius, 1);
buttonText = "Added";
}
else
{
circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius + 1, 1);
buttonText = "Get";
}
// Rounded rect
painter->drawRoundedRect(buttonRect, s_buttonBorderRadius, s_buttonBorderRadius);
// Text
QFont font;
QRect textRect = GetTextRect(font, buttonText, s_buttonFontSize);
if (isAdded)
{
textRect = QRect(buttonRect.left(), buttonRect.top(), buttonRect.width() - s_buttonCircleRadius * 2.0, buttonRect.height());
}
else
{
textRect = QRect(buttonRect.left() + s_buttonCircleRadius * 2.0, buttonRect.top(), buttonRect.width() - s_buttonCircleRadius * 2.0, buttonRect.height());
}
font.setPixelSize(s_buttonFontSize);
painter->setFont(font);
painter->setPen(m_textColor);
painter->drawText(textRect, Qt::AlignCenter, buttonText);
// Circle
painter->setBrush(m_textColor);
painter->drawEllipse(circleCenter, s_buttonCircleRadius, s_buttonCircleRadius);
painter->restore();
}
} // namespace O3DE::ProjectManager
@@ -16,6 +16,7 @@
#include <QStyledItemDelegate>
#include "GemInfo.h"
#include "GemModel.h"
#include <QHash>
#endif
QT_FORWARD_DECLARE_CLASS(QEvent)
@@ -38,6 +39,9 @@ namespace O3DE::ProjectManager
private:
void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, 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;
GemModel* m_gemModel = nullptr;
@@ -47,9 +51,10 @@ namespace O3DE::ProjectManager
const QColor m_backgroundColor = QColor("#333333"); // Outside of the actual gem item
const QColor m_itemBackgroundColor = QColor("#404040"); // Background color of the gem item
const QColor m_borderColor = QColor("#1E70EB");
const QColor m_buttonEnabledColor = QColor("#00B931");
// Item
inline constexpr static int s_height = 140; // Gem item total height
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;
@@ -58,5 +63,17 @@ namespace O3DE::ProjectManager
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 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;
// Platform icons
void AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath);
inline constexpr static int s_platformIconSize = 16;
QHash<GemInfo::Platform, QPixmap> m_platformIcons;
};
} // namespace O3DE::ProjectManager
@@ -55,7 +55,7 @@ namespace O3DE::ProjectManager
return modelIndex.data(RoleCreator).toString();
}
int GemModel::GetPlatforms(const QModelIndex& modelIndex) const
GemInfo::Platforms GemModel::GetPlatforms(const QModelIndex& modelIndex) const
{
return static_cast<GemInfo::Platforms>(modelIndex.data(RolePlatforms).toInt());
}
@@ -34,7 +34,7 @@ namespace O3DE::ProjectManager
QString GetName(const QModelIndex& modelIndex) const;
QString GetCreator(const QModelIndex& modelIndex) const;
int GetPlatforms(const QModelIndex& modelIndex) const;
GemInfo::Platforms GetPlatforms(const QModelIndex& modelIndex) const;
QString GetSummary(const QModelIndex& modelIndex) const;
bool IsAdded(const QModelIndex& modelIndex) const;