Clicking tag now select gem and scrolls to it, it also resets filters if gem is filtered out, also gem filter creation was refactored

Signed-off-by: nggieber <nggieber@amazon.com>
monroegm-disable-blank-issue-2
nggieber 4 years ago
parent 37243c74ec
commit 08255d2eda

@ -30,7 +30,7 @@ namespace O3DE::ProjectManager
: ScreenWidget(parent) : ScreenWidget(parent)
{ {
m_gemModel = new GemModel(this); m_gemModel = new GemModel(this);
m_proxModel = new GemSortFilterProxyModel(m_gemModel, this); m_proxyModel = new GemSortFilterProxyModel(m_gemModel, this);
QVBoxLayout* vLayout = new QVBoxLayout(); QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setMargin(0); vLayout->setMargin(0);
@ -39,7 +39,7 @@ namespace O3DE::ProjectManager
m_downloadController = new DownloadController(); m_downloadController = new DownloadController();
m_headerWidget = new GemCatalogHeaderWidget(m_gemModel, m_proxModel, m_downloadController); m_headerWidget = new GemCatalogHeaderWidget(m_gemModel, m_proxyModel, m_downloadController);
vLayout->addWidget(m_headerWidget); vLayout->addWidget(m_headerWidget);
connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged); connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged);
@ -50,11 +50,11 @@ namespace O3DE::ProjectManager
hLayout->setMargin(0); hLayout->setMargin(0);
vLayout->addLayout(hLayout); vLayout->addLayout(hLayout);
m_gemListView = new GemListView(m_proxModel, m_proxModel->GetSelectionModel(), this); m_gemListView = new GemListView(m_proxyModel, m_proxyModel->GetSelectionModel(), this);
m_gemInspector = new GemInspector(m_gemModel, this); m_gemInspector = new GemInspector(m_gemModel, this);
m_gemInspector->setFixedWidth(240); m_gemInspector->setFixedWidth(240);
connect(m_gemInspector, &GemInspector::TagClicked, m_headerWidget, &GemCatalogHeaderWidget::SetSearchFilter); connect(m_gemInspector, &GemInspector::TagClicked, this, &GemCatalogScreen::SelectGem);
QWidget* filterWidget = new QWidget(this); QWidget* filterWidget = new QWidget(this);
filterWidget->setFixedWidth(240); filterWidget->setFixedWidth(240);
@ -63,7 +63,7 @@ namespace O3DE::ProjectManager
m_filterWidgetLayout->setSpacing(0); m_filterWidgetLayout->setSpacing(0);
filterWidget->setLayout(m_filterWidgetLayout); filterWidget->setLayout(m_filterWidgetLayout);
GemListHeaderWidget* listHeaderWidget = new GemListHeaderWidget(m_proxModel); GemListHeaderWidget* listHeaderWidget = new GemListHeaderWidget(m_proxyModel);
QVBoxLayout* middleVLayout = new QVBoxLayout(); QVBoxLayout* middleVLayout = new QVBoxLayout();
middleVLayout->setMargin(0); middleVLayout->setMargin(0);
@ -86,15 +86,17 @@ namespace O3DE::ProjectManager
m_gemsToRegisterWithProject.clear(); m_gemsToRegisterWithProject.clear();
FillModel(projectPath); FillModel(projectPath);
m_proxyModel->ResetFilters();
if (m_filterWidget) if (m_filterWidget)
{ {
m_filterWidget->hide(); m_filterWidget->ResetAllFilters();
m_filterWidget->deleteLater(); }
else
{
m_filterWidget = new GemFilterWidget(m_proxyModel);
m_filterWidgetLayout->addWidget(m_filterWidget);
} }
m_proxModel->ResetFilters();
m_filterWidget = new GemFilterWidget(m_proxModel);
m_filterWidgetLayout->addWidget(m_filterWidget);
m_headerWidget->ReinitForProject(); m_headerWidget->ReinitForProject();
@ -193,6 +195,20 @@ namespace O3DE::ProjectManager
} }
} }
void GemCatalogScreen::SelectGem(const QString& gemName)
{
QModelIndex modelIndex = m_gemModel->FindIndexByNameString(gemName);
if (!m_proxyModel->filterAcceptsRow(modelIndex.row(), QModelIndex()))
{
m_proxyModel->ResetFilters();
m_filterWidget->ResetAllFilters();
}
QModelIndex proxyIndex = m_proxyModel->mapFromSource(modelIndex);
m_proxyModel->GetSelectionModel()->select(proxyIndex, QItemSelectionModel::ClearAndSelect);
m_gemListView->scrollTo(proxyIndex);
}
void GemCatalogScreen::hideEvent(QHideEvent* event) void GemCatalogScreen::hideEvent(QHideEvent* event)
{ {
ScreenWidget::hideEvent(event); ScreenWidget::hideEvent(event);

@ -48,6 +48,7 @@ namespace O3DE::ProjectManager
public slots: public slots:
void OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies); void OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies);
void OnAddGemClicked(); void OnAddGemClicked();
void SelectGem(const QString& gemName);
protected: protected:
void hideEvent(QHideEvent* event) override; void hideEvent(QHideEvent* event) override;
@ -68,7 +69,7 @@ namespace O3DE::ProjectManager
GemInspector* m_gemInspector = nullptr; GemInspector* m_gemInspector = nullptr;
GemModel* m_gemModel = nullptr; GemModel* m_gemModel = nullptr;
GemCatalogHeaderWidget* m_headerWidget = nullptr; GemCatalogHeaderWidget* m_headerWidget = nullptr;
GemSortFilterProxyModel* m_proxModel = nullptr; GemSortFilterProxyModel* m_proxyModel = nullptr;
QVBoxLayout* m_filterWidgetLayout = nullptr; QVBoxLayout* m_filterWidgetLayout = nullptr;
GemFilterWidget* m_filterWidget = nullptr; GemFilterWidget* m_filterWidget = nullptr;
DownloadController* m_downloadController = nullptr; DownloadController* m_downloadController = nullptr;

