Gem Catalog Allows Filtering by Gem Selected Status Live (#1274)
This commit is contained in:
@@ -82,6 +82,8 @@ namespace O3DE::ProjectManager
|
||||
|
||||
m_headerWidget->ReinitForProject();
|
||||
|
||||
connect(m_gemModel, &GemModel::dataChanged, m_filterWidget, &GemFilterWidget::ResetGemStatusFilter);
|
||||
|
||||
// Select the first entry after everything got correctly sized
|
||||
QTimer::singleShot(200, [=]{
|
||||
QModelIndex firstModelIndex = m_gemListView->model()->index(0,0);
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace O3DE::ProjectManager
|
||||
const QVector<QString>& elementNames,
|
||||
const QVector<int>& elementCounts,
|
||||
bool showAllLessButton,
|
||||
bool collapsed,
|
||||
int defaultShowCount,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
@@ -40,6 +41,7 @@ namespace O3DE::ProjectManager
|
||||
QHBoxLayout* collapseLayout = new QHBoxLayout();
|
||||
m_collapseButton = new QPushButton();
|
||||
m_collapseButton->setCheckable(true);
|
||||
m_collapseButton->setChecked(collapsed);
|
||||
m_collapseButton->setFlat(true);
|
||||
m_collapseButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_collapseButton->setFixedWidth(s_collapseButtonSize);
|
||||
@@ -178,6 +180,11 @@ namespace O3DE::ProjectManager
|
||||
return m_buttonGroup;
|
||||
}
|
||||
|
||||
bool FilterCategoryWidget::IsCollapsed()
|
||||
{
|
||||
return m_collapseButton->isChecked();
|
||||
}
|
||||
|
||||
GemFilterWidget::GemFilterWidget(GemSortFilterProxyModel* filterProxyModel, QWidget* parent)
|
||||
: QScrollArea(parent)
|
||||
, m_filterProxyModel(filterProxyModel)
|
||||
@@ -193,20 +200,106 @@ namespace O3DE::ProjectManager
|
||||
QWidget* mainWidget = new QWidget();
|
||||
setWidget(mainWidget);
|
||||
|
||||
m_mainLayout = new QVBoxLayout();
|
||||
m_mainLayout->setAlignment(Qt::AlignTop);
|
||||
mainWidget->setLayout(m_mainLayout);
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout();
|
||||
mainLayout->setAlignment(Qt::AlignTop);
|
||||
mainWidget->setLayout(mainLayout);
|
||||
|
||||
QLabel* filterByLabel = new QLabel("Filter by");
|
||||
filterByLabel->setStyleSheet("font-size: 16px;");
|
||||
m_mainLayout->addWidget(filterByLabel);
|
||||
mainLayout->addWidget(filterByLabel);
|
||||
|
||||
QWidget* filterSection = new QWidget(this);
|
||||
mainLayout->addWidget(filterSection);
|
||||
|
||||
m_filterLayout = new QVBoxLayout();
|
||||
m_filterLayout->setAlignment(Qt::AlignTop);
|
||||
m_filterLayout->setContentsMargins(0, 0, 0, 0);
|
||||
filterSection->setLayout(m_filterLayout);
|
||||
|
||||
ResetGemStatusFilter();
|
||||
AddGemOriginFilter();
|
||||
AddTypeFilter();
|
||||
AddPlatformFilter();
|
||||
AddFeatureFilter();
|
||||
}
|
||||
|
||||
void GemFilterWidget::ResetGemStatusFilter()
|
||||
{
|
||||
QVector<QString> elementNames;
|
||||
QVector<int> elementCounts;
|
||||
const int totalGems = m_gemModel->rowCount();
|
||||
const int selectedGemTotal = m_gemModel->TotalAddedGems();
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemStatusString(GemSortFilterProxyModel::GemStatus::Unselected));
|
||||
elementCounts.push_back(totalGems - selectedGemTotal);
|
||||
|
||||
elementNames.push_back(GemSortFilterProxyModel::GetGemStatusString(GemSortFilterProxyModel::GemStatus::Selected));
|
||||
elementCounts.push_back(selectedGemTotal);
|
||||
|
||||
bool wasCollapsed = false;
|
||||
if (m_statusFilter)
|
||||
{
|
||||
wasCollapsed = m_statusFilter->IsCollapsed();
|
||||
}
|
||||
|
||||
FilterCategoryWidget* filterWidget =
|
||||
new FilterCategoryWidget("Status", elementNames, elementCounts, /*showAllLessButton=*/false, /*collapsed*/wasCollapsed);
|
||||
if (m_statusFilter)
|
||||
{
|
||||
m_filterLayout->replaceWidget(m_statusFilter, filterWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterLayout->addWidget(filterWidget);
|
||||
}
|
||||
|
||||
m_statusFilter->deleteLater();
|
||||
m_statusFilter = filterWidget;
|
||||
|
||||
const GemSortFilterProxyModel::GemStatus currentFilterState = m_filterProxyModel->GetGemStatus();
|
||||
const QList<QAbstractButton*> buttons = m_statusFilter->GetButtonGroup()->buttons();
|
||||
for (int statusFilterIndex = 0; statusFilterIndex < buttons.size(); ++statusFilterIndex)
|
||||
{
|
||||
const GemSortFilterProxyModel::GemStatus gemStatus = static_cast<GemSortFilterProxyModel::GemStatus>(statusFilterIndex);
|
||||
QAbstractButton* button = buttons[statusFilterIndex];
|
||||
|
||||
if (static_cast<GemSortFilterProxyModel::GemStatus>(statusFilterIndex) == currentFilterState)
|
||||
{
|
||||
button->setChecked(true);
|
||||
}
|
||||
|
||||
connect(
|
||||
button, &QAbstractButton::toggled, this,
|
||||
[=](bool checked)
|
||||
{
|
||||
GemSortFilterProxyModel::GemStatus filterStatus = m_filterProxyModel->GetGemStatus();
|
||||
if (checked)
|
||||
{
|
||||
if (filterStatus == GemSortFilterProxyModel::GemStatus::NoFilter)
|
||||
{
|
||||
filterStatus = gemStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
filterStatus = GemSortFilterProxyModel::GemStatus::NoFilter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filterStatus != gemStatus)
|
||||
{
|
||||
filterStatus = static_cast<GemSortFilterProxyModel::GemStatus>(!gemStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
filterStatus = GemSortFilterProxyModel::GemStatus::NoFilter;
|
||||
}
|
||||
}
|
||||
m_filterProxyModel->SetGemStatus(filterStatus);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void GemFilterWidget::AddGemOriginFilter()
|
||||
{
|
||||
QVector<QString> elementNames;
|
||||
@@ -233,7 +326,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Provider", elementNames, elementCounts, /*showAllLessButton=*/false);
|
||||
m_mainLayout->addWidget(filterWidget);
|
||||
m_filterLayout->addWidget(filterWidget);
|
||||
|
||||
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
@@ -283,7 +376,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Type", elementNames, elementCounts, /*showAllLessButton=*/false);
|
||||
m_mainLayout->addWidget(filterWidget);
|
||||
m_filterLayout->addWidget(filterWidget);
|
||||
|
||||
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
@@ -333,7 +426,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Supported Platforms", elementNames, elementCounts, /*showAllLessButton=*/false);
|
||||
m_mainLayout->addWidget(filterWidget);
|
||||
m_filterLayout->addWidget(filterWidget);
|
||||
|
||||
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
@@ -388,8 +481,8 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Features", elementNames, elementCounts,
|
||||
/*showAllLessButton=*/true, /*defaultShowCount=*/5);
|
||||
m_mainLayout->addWidget(filterWidget);
|
||||
/*showAllLessButton=*/true, false, /*defaultShowCount=*/5);
|
||||
m_filterLayout->addWidget(filterWidget);
|
||||
|
||||
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
|
||||
@@ -37,11 +37,14 @@ namespace O3DE::ProjectManager
|
||||
const QVector<QString>& elementNames,
|
||||
const QVector<int>& elementCounts,
|
||||
bool showAllLessButton = true,
|
||||
bool collapsed = false,
|
||||
int defaultShowCount = 4,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
QButtonGroup* GetButtonGroup();
|
||||
|
||||
bool IsCollapsed();
|
||||
|
||||
private:
|
||||
void UpdateCollapseState();
|
||||
void UpdateSeeMoreLess();
|
||||
@@ -66,14 +69,18 @@ namespace O3DE::ProjectManager
|
||||
explicit GemFilterWidget(GemSortFilterProxyModel* filterProxyModel, QWidget* parent = nullptr);
|
||||
~GemFilterWidget() = default;
|
||||
|
||||
public slots:
|
||||
void ResetGemStatusFilter();
|
||||
|
||||
private:
|
||||
void AddGemOriginFilter();
|
||||
void AddTypeFilter();
|
||||
void AddPlatformFilter();
|
||||
void AddFeatureFilter();
|
||||
|
||||
QVBoxLayout* m_mainLayout = nullptr;
|
||||
QVBoxLayout* m_filterLayout = nullptr;
|
||||
GemModel* m_gemModel = nullptr;
|
||||
GemSortFilterProxyModel* m_filterProxyModel = nullptr;
|
||||
FilterCategoryWidget* m_statusFilter = nullptr;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -204,7 +204,6 @@ namespace O3DE::ProjectManager
|
||||
painter->save();
|
||||
const QRect buttonRect = CalcButtonRect(contentRect);
|
||||
QPoint circleCenter;
|
||||
QString buttonText;
|
||||
|
||||
const bool isAdded = GemModel::IsAdded(modelIndex);
|
||||
if (isAdded)
|
||||
@@ -213,34 +212,15 @@ namespace O3DE::ProjectManager
|
||||
painter->setPen(m_buttonEnabledColor);
|
||||
|
||||
circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius + 1, 1);
|
||||
buttonText = "Added";
|
||||
}
|
||||
else
|
||||
{
|
||||
circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius, 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);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSpacerItem>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -74,6 +75,15 @@ namespace O3DE::ProjectManager
|
||||
gemSummaryLabel->setStyleSheet("font-size: 12px;");
|
||||
columnHeaderLayout->addWidget(gemSummaryLabel);
|
||||
|
||||
QSpacerItem* horizontalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
columnHeaderLayout->addSpacerItem(horizontalSpacer);
|
||||
|
||||
QLabel* gemSelectedLabel = new QLabel(tr("Selected"));
|
||||
gemSelectedLabel->setStyleSheet("font-size: 12px;");
|
||||
columnHeaderLayout->addWidget(gemSelectedLabel);
|
||||
|
||||
columnHeaderLayout->addSpacing(60);
|
||||
|
||||
vLayout->addLayout(columnHeaderLayout);
|
||||
}
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -235,4 +235,19 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int GemModel::TotalAddedGems() const
|
||||
{
|
||||
int result = 0;
|
||||
for (int row = 0; row < rowCount(); ++row)
|
||||
{
|
||||
const QModelIndex modelIndex = index(row, 0);
|
||||
if (IsAdded(modelIndex))
|
||||
{
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace O3DE::ProjectManager
|
||||
QVector<QModelIndex> GatherGemsToBeAdded() const;
|
||||
QVector<QModelIndex> GatherGemsToBeRemoved() const;
|
||||
|
||||
int TotalAddedGems() const;
|
||||
|
||||
private:
|
||||
enum UserRole
|
||||
{
|
||||
|
||||
@@ -37,6 +37,16 @@ namespace O3DE::ProjectManager
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gem status
|
||||
if (m_gemStatusFilter != GemStatus::NoFilter)
|
||||
{
|
||||
const GemStatus sourceGemStatus = static_cast<GemStatus>(GemModel::IsAdded(sourceIndex));
|
||||
if (m_gemStatusFilter != sourceGemStatus)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Gem origins
|
||||
if (m_gemOriginFilter)
|
||||
{
|
||||
@@ -125,6 +135,19 @@ namespace O3DE::ProjectManager
|
||||
return true;
|
||||
}
|
||||
|
||||
QString GemSortFilterProxyModel::GetGemStatusString(GemStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case Unselected:
|
||||
return "Unselected";
|
||||
case Selected:
|
||||
return "Selected";
|
||||
default:
|
||||
return "<Unknown Gem Status>";
|
||||
}
|
||||
}
|
||||
|
||||
void GemSortFilterProxyModel::InvalidateFilter()
|
||||
{
|
||||
invalidate();
|
||||
|
||||
@@ -29,8 +29,17 @@ namespace O3DE::ProjectManager
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
enum GemStatus
|
||||
{
|
||||
NoFilter = -1,
|
||||
Unselected,
|
||||
Selected
|
||||
};
|
||||
|
||||
GemSortFilterProxyModel(GemModel* sourceModel, QObject* parent = nullptr);
|
||||
|
||||
static QString GetGemStatusString(GemStatus status);
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
|
||||
|
||||
GemModel* GetSourceModel() const { return m_sourceModel; }
|
||||
@@ -38,6 +47,9 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void SetSearchString(const QString& searchString) { m_searchString = searchString; InvalidateFilter(); }
|
||||
|
||||
GemStatus GetGemStatus() const { return m_gemStatusFilter; }
|
||||
void SetGemStatus(GemStatus gemStatus) { m_gemStatusFilter = gemStatus; InvalidateFilter(); }
|
||||
|
||||
GemInfo::GemOrigins GetGemOrigins() const { return m_gemOriginFilter; }
|
||||
void SetGemOrigins(const GemInfo::GemOrigins& gemOrigins) { m_gemOriginFilter = gemOrigins; InvalidateFilter(); }
|
||||
|
||||
@@ -61,6 +73,7 @@ namespace O3DE::ProjectManager
|
||||
AzQtComponents::SelectionProxyModel* m_selectionProxyModel = nullptr;
|
||||
|
||||
QString m_searchString;
|
||||
GemStatus m_gemStatusFilter = GemStatus::NoFilter;
|
||||
GemInfo::GemOrigins m_gemOriginFilter = {};
|
||||
GemInfo::Platforms m_platformFilter = {};
|
||||
GemInfo::Types m_typeFilter = {};
|
||||
|
||||
@@ -189,11 +189,13 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
if (m_stack->currentIndex() == ScreenOrder::Gems)
|
||||
{
|
||||
m_header->setSubTitle(QString(tr("Configure Gems for \"%1\"")).arg(m_projectInfo.m_projectName));
|
||||
m_nextButton->setText(tr("Confirm"));
|
||||
m_header->setTitle(QString(tr("Edit Project Settings: \"%1\"")).arg(m_projectInfo.m_projectName));
|
||||
m_header->setSubTitle(QString(tr("Configure Gems")));
|
||||
m_nextButton->setText(tr("Finalize"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_header->setTitle("");
|
||||
m_header->setSubTitle(QString(tr("Edit Project Settings: \"%1\"")).arg(m_projectInfo.m_projectName));
|
||||
m_nextButton->setText(tr("Save"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user