You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.4 KiB
C++
144 lines
5.4 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
#include "AssetTreeEntry.h"
|
|
#include "EditorCommon.h"
|
|
|
|
#include <AzCore/std/containers/map.h>
|
|
#include <AzCore/Asset/AssetManager.h>
|
|
#include <AzCore/Asset/AssetTypeInfoBus.h>
|
|
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
|
|
|
UISliceLibraryFilter::UISliceLibraryFilter(const AZ::Data::AssetType& assetType, const char* pathToSearch)
|
|
: m_assetType(assetType)
|
|
, m_pathToSearch(pathToSearch)
|
|
{
|
|
// propagation = Down means the filter will examine all children recursively until it satisfies or no more children are left
|
|
// in our case we start from root entry and examine everything underneath it
|
|
SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::Down);
|
|
}
|
|
|
|
QString UISliceLibraryFilter::GetNameInternal() const
|
|
{
|
|
return "UISliceLibraryFilter";
|
|
}
|
|
|
|
bool UISliceLibraryFilter::MatchInternal(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
|
|
{
|
|
// entry must be a product
|
|
auto product = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
|
|
if (!product)
|
|
{
|
|
return false;
|
|
}
|
|
// entry must be of slice asset type
|
|
if (product->GetAssetType() != m_assetType)
|
|
{
|
|
return false;
|
|
}
|
|
// entry must be located within m_pathToSearch
|
|
if (AzFramework::StringFunc::Find(product->GetRelativePath().c_str(), m_pathToSearch.c_str()) == AZStd::string::npos)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
AssetTreeEntry::~AssetTreeEntry()
|
|
{
|
|
for (auto folderEntry : m_folders)
|
|
{
|
|
delete folderEntry.second;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void AssetTreeEntry::Insert(const AZStd::string& path, const AZStd::string& menuName, const AZ::Data::AssetId& assetId)
|
|
{
|
|
if (path.empty())
|
|
{
|
|
// there are no more folders in the pathname - add the leaf file entry
|
|
m_files.insert(AZStd::make_pair(menuName, assetId));
|
|
}
|
|
else
|
|
{
|
|
AZStd::string folderName;
|
|
AZStd::string remainderPath;
|
|
size_t separator = path.find('/');
|
|
if (separator == AZStd::string::npos)
|
|
{
|
|
folderName = path;
|
|
}
|
|
else
|
|
{
|
|
folderName = path.substr(0, separator);
|
|
if (path.length() > separator + 1)
|
|
{
|
|
remainderPath = path.substr(separator + 1);
|
|
}
|
|
}
|
|
|
|
AssetTreeEntry* folderEntry = nullptr;
|
|
// check if the folder already exists
|
|
if (m_folders.count(folderName) == 0)
|
|
{
|
|
// does not exist, create it and insert it in tree
|
|
folderEntry = new AssetTreeEntry;
|
|
m_folders.insert(AZStd::make_pair(folderName, folderEntry));
|
|
}
|
|
else
|
|
{
|
|
// already exists
|
|
folderEntry = m_folders[folderName];
|
|
}
|
|
|
|
// recurse down the pathname creating folders until we get to the leaf folder
|
|
// to insert the file entry
|
|
folderEntry->Insert(remainderPath, menuName, assetId);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
AssetTreeEntry* AssetTreeEntry::BuildAssetTree(const AZ::Data::AssetType& assetType, const AZStd::string& pathToSearch)
|
|
{
|
|
using namespace AzToolsFramework::AssetBrowser;
|
|
|
|
// asset browser model is a collection of all assets. We search it from root entry down for all ui slice files.
|
|
AssetBrowserModel* assetBrowserModel;
|
|
AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel);
|
|
AZ_Assert(assetBrowserModel, "Failed to get asset browser model");
|
|
|
|
const auto rootEntry = assetBrowserModel->GetRootEntry();
|
|
|
|
// UISliceLibraryFilter::Filter function returns all assets (recursively) that match the specified filter
|
|
// in this case we are only looking for ui slices.
|
|
AZStd::vector<const AssetBrowserEntry*> entries;
|
|
UISliceLibraryFilter filter(assetType, pathToSearch.c_str());
|
|
filter.Filter(entries, rootEntry.get());
|
|
|
|
AssetTreeEntry* assetTree = new AssetTreeEntry;
|
|
for (const auto& entry : entries)
|
|
{
|
|
auto product = azrtti_cast<const ProductAssetBrowserEntry*>(entry);
|
|
AZStd::string name;
|
|
AZStd::string path;
|
|
// split the product relative path into name and path. Note that product's parent (source entry) is used because
|
|
// product name stored in db is in all lower case, but we want to preserve case here
|
|
AzFramework::StringFunc::Path::Split(product->GetParent()->GetRelativePath().c_str(), nullptr, &path, &name);
|
|
// find next character position after default slice path in order to generate hierarchical sub-menus matching the subfolders
|
|
const size_t pos = AzFramework::StringFunc::Find(path.c_str(), pathToSearch.c_str()) + pathToSearch.length();
|
|
assetTree->Insert(path.substr(pos), name, product->GetAssetId());
|
|
}
|
|
return assetTree;
|
|
}
|