@ -213,11 +213,99 @@ namespace O3DE::ProjectManager
m_filterLayout->setContentsMargins(0, 0, 0, 0); m_filterLayout->setContentsMargins(0, 0, 0, 0);
filterSection->setLayout(m_filterLayout); filterSection->setLayout(m_filterLayout);
ResetAllFilters();
}
void GemFilterWidget::ResetAllFilters()
{
ResetGemStatusFilter(); ResetGemStatusFilter();
AddGemOriginFilter(); ResetGemOriginFilter();
AddTypeFilter(); ResetTypeFilter();
AddPlatformFilter(); ResetPlatformFilter();
AddFeatureFilter(); ResetFeatureFilter();
}
void GemFilterWidget::ResetFilterWidget(
FilterCategoryWidget*& filterPtr,
const QString& filterName,
const QVector<QString>& elementNames,
const QVector<int>& elementCounts,
int defaultShowCount)
{
bool wasCollapsed = false;
if (filterPtr)
{
wasCollapsed = filterPtr->IsCollapsed();
}
FilterCategoryWidget* filterWidget = new FilterCategoryWidget(
filterName, elementNames, elementCounts, /*showAllLessButton=*/defaultShowCount != 4, /*collapsed*/ wasCollapsed,
/*defaultShowCount=*/defaultShowCount);
if (filterPtr)
{
m_filterLayout->replaceWidget(filterPtr, filterWidget);
}
else
{
m_filterLayout->addWidget(filterWidget);
}
filterPtr->deleteLater();
filterPtr = filterWidget;
}
template<typename filterType, typename filterFlagsType>
void GemFilterWidget::ResetSimpleOrFilter(
FilterCategoryWidget*& filterPtr,
const QString& filterName,
int numFilterElements,
bool (*filterMatcher)(GemModel*, filterType, int),
QString (*typeStringGetter)(filterType),
filterFlagsType (GemSortFilterProxyModel::*filterFlagsGetter)() const,
void (GemSortFilterProxyModel::*filterFlagsSetter)(const filterFlagsType&))
{
QVector<QString> elementNames;
QVector<int> elementCounts;
const int numGems = m_gemModel->rowCount();
for (int filterIndex = 0; filterIndex < numFilterElements; ++filterIndex)
{
const filterType gemFilterToBeCounted = static_cast<filterType>(1 << filterIndex);
int gemFilterCount = 0;
for (int gemIndex = 0; gemIndex < numGems; ++gemIndex)
{
// If filter matches increment filter count
gemFilterCount += filterMatcher(m_gemModel, gemFilterToBeCounted, gemIndex);
}
elementNames.push_back(typeStringGetter(gemFilterToBeCounted));
elementCounts.push_back(gemFilterCount);
}
// Replace existing filter and delete old one
ResetFilterWidget(filterPtr, filterName, elementNames, elementCounts);
const QList<QAbstractButton*> buttons = filterPtr->GetButtonGroup()->buttons();
for (int i = 0; i < buttons.size(); ++i)
{
const filterType gemFilter = static_cast<filterType>(1 << i);
QAbstractButton* button = buttons[i];
connect(
button, &QAbstractButton::toggled, this,
[=](bool checked)
{
filterFlagsType gemFilters = (m_filterProxyModel->*filterFlagsGetter)();
if (checked)
{
gemFilters |= gemFilter;
}
else
{
gemFilters &= ~gemFilter;
}
(m_filterProxyModel->*filterFlagsSetter)(gemFilters);
});
}
} }
void GemFilterWidget::ResetGemStatusFilter() void GemFilterWidget::ResetGemStatusFilter()
@ -241,25 +329,7 @@ namespace O3DE::ProjectManager
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive)); elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive));
elementCounts.push_back(totalGems - enabledGemTotal); elementCounts.push_back(totalGems - enabledGemTotal);
bool wasCollapsed = false; ResetFilterWidget(m_statusFilter, "Status", elementNames, elementCounts);
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 QList<QAbstractButton*> buttons = m_statusFilter->GetButtonGroup()->buttons(); const QList<QAbstractButton*> buttons = m_statusFilter->GetButtonGroup()->buttons();
@ -317,157 +387,42 @@ namespace O3DE::ProjectManager
connect(activeButton, &QAbstractButton::toggled, this, updateGemActive); connect(activeButton, &QAbstractButton::toggled, this, updateGemActive);
} }
void GemFilterWidget::AddGemOriginFilter() void GemFilterWidget::ResetGemOriginFilter()
{ {
QVector<QString> elementNames; ResetSimpleOrFilter<GemInfo::GemOrigin, GemInfo::GemOrigins>
QVector<int> elementCounts; (
const int numGems = m_gemModel->rowCount(); m_originFilter, "Provider", GemInfo::NumGemOrigins,
for (int originIndex = 0; originIndex < GemInfo::NumGemOrigins; ++originIndex) [](GemModel* gemModel, GemInfo::GemOrigin origin, int gemIndex)
{
const GemInfo::GemOrigin gemOriginToBeCounted = static_cast<GemInfo::GemOrigin>(1 << originIndex);
int gemOriginCount = 0;
for (int gemIndex = 0; gemIndex < numGems; ++gemIndex)
{ {
const GemInfo::GemOrigin gemOrigin = m_gemModel->GetGemOrigin(m_gemModel->index(gemIndex, 0)); return origin == gemModel->GetGemOrigin(gemModel->index(gemIndex, 0));
},
// Is the gem of the given origin? &GemInfo::GetGemOriginString, &GemSortFilterProxyModel::GetGemOrigins, &GemSortFilterProxyModel::SetGemOrigins
if (gemOriginToBeCounted == gemOrigin) );
{
gemOriginCount++;
}
}
elementNames.push_back(GemInfo::GetGemOriginString(gemOriginToBeCounted));
elementCounts.push_back(gemOriginCount);
}
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Provider", elementNames, elementCounts, /*showAllLessButton=*/false);
m_filterLayout->addWidget(filterWidget);
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
for (int i = 0; i < buttons.size(); ++i)
{
const GemInfo::GemOrigin gemOrigin = static_cast<GemInfo::GemOrigin>(1 << i);
QAbstractButton* button = buttons[i];
connect(button, &QAbstractButton::toggled, this, [=](bool checked)
{
GemInfo::GemOrigins gemOrigins = m_filterProxyModel->GetGemOrigins();
if (checked)
{
gemOrigins |= gemOrigin;
}
else
{
gemOrigins &= ~gemOrigin;
}
m_filterProxyModel->SetGemOrigins(gemOrigins);
});
}
} }
void GemFilterWidget::AddTypeFilter() void GemFilterWidget::ResetTypeFilter()
{ {
QVector<QString> elementNames; ResetSimpleOrFilter<GemInfo::Type, GemInfo::Types>(
QVector<int> elementCounts; m_typeFilter, "Type", GemInfo::NumTypes,
const int numGems = m_gemModel->rowCount(); [](GemModel* gemModel, GemInfo::Type type, int gemIndex)
for (int typeIndex = 0; typeIndex < GemInfo::NumTypes; ++typeIndex)
{
const GemInfo::Type type = static_cast<GemInfo::Type>(1 << typeIndex);
int typeGemCount = 0;
for (int gemIndex = 0; gemIndex < numGems; ++gemIndex)
{ {
const GemInfo::Types types = m_gemModel->GetTypes(m_gemModel->index(gemIndex, 0)); return static_cast<bool>(type & gemModel->GetTypes(gemModel->index(gemIndex, 0)));
},
// Is type (Asset, Code, Tool) part of the gem? &GemInfo::GetTypeString, &GemSortFilterProxyModel::GetTypes, &GemSortFilterProxyModel::SetTypes);
if (types & type)
{
typeGemCount++;
}
}
elementNames.push_back(GemInfo::GetTypeString(type));
elementCounts.push_back(typeGemCount);
}
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Type", elementNames, elementCounts, /*showAllLessButton=*/false);
m_filterLayout->addWidget(filterWidget);
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
for (int i = 0; i < buttons.size(); ++i)
{
const GemInfo::Type type = static_cast<GemInfo::Type>(1 << i);
QAbstractButton* button = buttons[i];
connect(button, &QAbstractButton::toggled, this, [=](bool checked)
{
GemInfo::Types types = m_filterProxyModel->GetTypes();
if (checked)
{
types |= type;
}
else
{
types &= ~type;
}
m_filterProxyModel->SetTypes(types);
});
}
} }
void GemFilterWidget::AddPlatformFilter() void GemFilterWidget::ResetPlatformFilter()
{ {
QVector<QString> elementNames; ResetSimpleOrFilter<GemInfo::Platform, GemInfo::Platforms>(
QVector<int> elementCounts; m_platformFilter, "Supported Platforms", GemInfo::NumPlatforms,
const int numGems = m_gemModel->rowCount(); [](GemModel* gemModel, GemInfo::Platform platform, int gemIndex)
for (int platformIndex = 0; platformIndex < GemInfo::NumPlatforms; ++platformIndex)
{
const GemInfo::Platform platform = static_cast<GemInfo::Platform>(1 << platformIndex);
int platformGemCount = 0;
for (int gemIndex = 0; gemIndex < numGems; ++gemIndex)
{ {
const GemInfo::Platforms platforms = m_gemModel->GetPlatforms(m_gemModel->index(gemIndex, 0)); return static_cast<bool>(platform & gemModel->GetPlatforms(gemModel->index(gemIndex, 0)));
},
// Is platform supported? &GemInfo::GetPlatformString, &GemSortFilterProxyModel::GetPlatforms, &GemSortFilterProxyModel::SetPlatforms);
if (platforms & platform)
{
platformGemCount++;
}
}
elementNames.push_back(GemInfo::GetPlatformString(platform));
elementCounts.push_back(platformGemCount);
}
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Supported Platforms", elementNames, elementCounts, /*showAllLessButton=*/false);
m_filterLayout->addWidget(filterWidget);
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons();
for (int i = 0; i < buttons.size(); ++i)
{
const GemInfo::Platform platform = static_cast<GemInfo::Platform>(1 << i);
QAbstractButton* button = buttons[i];
connect(button, &QAbstractButton::toggled, this, [=](bool checked)
{
GemInfo::Platforms platforms = m_filterProxyModel->GetPlatforms();
if (checked)
{
platforms |= platform;
}
else
{
platforms &= ~platform;
}
m_filterProxyModel->SetPlatforms(platforms);
});
}
} }
void GemFilterWidget::AddFeatureFilter() void GemFilterWidget::ResetFeatureFilter()
{ {
// Alphabetically sorted, unique features and their number of occurrences in the gem database. // Alphabetically sorted, unique features and their number of occurrences in the gem database.
QMap<QString, int> uniqueFeatureCounts; QMap<QString, int> uniqueFeatureCounts;
@ -497,11 +452,15 @@ namespace O3DE::ProjectManager
elementCounts.push_back(iterator.value()); elementCounts.push_back(iterator.value());
} }
FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Features", elementNames, elementCounts, ResetFilterWidget(m_featureFilter, "Features", elementNames, elementCounts, /*defaultShowCount=*/5);
/*showAllLessButton=*/true, false, /*defaultShowCount=*/5);
m_filterLayout->addWidget(filterWidget);
const QList<QAbstractButton*> buttons = filterWidget->GetButtonGroup()->buttons(); for (QMetaObject::Connection& connection : m_featureTagConnections)
{
disconnect(connection);
}
m_featureTagConnections.clear();
const QList<QAbstractButton*> buttons = m_featureFilter->GetButtonGroup()->buttons();
for (int i = 0; i < buttons.size(); ++i) for (int i = 0; i < buttons.size(); ++i)
{ {
const QString& feature = elementNames[i]; const QString& feature = elementNames[i];
@ -523,13 +482,13 @@ namespace O3DE::ProjectManager
}); });
// Sync the UI state with the proxy model filtering. // Sync the UI state with the proxy model filtering.
connect(m_filterProxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=] m_featureTagConnections.push_back(connect(m_filterProxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=]
{ {
const QSet<QString>& filteredFeatureTags = m_filterProxyModel->GetFeatures(); const QSet<QString>& filteredFeatureTags = m_filterProxyModel->GetFeatures();
const bool isChecked = filteredFeatureTags.contains(button->text()); const bool isChecked = filteredFeatureTags.contains(button->text());
QSignalBlocker signalsBlocker(button); QSignalBlocker signalsBlocker(button);
button->setChecked(isChecked); button->setChecked(isChecked);
}); }));
} }
} }
} // namespace O3DE::ProjectManager } // namespace O3DE::ProjectManager

