Asset Browser Table view filtering

This commit is contained in:
igarri
2021-05-10 15:52:35 +01:00
parent 662951eb98
commit 6e15e87e41
5 changed files with 217 additions and 182 deletions
@@ -45,7 +45,7 @@ namespace AzToolsFramework
//asset type filtering
void SetFilter(FilterConstType filter);
void FilterUpdatedSlotImmediate();
const FilterConstType& GetFilter() const { return m_filter; }
//////////////////////////////////////////////////////////////////////////
// AssetBrowserComponentNotificationBus
//////////////////////////////////////////////////////////////////////////
@@ -5,7 +5,7 @@
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
#include <AssetBrowser/AssetBrowserTableModel.h>
#include <AssetBrowser/AssetBrowserModel.h>
#include <AssetBrowser/AssetBrowserFilterModel.h>
#include <QCollator>
#include <QSharedPointer>
@@ -29,10 +29,12 @@ namespace AzToolsFramework
}
void AssetBrowserTableModel::OnAssetBrowserComponentReady()
{
BuildMap(sourceModel());
//BuildMap(sourceModel());
}
void AssetBrowserTableModel::setSourceModel(QAbstractItemModel* sourceModel)
{
m_filterModel = qobject_cast<AssetBrowserFilterModel*>(sourceModel);
AZ_Assert(m_filterModel, "Expecting AssetBrowserFilterModel");
QSortFilterProxyModel::setSourceModel(sourceModel);
}
@@ -60,6 +62,18 @@ namespace AzToolsFramework
return createIndex(m_rowMap[sourceIndex], sourceIndex.column(), sourceIndex.internalPointer());
}
bool AssetBrowserTableModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
AZ_UNUSED(source_row);
AZ_UNUSED(source_parent);
// no filter present, every entry is not visible
if (!m_filterModel->GetFilter())
{
return false;
}
return true;
}
QModelIndex AssetBrowserTableModel::index(int row, int column, const QModelIndex& parent) const
{
/*AZ_UNUSED(row);
@@ -159,158 +173,172 @@ namespace AzToolsFramework
}
void AssetBrowserTableModel::UpdateMap()
{
m_indexMap.clear();
m_rowMap.clear();
//m_indexMap.clear();
//m_rowMap.clear();
if (m_indexMap.size() > 0)
{
//beginRemoveRows(m_indexMap.first().parent(), m_indexMap.first().row(), m_indexMap.last().row());
for (const auto& key : m_indexMap.keys())
{
beginRemoveRows(m_indexMap[key], m_indexMap[key].row(), m_indexMap[key].row());
m_rowMap.remove(m_indexMap[key]);
m_indexMap.remove(key);
endRemoveRows();
}
//endRemoveRows();
}
BuildMap(sourceModel());
}
//---------------------------------------AssetBrowserTableFilterModel--------------------------------------------
AssetBrowserTableFilterModel::AssetBrowserTableFilterModel(QObject* parent)
: QSortFilterProxyModel(parent)
{
m_showColumn.insert(static_cast<int>(AssetBrowserEntry::Column::DisplayName));
m_showColumn.insert(static_cast<int>(AssetBrowserEntry::Column::Path));
AssetBrowserComponentNotificationBus::Handler::BusConnect();
}
//AssetBrowserTableFilterModel::AssetBrowserTableFilterModel(QObject* parent)
// : QSortFilterProxyModel(parent)
//{
// m_showColumn.insert(static_cast<int>(AssetBrowserEntry::Column::DisplayName));
// m_showColumn.insert(static_cast<int>(AssetBrowserEntry::Column::Path));
// AssetBrowserComponentNotificationBus::Handler::BusConnect();
//}
AssetBrowserTableFilterModel::~AssetBrowserTableFilterModel()
{
AssetBrowserComponentNotificationBus::Handler::BusDisconnect();
}
//AssetBrowserTableFilterModel::~AssetBrowserTableFilterModel()
//{
// AssetBrowserComponentNotificationBus::Handler::BusDisconnect();
//}
void AssetBrowserTableFilterModel::setSourceModel(QAbstractItemModel* sourceModel)
{
QSortFilterProxyModel::setSourceModel(sourceModel);
}
//void AssetBrowserTableFilterModel::setSourceModel(QAbstractItemModel* sourceModel)
//{
// QSortFilterProxyModel::setSourceModel(sourceModel);
//}
void AssetBrowserTableFilterModel::SetFilter(FilterConstType filter)
{
connect(filter.data(), &AssetBrowserEntryFilter::updatedSignal, this, &AssetBrowserTableFilterModel::filterUpdatedSlot);
m_filter = filter;
m_invalidateFilter = true;
// asset browser entries are not guaranteed to have populated when the filter is set, delay filtering until they are
bool isAssetBrowserComponentReady = false;
AssetBrowserComponentRequestBus::BroadcastResult(isAssetBrowserComponentReady, &AssetBrowserComponentRequests::AreEntriesReady);
if (isAssetBrowserComponentReady)
{
OnAssetBrowserComponentReady();
}
}
//void AssetBrowserTableFilterModel::SetFilter(FilterConstType filter)
//{
// connect(filter.data(), &AssetBrowserEntryFilter::updatedSignal, this, &AssetBrowserTableFilterModel::filterUpdatedSlot);
// m_filter = filter;
// m_invalidateFilter = true;
// // asset browser entries are not guaranteed to have populated when the filter is set, delay filtering until they are
// bool isAssetBrowserComponentReady = false;
// AssetBrowserComponentRequestBus::BroadcastResult(isAssetBrowserComponentReady, &AssetBrowserComponentRequests::AreEntriesReady);
// if (isAssetBrowserComponentReady)
// {
// OnAssetBrowserComponentReady();
// }
//}
void AssetBrowserTableFilterModel::FilterUpdatedSlotImmediate()
{
auto compFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(m_filter);
if (compFilter)
{
auto& subFilters = compFilter->GetSubFilters();
auto it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool {
auto assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(filter);
return !assetTypeFilter.isNull();
});
if (it != subFilters.end())
{
m_assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(*it);
}
it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool {
auto stringFilter = qobject_cast<QSharedPointer<const StringFilter>>(filter);
return !stringFilter.isNull();
});
if (it != subFilters.end())
{
m_stringFilter = qobject_cast<QSharedPointer<const StringFilter>>(*it);
}
}
invalidateFilter();
Q_EMIT filterChanged();
}
//void AssetBrowserTableFilterModel::FilterUpdatedSlotImmediate()
//{
// auto compFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(m_filter);
// if (compFilter)
// {
// auto& subFilters = compFilter->GetSubFilters();
// auto it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool {
// auto assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(filter);
// return !assetTypeFilter.isNull();
// });
// if (it != subFilters.end())
// {
// m_assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(*it);
// }
// it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool {
// auto stringFilter = qobject_cast<QSharedPointer<const StringFilter>>(filter);
// return !stringFilter.isNull();
// });
// if (it != subFilters.end())
// {
// m_stringFilter = qobject_cast<QSharedPointer<const StringFilter>>(*it);
// }
// }
// invalidateFilter();
// Q_EMIT filterChanged();
//}
void AssetBrowserTableFilterModel::OnAssetBrowserComponentReady()
{
if (m_invalidateFilter)
{
invalidateFilter();
m_invalidateFilter = false;
}
Q_EMIT entriesUpdated();
}
//void AssetBrowserTableFilterModel::OnAssetBrowserComponentReady()
//{
// if (m_invalidateFilter)
// {
// invalidateFilter();
// m_invalidateFilter = false;
// }
// Q_EMIT entriesUpdated();
//}
bool AssetBrowserTableFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
AZ_UNUSED(source_row);
AZ_UNUSED(source_parent);
QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
if (!idx.isValid())
{
return false;
}
// no filter present, every entry is visible
if (!m_filter)
{
return true;
}
//bool AssetBrowserTableFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
//{
// AZ_UNUSED(source_row);
// AZ_UNUSED(source_parent);
// QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
// if (!idx.isValid())
// {
// return false;
// }
// // no filter present, every entry is visible
// if (!m_filter)
// {
// return true;
// }
//// the entry is the internal pointer of the index
//auto entry = static_cast<AssetBrowserEntry*>(idx.internalPointer());
// //// the entry is the internal pointer of the index
// //auto entry = static_cast<AssetBrowserEntry*>(idx.internalPointer());
//if (entry)
//{
// // root should return true even if its not displayed in the treeview
// if (entry && entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Root)
// {
// return true;
// }
// return m_filter->Match(entry);
//}
return true;
}
// //if (entry)
// //{
// // // root should return true even if its not displayed in the treeview
// // if (entry && entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Root)
// // {
// // return true;
// // }
// // return m_filter->Match(entry);
// //}
// return true;
//}
bool AssetBrowserTableFilterModel::filterAcceptsColumn(int source_column, const QModelIndex&) const
{
return m_showColumn.find(source_column) != m_showColumn.end();
}
//bool AssetBrowserTableFilterModel::filterAcceptsColumn(int source_column, const QModelIndex&) const
//{
// return m_showColumn.find(source_column) != m_showColumn.end();
//}
bool AssetBrowserTableFilterModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const
{
if (source_left.column() == source_right.column())
{
QVariant leftData = sourceModel()->data(source_left, AssetBrowserModel::Roles::EntryRole);
QVariant rightData = sourceModel()->data(source_right, AssetBrowserModel::Roles::EntryRole);
if (leftData.canConvert<const AssetBrowserEntry*>() && rightData.canConvert<const AssetBrowserEntry*>())
{
auto leftEntry = qvariant_cast<const AssetBrowserEntry*>(leftData);
auto rightEntry = qvariant_cast<const AssetBrowserEntry*>(rightData);
//bool AssetBrowserTableFilterModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const
//{
// if (source_left.column() == source_right.column())
// {
// QVariant leftData = sourceModel()->data(source_left, AssetBrowserModel::Roles::EntryRole);
// QVariant rightData = sourceModel()->data(source_right, AssetBrowserModel::Roles::EntryRole);
// if (leftData.canConvert<const AssetBrowserEntry*>() && rightData.canConvert<const AssetBrowserEntry*>())
// {
// auto leftEntry = qvariant_cast<const AssetBrowserEntry*>(leftData);
// auto rightEntry = qvariant_cast<const AssetBrowserEntry*>(rightData);
// folders should always come first
if (azrtti_istypeof<const FolderAssetBrowserEntry*>(leftEntry) &&
azrtti_istypeof<const SourceAssetBrowserEntry*>(rightEntry))
{
return false;
}
if (azrtti_istypeof<const SourceAssetBrowserEntry*>(leftEntry) &&
azrtti_istypeof<const FolderAssetBrowserEntry*>(rightEntry))
{
return true;
}
// // folders should always come first
// if (azrtti_istypeof<const FolderAssetBrowserEntry*>(leftEntry) &&
// azrtti_istypeof<const SourceAssetBrowserEntry*>(rightEntry))
// {
// return false;
// }
// if (azrtti_istypeof<const SourceAssetBrowserEntry*>(leftEntry) &&
// azrtti_istypeof<const FolderAssetBrowserEntry*>(rightEntry))
// {
// return true;
// }
// if both entries are of same type, sort alphabetically
return m_collator.compare(leftEntry->GetDisplayName(), rightEntry->GetDisplayName()) > 0;
}
}
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
// // if both entries are of same type, sort alphabetically
// return m_collator.compare(leftEntry->GetDisplayName(), rightEntry->GetDisplayName()) > 0;
// }
// }
// return QSortFilterProxyModel::lessThan(source_left, source_right);
//}
void AssetBrowserTableFilterModel::filterUpdatedSlot()
{
if (!m_alreadyRecomputingFilters)
{
m_alreadyRecomputingFilters = true;
// de-bounce it, since we may get many filter updates all at once.
QTimer::singleShot(0, this, [this]() {
m_alreadyRecomputingFilters = false;
FilterUpdatedSlotImmediate();
});
}
}
//void AssetBrowserTableFilterModel::filterUpdatedSlot()
//{
// if (!m_alreadyRecomputingFilters)
// {
// m_alreadyRecomputingFilters = true;
// // de-bounce it, since we may get many filter updates all at once.
// QTimer::singleShot(0, this, [this]() {
// m_alreadyRecomputingFilters = false;
// FilterUpdatedSlotImmediate();
// });
// }
//}
} // namespace AssetBrowser
} // namespace AzToolsFramework
@@ -7,6 +7,8 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/std/containers/fixed_unordered_set.h>
#include <AzCore/std/containers/vector.h>
//#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <QPointer>
AZ_PUSH_DISABLE_WARNING(
4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
@@ -19,6 +21,9 @@ namespace AzToolsFramework
{
namespace AssetBrowser
{
class AssetBrowserFilterModel;
class AssetBrowserTableModel
: public QSortFilterProxyModel
, public AssetBrowserComponentNotificationBus::Handler
@@ -38,6 +43,7 @@ namespace AzToolsFramework
// QSortFilterProxyModel
QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override;
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
QModelIndex parent(const QModelIndex& child) const override;
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
@@ -53,55 +59,56 @@ namespace AzToolsFramework
AssetBrowserEntry* GetAssetEntry(QModelIndex index) const;
int BuildMap(const QAbstractItemModel* model, const QModelIndex& parent = QModelIndex(), int row = 0);
private:
QPointer<AssetBrowserFilterModel> m_filterModel;
QMap<int, QModelIndex> m_indexMap;
QMap<QModelIndex, int> m_rowMap;
};
class AssetBrowserTableFilterModel
: public QSortFilterProxyModel
, public AssetBrowserComponentNotificationBus::Handler
{
Q_OBJECT
public:
explicit AssetBrowserTableFilterModel(QObject* parent = nullptr);
~AssetBrowserTableFilterModel();
//class AssetBrowserTableFilterModel
// : public QSortFilterProxyModel
// , public AssetBrowserComponentNotificationBus::Handler
//{
// Q_OBJECT
//public:
// explicit AssetBrowserTableFilterModel(QObject* parent = nullptr);
// ~AssetBrowserTableFilterModel();
void setSourceModel(QAbstractItemModel* sourceModel) override;
// asset type filtering
void SetFilter(FilterConstType filter);
void FilterUpdatedSlotImmediate();
// void setSourceModel(QAbstractItemModel* sourceModel) override;
// // asset type filtering
// void SetFilter(FilterConstType filter);
// void FilterUpdatedSlotImmediate();
//////////////////////////////////////////////////////////////////////////
// AssetBrowserComponentNotificationBus
//////////////////////////////////////////////////////////////////////////
void OnAssetBrowserComponentReady() override;
// //////////////////////////////////////////////////////////////////////////
// // AssetBrowserComponentNotificationBus
// //////////////////////////////////////////////////////////////////////////
// void OnAssetBrowserComponentReady() override;
Q_SIGNALS:
void filterChanged();
void entriesUpdated();
//Q_SIGNALS:
// void filterChanged();
// void entriesUpdated();
//////////////////////////////////////////////////////////////////////////
// QSortFilterProxyModel
protected:
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
bool filterAcceptsColumn(int source_column, const QModelIndex& /*source_parent*/) const override;
bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override;
//////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
// // QSortFilterProxyModel
//protected:
// bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
// bool filterAcceptsColumn(int source_column, const QModelIndex& /*source_parent*/) const override;
// bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override;
// //////////////////////////////////////////////////////////////////////////
public Q_SLOTS:
void filterUpdatedSlot();
//public Q_SLOTS:
// void filterUpdatedSlot();
private:
AZStd::fixed_unordered_set<int, 3, static_cast<int>(AssetBrowserEntry::Column::Count)> m_showColumn;
bool m_alreadyRecomputingFilters = false;
// asset source name match filter
FilterConstType m_filter;
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
QWeakPointer<const StringFilter> m_stringFilter;
QWeakPointer<const CompositeFilter> m_assetTypeFilter;
QCollator m_collator; // cache the collator as its somewhat expensive to constantly create and destroy one.
AZ_POP_DISABLE_WARNING
bool m_invalidateFilter = false;
};
//private:
// AZStd::fixed_unordered_set<int, 3, static_cast<int>(AssetBrowserEntry::Column::Count)> m_showColumn;
// bool m_alreadyRecomputingFilters = false;
// // asset source name match filter
// FilterConstType m_filter;
// AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
// QWeakPointer<const StringFilter> m_stringFilter;
// QWeakPointer<const CompositeFilter> m_assetTypeFilter;
// QCollator m_collator; // cache the collator as its somewhat expensive to constantly create and destroy one.
// AZ_POP_DISABLE_WARNING
// bool m_invalidateFilter = false;
//};
} // namespace AssetBrowser
} // namespace AzToolsFramework