eb51cd4c06
Consolidated duplicate asset browser code from multiple tools into single class in atom tools framework Moved creation of asset browser and Python terminal windows into base main window class Fixed docked window orientations Added checks to asset browser to prevent crashes if tree state saver was null Signed-off-by: Guthrie Adams <guthadam@amazon.com>
225 lines
9.0 KiB
C++
225 lines
9.0 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 <AssetBrowser/ui_AtomToolsAssetBrowser.h>
|
|
#include <AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzQtComponents/Utilities/DesktopUtilities.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
|
|
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
|
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
|
|
#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
|
|
|
|
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
|
#include <QAction>
|
|
#include <QCursor>
|
|
#include <QMenu>
|
|
#include <QMessageBox>
|
|
#include <QPushButton>
|
|
AZ_POP_DISABLE_WARNING
|
|
|
|
namespace AtomToolsFramework
|
|
{
|
|
AtomToolsAssetBrowser::AtomToolsAssetBrowser(QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_ui(new Ui::AtomToolsAssetBrowser)
|
|
{
|
|
using namespace AzToolsFramework::AssetBrowser;
|
|
|
|
m_ui->setupUi(this);
|
|
|
|
m_ui->m_searchWidget->Setup(true, true);
|
|
m_ui->m_searchWidget->setMinimumSize(QSize(150, 0));
|
|
|
|
m_ui->m_viewOptionButton->setIcon(QIcon(":/Icons/view.svg"));
|
|
m_ui->m_splitter->setSizes(QList<int>() << 400 << 200);
|
|
m_ui->m_splitter->setStretchFactor(0, 1);
|
|
|
|
// Get the asset browser model
|
|
AssetBrowserModel* assetBrowserModel = nullptr;
|
|
AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel);
|
|
AZ_Assert(assetBrowserModel, "Failed to get file browser model");
|
|
|
|
// Hook up the data set to the tree view
|
|
m_filterModel = aznew AssetBrowserFilterModel(this);
|
|
m_filterModel->setSourceModel(assetBrowserModel);
|
|
m_filterModel->SetFilter(CreateFilter());
|
|
|
|
m_ui->m_assetBrowserTreeViewWidget->setModel(m_filterModel);
|
|
m_ui->m_assetBrowserTreeViewWidget->SetShowSourceControlIcons(false);
|
|
m_ui->m_assetBrowserTreeViewWidget->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
|
|
|
|
// Maintains the tree expansion state between runs
|
|
m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_main");
|
|
|
|
connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AtomToolsAssetBrowser::UpdateFilter);
|
|
connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::activated, this, &AtomToolsAssetBrowser::OpenSelectedEntries);
|
|
connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::selectionChangedSignal, this, &AtomToolsAssetBrowser::UpdatePreview);
|
|
connect(m_ui->m_viewOptionButton, &QPushButton::clicked, this, &AtomToolsAssetBrowser::OpenOptionsMenu);
|
|
connect(
|
|
m_ui->m_searchWidget->GetFilter().data(), &AssetBrowserEntryFilter::updatedSignal, m_filterModel,
|
|
&AssetBrowserFilterModel::filterUpdatedSlot);
|
|
}
|
|
|
|
AtomToolsAssetBrowser::~AtomToolsAssetBrowser()
|
|
{
|
|
// Maintains the tree expansion state between runs
|
|
m_ui->m_assetBrowserTreeViewWidget->SaveState();
|
|
AZ::TickBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::SetFilterState(const AZStd::string& category, const AZStd::string& displayName, bool enabled)
|
|
{
|
|
m_ui->m_searchWidget->SetFilterState(category.c_str(), displayName.c_str(), enabled);
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::SetOpenHandler(AZStd::function<void(const AZStd::string&)> openHandler)
|
|
{
|
|
m_openHandler = openHandler;
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::SelectEntries(const AZStd::string& absolutePath)
|
|
{
|
|
if (!absolutePath.empty())
|
|
{
|
|
// Selecting a new asset in the browser is not guaranteed to happen immediately.
|
|
// The asset browser model notifications are sent before the model is updated.
|
|
// Instead of relying on the notifications, queue the selection and process it on tick until this change occurs.
|
|
m_pathToSelect = absolutePath;
|
|
AzFramework::StringFunc::Path::Normalize(m_pathToSelect);
|
|
AZ::TickBus::Handler::BusConnect();
|
|
}
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::OpenSelectedEntries()
|
|
{
|
|
const AZStd::vector<AssetBrowserEntry*> entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets();
|
|
|
|
const int multiSelectPromptThreshold = 10;
|
|
if (entries.size() >= multiSelectPromptThreshold)
|
|
{
|
|
QMessageBox::StandardButton result = QMessageBox::question(
|
|
QApplication::activeWindow(),
|
|
tr("Attemptng to open %1 files").arg(entries.size()),
|
|
tr("Would you like to open anyway?"),
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
if (result == QMessageBox::No)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (const AssetBrowserEntry* entry : entries)
|
|
{
|
|
if (entry && entry->GetEntryType() != AssetBrowserEntry::AssetEntryType::Folder && m_openHandler)
|
|
{
|
|
m_openHandler(entry->GetFullPath().c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::OpenOptionsMenu()
|
|
{
|
|
QMenu menu;
|
|
QAction* action = menu.addAction(tr("Show Asset Preview"), this, &AtomToolsAssetBrowser::TogglePreview);
|
|
action->setCheckable(true);
|
|
action->setChecked(m_ui->m_previewerFrame->isVisible());
|
|
menu.exec(QCursor::pos());
|
|
}
|
|
|
|
AzToolsFramework::AssetBrowser::FilterConstType AtomToolsAssetBrowser::CreateFilter() const
|
|
{
|
|
using namespace AzToolsFramework::AssetBrowser;
|
|
|
|
QSharedPointer<EntryTypeFilter> sourceFilter(new EntryTypeFilter);
|
|
sourceFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Source);
|
|
|
|
QSharedPointer<EntryTypeFilter> folderFilter(new EntryTypeFilter);
|
|
folderFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Folder);
|
|
|
|
QSharedPointer<CompositeFilter> sourceOrFolderFilter(new CompositeFilter(CompositeFilter::LogicOperatorType::OR));
|
|
sourceOrFolderFilter->AddFilter(sourceFilter);
|
|
sourceOrFolderFilter->AddFilter(folderFilter);
|
|
|
|
QSharedPointer<CompositeFilter> finalFilter(new CompositeFilter(CompositeFilter::LogicOperatorType::AND));
|
|
finalFilter->AddFilter(sourceOrFolderFilter);
|
|
finalFilter->AddFilter(m_ui->m_searchWidget->GetFilter());
|
|
|
|
return finalFilter;
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::UpdateFilter()
|
|
{
|
|
const bool hasFilter = !m_ui->m_searchWidget->GetFilterString().isEmpty();
|
|
constexpr bool selectFirstFilteredIndex = true;
|
|
m_ui->m_assetBrowserTreeViewWidget->UpdateAfterFilter(hasFilter, selectFirstFilteredIndex);
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::UpdatePreview()
|
|
{
|
|
const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets();
|
|
if (!selectedAssets.empty())
|
|
{
|
|
m_ui->m_previewerFrame->Display(selectedAssets.front());
|
|
}
|
|
else
|
|
{
|
|
m_ui->m_previewerFrame->Clear();
|
|
}
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::TogglePreview()
|
|
{
|
|
const bool isPreviewFrameVisible = m_ui->m_previewerFrame->isVisible();
|
|
m_ui->m_previewerFrame->setVisible(!isPreviewFrameVisible);
|
|
if (isPreviewFrameVisible)
|
|
{
|
|
m_browserState = m_ui->m_splitter->saveState();
|
|
m_ui->m_splitter->setSizes(QList({ 1, 0 }));
|
|
}
|
|
else
|
|
{
|
|
m_ui->m_splitter->restoreState(m_browserState);
|
|
}
|
|
}
|
|
|
|
void AtomToolsAssetBrowser::OnTick(float deltaTime, AZ::ScriptTimePoint time)
|
|
{
|
|
AZ_UNUSED(time);
|
|
AZ_UNUSED(deltaTime);
|
|
|
|
if (!m_pathToSelect.empty())
|
|
{
|
|
// Attempt to select the new path
|
|
AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast(
|
|
&AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Events::SelectFileAtPath, m_pathToSelect);
|
|
|
|
// Iterate over the selected entries to verify if the selection was made
|
|
for (const AssetBrowserEntry* entry : m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets())
|
|
{
|
|
if (entry)
|
|
{
|
|
AZStd::string sourcePath = entry->GetFullPath();
|
|
AzFramework::StringFunc::Path::Normalize(sourcePath);
|
|
if (m_pathToSelect == sourcePath)
|
|
{
|
|
// Once the selection is confirmed, cancel the operation and disconnect
|
|
AZ::TickBus::Handler::BusDisconnect();
|
|
m_pathToSelect.clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // namespace AtomToolsFramework
|
|
|
|
#include <AtomToolsFramework/AssetBrowser/moc_AtomToolsAssetBrowser.cpp>
|