@ -66,17 +66,41 @@ namespace O3DE::ProjectManager
~GemFilterWidget() = default; ~GemFilterWidget() = default;
public slots: public slots:
void ResetAllFilters();
void ResetGemStatusFilter(); void ResetGemStatusFilter();
private: private:
void AddGemOriginFilter(); void ResetGemOriginFilter();
void AddTypeFilter(); void ResetTypeFilter();
void AddPlatformFilter(); void ResetPlatformFilter();
void AddFeatureFilter(); void ResetFeatureFilter();
void ResetFilterWidget(
FilterCategoryWidget*& filterPtr,
const QString& filterName,
const QVector<QString>& elementNames,
const QVector<int>& elementCounts,
int defaultShowCount = 4);
template<typename filterType, typename filterFlagsType>
void ResetSimpleOrFilter(
FilterCategoryWidget*& filterPtr,
const QString& filterName,
int numFilterElements,
bool (*filterMatcher)(GemModel*, filterType, int),
QString (*typeStringGetter)(filterType),
filterFlagsType (GemSortFilterProxyModel::*filterFlagsGetter)() const,
void (GemSortFilterProxyModel::*filterFlagsSetter)(const filterFlagsType&));
QVBoxLayout* m_filterLayout = nullptr; QVBoxLayout* m_filterLayout = nullptr;
GemModel* m_gemModel = nullptr; GemModel* m_gemModel = nullptr;
GemSortFilterProxyModel* m_filterProxyModel = nullptr; GemSortFilterProxyModel* m_filterProxyModel = nullptr;
FilterCategoryWidget* m_statusFilter = nullptr; FilterCategoryWidget* m_statusFilter = nullptr;
FilterCategoryWidget* m_originFilter = nullptr;
FilterCategoryWidget* m_typeFilter = nullptr;
FilterCategoryWidget* m_platformFilter = nullptr;
FilterCategoryWidget* m_featureFilter = nullptr;
QVector<QMetaObject::Connection> m_featureTagConnections;
}; };
} // namespace O3DE::ProjectManager } // namespace O3DE::ProjectManager

@ -54,6 +54,7 @@ namespace O3DE::ProjectManager
appendRow(item); appendRow(item);
const QModelIndex modelIndex = index(rowCount()-1, 0); const QModelIndex modelIndex = index(rowCount()-1, 0);
m_nameToIndexMap[gemInfo.m_displayName] = modelIndex;
m_nameToIndexMap[gemInfo.m_name] = modelIndex; m_nameToIndexMap[gemInfo.m_name] = modelIndex;
} }

@ -207,6 +207,8 @@ namespace O3DE::ProjectManager
void GemSortFilterProxyModel::ResetFilters() void GemSortFilterProxyModel::ResetFilters()
{ {
m_searchString.clear(); m_searchString.clear();
m_gemSelectedFilter = GemSelected::NoFilter;
m_gemActiveFilter = GemActive::NoFilter;
m_gemOriginFilter = {}; m_gemOriginFilter = {};
m_platformFilter = {}; m_platformFilter = {};
m_typeFilter = {}; m_typeFilter = {};

Loading…
Cancel
Save