Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,345 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <Editor/View/Widgets/LoggingPanel/PivotTree/EntityPivotTree/EntityPivotTree.h>
namespace ScriptCanvasEditor
{
/////////////////////////////
// EntityPivotTreeGraphItem
/////////////////////////////
EntityPivotTreeGraphItem::EntityPivotTreeGraphItem(const ScriptCanvas::GraphIdentifier& graphIdentifier)
: PivotTreeGraphItem(graphIdentifier.m_assetId)
, m_checkState(Qt::CheckState::Unchecked)
, m_graphIdentifier(graphIdentifier)
{
}
Qt::CheckState EntityPivotTreeGraphItem::GetCheckState() const
{
return m_checkState;
}
void EntityPivotTreeGraphItem::SetCheckState(Qt::CheckState checkState)
{
m_checkState = checkState;
SignalDataChanged();
}
const ScriptCanvas::GraphIdentifier& EntityPivotTreeGraphItem::GetGraphIdentifier() const
{
return m_graphIdentifier;
}
//////////////////////////////
// EntityPivotTreeEntityItem
//////////////////////////////
EntityPivotTreeEntityItem::EntityPivotTreeEntityItem(const AZ::NamedEntityId& entityId)
: PivotTreeEntityItem(entityId)
, m_checkState(Qt::CheckState::Unchecked)
{
const bool isPivotElement = true;
SetIsPivotedElement(isPivotElement);
}
void EntityPivotTreeEntityItem::RegisterGraphIdentifier(const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapIter = m_pivotItems.find(graphIdentifier);
if (mapIter == m_pivotItems.end())
{
EntityPivotTreeGraphItem* graphItem = CreateChildNode<EntityPivotTreeGraphItem>(graphIdentifier);
m_pivotItems[graphIdentifier] = graphItem;
if (m_checkState != Qt::CheckState::PartiallyChecked)
{
graphItem->SetCheckState(m_checkState);
}
}
}
void EntityPivotTreeEntityItem::OnChildDataChanged(GraphCanvasTreeItem* treeItem)
{
EntityPivotTreeGraphItem* graphItem = static_cast<EntityPivotTreeGraphItem*>(treeItem);
ScriptCanvas::GraphIdentifier graphIdentifier = graphItem->GetGraphIdentifier();
if (graphItem->GetCheckState() == Qt::CheckState::Checked)
{
LoggingDataRequestBus::Event(GetLoggingDataId(), &LoggingDataRequests::EnableRegistration, GetNamedEntityId(), graphIdentifier);
}
else
{
LoggingDataRequestBus::Event(GetLoggingDataId(), &LoggingDataRequests::DisableRegistration, GetNamedEntityId(), graphIdentifier);
}
CalculateCheckState();
SignalDataChanged();
}
void EntityPivotTreeEntityItem::UnregisterGraphIdentifier(const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapIter = m_pivotItems.find(graphIdentifier);
if (mapIter != m_pivotItems.end())
{
RemoveChild(mapIter->second);
m_pivotItems.erase(mapIter);
}
}
Qt::CheckState EntityPivotTreeEntityItem::GetCheckState() const
{
return m_checkState;
}
void EntityPivotTreeEntityItem::SetCheckState(Qt::CheckState checkState)
{
if (m_checkState != checkState)
{
m_checkState = checkState;
for (const auto& mapIter : m_pivotItems)
{
mapIter.second->SetCheckState(checkState);
}
SignalDataChanged();
}
}
EntityPivotTreeGraphItem* EntityPivotTreeEntityItem::FindGraphTreeItem(const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapIter = m_pivotItems.find(graphIdentifier);
if (mapIter != m_pivotItems.end())
{
return mapIter->second;
}
else
{
return nullptr;
}
}
void EntityPivotTreeEntityItem::OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (namedEntityId == GetEntityId())
{
EntityPivotTreeGraphItem* item = FindGraphTreeItem(graphIdentifier);
if (item)
{
if (isEnabled)
{
item->SetCheckState(Qt::CheckState::Checked);
}
else
{
item->SetCheckState(Qt::CheckState::Unchecked);
}
}
}
}
void EntityPivotTreeEntityItem::OnLoggingDataIdSet()
{
LoggingDataNotificationBus::Handler::BusDisconnect();
LoggingDataNotificationBus::Handler::BusConnect(GetLoggingDataId());
}
void EntityPivotTreeEntityItem::CalculateCheckState()
{
bool isChecked = false;
bool isUnchecked = false;
for (const auto& mapIter : m_pivotItems)
{
if (mapIter.second->GetCheckState() == Qt::CheckState::Checked)
{
isChecked = true;
}
else
{
isUnchecked = true;
}
if (isChecked && isUnchecked)
{
break;
}
}
m_checkState = Qt::CheckState::Unchecked;
if (isChecked && isUnchecked)
{
m_checkState = Qt::CheckState::PartiallyChecked;
}
else if (isChecked)
{
m_checkState = Qt::CheckState::Checked;
}
}
////////////////////////
// EntityPivotTreeRoot
////////////////////////
EntityPivotTreeRoot::EntityPivotTreeRoot()
: m_capturingData(false)
{
}
void EntityPivotTreeRoot::OnDataSourceChanged(const LoggingDataId& aggregateDataSource)
{
ClearData();
LoggingDataNotificationBus::Handler::BusDisconnect();
m_dataSource = aggregateDataSource;
const LoggingDataAggregator* dataAggregator = nullptr;
LoggingDataRequestBus::EventResult(dataAggregator, m_dataSource, &LoggingDataRequests::FindLoggingData);
if (dataAggregator)
{
const EntityGraphRegistrationMap& registrationMap = dataAggregator->GetEntityGraphRegistrationMap();
for (const auto& mapIter : registrationMap)
{
OnEntityGraphRegistered(mapIter.first, mapIter.second);
}
if (dataAggregator->IsCapturingData())
{
OnDataCaptureBegin();
}
}
LoggingDataNotificationBus::Handler::BusConnect(m_dataSource);
}
void EntityPivotTreeRoot::OnDataCaptureBegin()
{
m_capturingData = true;
}
void EntityPivotTreeRoot::OnDataCaptureEnd()
{
m_capturingData = false;
for (const auto& unregistrationPair : m_delayedUnregistrations)
{
OnEntityGraphUnregistered(unregistrationPair.first, unregistrationPair.second);
}
m_delayedUnregistrations.clear();
}
void EntityPivotTreeRoot::OnEntityGraphRegistered(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
EntityPivotTreeEntityItem* pivotItem = nullptr;
auto mapIter = m_entityTreeItemMapping.find(namedEntityId);
if (mapIter != m_entityTreeItemMapping.end())
{
pivotItem = mapIter->second;
}
else
{
pivotItem = CreateChildNode<EntityPivotTreeEntityItem>(namedEntityId);
m_entityTreeItemMapping[namedEntityId] = pivotItem;
}
if (pivotItem)
{
pivotItem->RegisterGraphIdentifier(graphIdentifier);
}
}
void EntityPivotTreeRoot::OnEntityGraphUnregistered(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapIter = m_entityTreeItemMapping.find(namedEntityId);
if (mapIter != m_entityTreeItemMapping.end())
{
EntityPivotTreeEntityItem* pivotItem = mapIter->second;
if (!m_capturingData)
{
pivotItem->UnregisterGraphIdentifier(graphIdentifier);
if (pivotItem->GetChildCount() == 0)
{
RemoveChild(pivotItem);
m_entityTreeItemMapping.erase(mapIter);
}
}
else
{
m_delayedUnregistrations.emplace_back(namedEntityId, graphIdentifier);
}
}
}
void EntityPivotTreeRoot::OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId)
{
return;
}
auto mapIter = m_entityTreeItemMapping.find(namedEntityId);
if (mapIter != m_entityTreeItemMapping.end())
{
EntityPivotTreeGraphItem* pivotTreeItem = mapIter->second->FindGraphTreeItem(graphIdentifier);
if (pivotTreeItem)
{
if (isEnabled)
{
pivotTreeItem->SetCheckState(Qt::CheckState::Checked);
}
else
{
pivotTreeItem->SetCheckState(Qt::CheckState::Unchecked);
}
}
}
}
void EntityPivotTreeRoot::ClearData()
{
ClearChildren();
m_entityTreeItemMapping.clear();
}
//////////////////////////
// EntityPivotTreeWidget
//////////////////////////
EntityPivotTreeWidget::EntityPivotTreeWidget(QWidget* parent)
: PivotTreeWidget(aznew EntityPivotTreeRoot(), AZ_CRC("EntityPivotTreeId", 0xd44255d6), parent)
{
}
#include <Editor/View/Widgets/LoggingPanel/PivotTree/EntityPivotTree/moc_EntityPivotTree.cpp>
}
@@ -0,0 +1,124 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/std/containers/unordered_map.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/PivotTreeWidget.h>
#include <Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.h>
#endif
namespace ScriptCanvasEditor
{
class EntityPivotTreeGraphItem
: public PivotTreeGraphItem
{
friend class EntityPivotTreeEntityItem;
public:
AZ_CLASS_ALLOCATOR(EntityPivotTreeGraphItem, AZ::SystemAllocator, 0);
AZ_RTTI(EntityPivotTreeGraphItem, "{CE064D69-D478-4594-A596-5DBE0DE46F6E}", PivotTreeGraphItem);
EntityPivotTreeGraphItem(const ScriptCanvas::GraphIdentifier& graphIdentifier);
Qt::CheckState GetCheckState() const override final;
void SetCheckState(Qt::CheckState checkState) override final;
const ScriptCanvas::GraphIdentifier& GetGraphIdentifier() const;
private:
Qt::CheckState m_checkState;
ScriptCanvas::GraphIdentifier m_graphIdentifier;
};
class EntityPivotTreeEntityItem
: public PivotTreeEntityItem
, public LoggingDataNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(EntityPivotTreeEntityItem, AZ::SystemAllocator, 0);
AZ_RTTI(EntityPivotTreeEntityItem, "{027A8617-4095-46F1-B9AD-49E360C90C73}", PivotTreeEntityItem);
EntityPivotTreeEntityItem(const AZ::NamedEntityId& entityId);
void RegisterGraphIdentifier(const ScriptCanvas::GraphIdentifier& graphIdentifier);
void UnregisterGraphIdentifier(const ScriptCanvas::GraphIdentifier& graphIdentifier);
void OnChildDataChanged(GraphCanvasTreeItem* treeItem) override;
Qt::CheckState GetCheckState() const override final;
void SetCheckState(Qt::CheckState debugging) override final;
EntityPivotTreeGraphItem* FindGraphTreeItem(const ScriptCanvas::GraphIdentifier& registrationData);
// LoggingDataNotificationBus
void OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& registrationData) override;
////
protected:
void OnLoggingDataIdSet() override;
private:
void CalculateCheckState();
Qt::CheckState m_checkState;
AZStd::unordered_map< ScriptCanvas::GraphIdentifier, EntityPivotTreeGraphItem*> m_pivotItems;
};
class EntityPivotTreeRoot
: public PivotTreeRoot
, public LoggingDataNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(EntityPivotTreeRoot, AZ::SystemAllocator, 0);
AZ_RTTI(EntityPivotTreeRoot, "{93DE206E-CE31-4A59-BEBF-87B26E5A28D2}", PivotTreeRoot);
EntityPivotTreeRoot();
// PivotTreeRoot
void OnDataSourceChanged(const LoggingDataId& aggregateDataSource) override;
////
// LoggedDataNotifications
void OnDataCaptureBegin() override;
void OnDataCaptureEnd() override;
void OnEntityGraphRegistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& assetId) override;
void OnEntityGraphUnregistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& assetId) override;
void OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& registrationData) override;
////
private:
void ClearData();
LoggingDataId m_dataSource;
AZStd::unordered_map< AZ::EntityId, EntityPivotTreeEntityItem* > m_entityTreeItemMapping;
AZStd::vector < AZStd::pair < AZ::NamedEntityId, ScriptCanvas::GraphIdentifier > > m_delayedUnregistrations;
bool m_capturingData;
};
class EntityPivotTreeWidget
: public PivotTreeWidget
{
Q_OBJECT
public:
EntityPivotTreeWidget(QWidget* parent);
};
}
@@ -0,0 +1,583 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/GraphPivotTree/GraphPivotTree.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
namespace ScriptCanvasEditor
{
/////////////////////////////
// GraphPivotTreeEntityItem
/////////////////////////////
GraphPivotTreeEntityItem::GraphPivotTreeEntityItem(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
: PivotTreeEntityItem(namedEntityId)
, m_checkState(Qt::CheckState::Unchecked)
, m_graphIdentifier(graphIdentifier)
{
}
Qt::CheckState GraphPivotTreeEntityItem::GetCheckState() const
{
return m_checkState;
}
void GraphPivotTreeEntityItem::SetCheckState(Qt::CheckState checkState)
{
m_checkState = checkState;
SignalDataChanged();
}
const ScriptCanvas::GraphIdentifier& GraphPivotTreeEntityItem::GetGraphIdentifier() const
{
return m_graphIdentifier;
}
////////////////////////////
// GraphPivotTreeGraphItem
////////////////////////////
GraphPivotTreeGraphItem::GraphPivotTreeGraphItem(const AZ::Data::AssetId& assetId)
: PivotTreeGraphItem(assetId)
, m_checkState(Qt::CheckState::Unchecked)
{
const bool isPivotedElement = true;
SetIsPivotedElement(isPivotedElement);
const bool isChecked = true;
SetupDynamicallySpawnedElementItem(isChecked);
}
void GraphPivotTreeGraphItem::OnDataSwitch()
{
bool isChecked = true;
auto pivotIter = m_pivotItems.find(AZ::EntityId());
if (pivotIter != m_pivotItems.end())
{
GraphPivotTreeEntityItem* entityItem = pivotIter->second;
isChecked = entityItem->GetCheckState() == Qt::CheckState::Checked;
}
m_pivotItems.clear();
ClearChildren();
SetupDynamicallySpawnedElementItem(isChecked);
}
void GraphPivotTreeGraphItem::RegisterEntity(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto pivotRange = m_pivotItems.equal_range(entityId);
bool foundElement = false;
for (auto mapIter = pivotRange.first; mapIter != pivotRange.second; ++mapIter)
{
if (mapIter->second->GetGraphIdentifier() == graphIdentifier)
{
foundElement = true;
break;
}
}
if (!foundElement)
{
GraphPivotTreeEntityItem* entityItem = CreateChildNode<GraphPivotTreeEntityItem>(entityId, graphIdentifier);
entityItem->SetCheckState(Qt::CheckState::Unchecked);
m_pivotItems.insert(AZStd::make_pair(entityId,entityItem));
}
}
void GraphPivotTreeGraphItem::UnregisterEntity(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto pivotRange = m_pivotItems.equal_range(entityId);
for (auto pivotIter = pivotRange.first; pivotIter != pivotRange.second; ++pivotIter)
{
if (pivotIter->second->GetGraphIdentifier() == graphIdentifier)
{
RemoveChild(pivotIter->second);
m_pivotItems.erase(pivotIter);
break;
}
}
}
void GraphPivotTreeGraphItem::OnChildDataChanged(GraphCanvasTreeItem* treeItem)
{
GraphPivotTreeEntityItem* graphItem = static_cast<GraphPivotTreeEntityItem*>(treeItem);
if (graphItem->GetCheckState() == Qt::CheckState::Checked)
{
LoggingDataRequestBus::Event(GetLoggingDataId(), &LoggingDataRequests::EnableRegistration, graphItem->GetNamedEntityId(), graphItem->GetGraphIdentifier());
}
else
{
LoggingDataRequestBus::Event(GetLoggingDataId(), &LoggingDataRequests::DisableRegistration, graphItem->GetNamedEntityId(), graphItem->GetGraphIdentifier());
}
CalculateCheckState();
SignalDataChanged();
}
Qt::CheckState GraphPivotTreeGraphItem::GetCheckState() const
{
return m_checkState;
}
void GraphPivotTreeGraphItem::SetCheckState(Qt::CheckState checkState)
{
if (checkState != m_checkState)
{
m_checkState = checkState;
for (int i = 0; i < GetChildCount(); ++i)
{
PivotTreeItem* treeItem = static_cast<PivotTreeItem*>(FindChildByRow(i));
if (treeItem)
{
treeItem->SetCheckState(checkState);
}
}
SignalDataChanged();
}
}
GraphPivotTreeEntityItem* GraphPivotTreeGraphItem::FindDynamicallySpawnedTreeItem() const
{
return FindEntityTreeItem(AZ::NamedEntityId(AZ::EntityId(), ""), ScriptCanvas::GraphIdentifier(GetAssetId(), k_dynamicallySpawnedControllerId));
}
GraphPivotTreeEntityItem* GraphPivotTreeGraphItem::FindEntityTreeItem(const AZ::NamedEntityId& namedEntityId, [[maybe_unused]] const ScriptCanvas::GraphIdentifier& graphIdentifier) const
{
auto pivotIter = m_pivotItems.find(namedEntityId);
if (pivotIter != m_pivotItems.end())
{
return pivotIter->second;
}
return nullptr;
}
void GraphPivotTreeGraphItem::OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (graphIdentifier.m_assetId == GetAssetId())
{
GraphPivotTreeEntityItem* item = FindEntityTreeItem(namedEntityId, graphIdentifier);
if (item)
{
if (isEnabled)
{
item->SetCheckState(Qt::CheckState::Checked);
}
else
{
item->SetCheckState(Qt::CheckState::Unchecked);
}
}
}
}
void GraphPivotTreeGraphItem::OnLoggingDataIdSet()
{
LoggingDataNotificationBus::Handler::BusDisconnect();
LoggingDataNotificationBus::Handler::BusConnect(GetLoggingDataId());
}
void GraphPivotTreeGraphItem::SetupDynamicallySpawnedElementItem([[maybe_unused]] bool isChecked)
{
AZ::NamedEntityId dynamicEntityId(AZ::EntityId(), "All Graph Instances");
RegisterEntity(dynamicEntityId, ScriptCanvas::GraphIdentifier(GetAssetId(), k_dynamicallySpawnedControllerId));
}
void GraphPivotTreeGraphItem::CalculateCheckState()
{
bool isChecked = false;
bool isUnchecked = false;
for (int i = 0; i < GetChildCount(); ++i)
{
PivotTreeItem* treeItem = static_cast<PivotTreeItem*>(FindChildByRow(i));
if (treeItem)
{
if (treeItem->GetCheckState() == Qt::CheckState::Checked)
{
isChecked = true;
}
else
{
isUnchecked = true;
}
if (isChecked && isUnchecked)
{
break;
}
}
}
if (isChecked && isUnchecked)
{
m_checkState = Qt::CheckState::PartiallyChecked;
}
else if (isChecked)
{
m_checkState = Qt::CheckState::Checked;
}
else
{
m_checkState = Qt::CheckState::Unchecked;
}
}
/////////////////////////
// GraphPivotTreeFolder
/////////////////////////
GraphPivotTreeFolder::GraphPivotTreeFolder(AZStd::string_view folder)
: m_folderName(folder)
, m_checkState(Qt::CheckState::Unchecked)
{
const bool isPivotElement = true;
SetIsPivotedElement(isPivotElement);
}
Qt::CheckState GraphPivotTreeFolder::GetCheckState() const
{
return m_checkState;
}
void GraphPivotTreeFolder::SetCheckState(Qt::CheckState checkState)
{
if (m_checkState != checkState)
{
m_checkState = checkState;
for (int i = 0; i < GetChildCount(); ++i)
{
PivotTreeItem* pivotTreeItem = static_cast<PivotTreeItem*>(FindChildByRow(i));
pivotTreeItem->SetCheckState(checkState);
}
SignalDataChanged();
}
}
AZStd::string GraphPivotTreeFolder::GetDisplayName() const
{
return m_folderName;
}
void GraphPivotTreeFolder::OnChildDataChanged([[maybe_unused]] GraphCanvasTreeItem* treeItem)
{
CalculateCheckState();
SignalDataChanged();
}
void GraphPivotTreeFolder::CalculateCheckState()
{
bool isChecked = false;
bool isUnchecked = false;
for (int i = 0; i < GetChildCount(); ++i)
{
const PivotTreeItem* pivotTreeItem = static_cast<const PivotTreeItem*>(FindChildByRow(i));
if (pivotTreeItem)
{
Qt::CheckState checkState = pivotTreeItem->GetCheckState();
if (checkState == Qt::CheckState::PartiallyChecked)
{
isChecked = true;
isUnchecked = true;
}
else if (checkState == Qt::CheckState::Checked)
{
isChecked = true;
}
else
{
isUnchecked = true;
}
if (isChecked && isUnchecked)
{
break;
}
}
}
if (isChecked && isUnchecked)
{
m_checkState = Qt::CheckState::PartiallyChecked;
}
else if (isChecked)
{
m_checkState = Qt::CheckState::Checked;
}
else
{
m_checkState = Qt::CheckState::Unchecked;
}
SignalDataChanged();
}
///////////////////////
// GraphPivotTreeRoot
///////////////////////
GraphPivotTreeRoot::GraphPivotTreeRoot()
: m_categorizer((*this))
{
AzToolsFramework::AssetBrowser::AssetBrowserModel* assetBrowserModel = nullptr;
AzToolsFramework::AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AzToolsFramework::AssetBrowser::AssetBrowserComponentRequests::GetAssetBrowserModel);
m_assetModel = new AzToolsFramework::AssetBrowser::AssetBrowserFilterModel();
AzToolsFramework::AssetBrowser::AssetGroupFilter* assetFilter = new AzToolsFramework::AssetBrowser::AssetGroupFilter();
assetFilter->SetAssetGroup(ScriptCanvasEditor::ScriptCanvasAsset::Description::GetGroup(azrtti_typeid<ScriptCanvasAsset>()));
assetFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
QObject::connect(m_assetModel, &QAbstractItemModel::rowsInserted, this, &GraphPivotTreeRoot::OnScriptCanvasGraphAssetAdded);
QObject::connect(m_assetModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &GraphPivotTreeRoot::OnScriptCanvasGraphAssetRemoved);
m_assetModel->setSourceModel(assetBrowserModel);
SetAllowPruneOnEmpty(false);
}
void GraphPivotTreeRoot::OnDataSourceChanged(const LoggingDataId& aggregateDataSource)
{
if (LoggingDataNotificationBus::Handler::BusIsConnected())
{
LoggingDataNotificationBus::Handler::BusDisconnect();
}
m_loggedDataId = aggregateDataSource;
for (auto assetPair : m_graphTreeItemMapping)
{
assetPair.second->OnDataSwitch();
}
const LoggingDataAggregator* dataAggregator = nullptr;
LoggingDataRequestBus::EventResult(dataAggregator, m_loggedDataId, &LoggingDataRequests::FindLoggingData);
if (dataAggregator)
{
const EntityGraphRegistrationMap& entityPivoting = dataAggregator->GetEntityGraphRegistrationMap();
for (const auto& registrationMap : entityPivoting)
{
OnEntityGraphUnregistered(registrationMap.first, registrationMap.second);
}
if (dataAggregator->IsCapturingData())
{
OnDataCaptureBegin();
}
}
LoggingDataNotificationBus::Handler::BusConnect(m_loggedDataId);
}
void GraphPivotTreeRoot::OnDataCaptureBegin()
{
}
void GraphPivotTreeRoot::OnDataCaptureEnd()
{
}
void GraphPivotTreeRoot::OnEntityGraphRegistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
GraphPivotTreeGraphItem* graphItem = nullptr;
auto mapPairIter = m_graphTreeItemMapping.find(graphIdentifier.m_assetId);
if (mapPairIter == m_graphTreeItemMapping.end())
{
AZStd::string fullPath;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(fullPath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, graphIdentifier.m_assetId);
GraphCanvasTreeItem* parentItem = m_categorizer.GetCategoryNode(fullPath.c_str(), this);
graphItem = parentItem->CreateChildNode<GraphPivotTreeGraphItem>(graphIdentifier.m_assetId);
m_graphTreeItemMapping[graphIdentifier.m_assetId] = graphItem;
}
else
{
graphItem = mapPairIter->second;
}
if (entityId.IsValid())
{
graphItem->RegisterEntity(entityId, graphIdentifier);
}
}
void GraphPivotTreeRoot::OnEntityGraphUnregistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapPairIter = m_graphTreeItemMapping.find(graphIdentifier.m_assetId);
if (mapPairIter != m_graphTreeItemMapping.end())
{
mapPairIter->second->UnregisterEntity(entityId, graphIdentifier);
if (mapPairIter->second->GetChildCount() == 0)
{
m_categorizer.PruneEmptyNodes();
}
}
}
void GraphPivotTreeRoot::OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
auto mapIter = m_graphTreeItemMapping.find(graphIdentifier.m_assetId);
if (mapIter != m_graphTreeItemMapping.end())
{
GraphPivotTreeEntityItem* pivotTreeItem = nullptr;
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId)
{
pivotTreeItem = mapIter->second->FindDynamicallySpawnedTreeItem();
}
else
{
pivotTreeItem = mapIter->second->FindEntityTreeItem(namedEntityId, graphIdentifier);
}
if (pivotTreeItem)
{
if (isEnabled)
{
pivotTreeItem->SetCheckState(Qt::CheckState::Checked);
}
else
{
pivotTreeItem->SetCheckState(Qt::CheckState::Unchecked);
}
}
}
}
GraphCanvas::GraphCanvasTreeItem* GraphPivotTreeRoot::CreateCategoryNode([[maybe_unused]] AZStd::string_view categoryPath, AZStd::string_view categoryName, GraphCanvasTreeItem* parent) const
{
return parent->CreateChildNode<GraphPivotTreeFolder>(categoryName);
}
void GraphPivotTreeRoot::OnScriptCanvasGraphAssetAdded(const QModelIndex& parentIndex, int first, int last)
{
for (int i = first; i <= last; ++i)
{
QModelIndex modelIndex = m_assetModel->index(i, 0, parentIndex);
QModelIndex sourceIndex = m_assetModel->mapToSource(modelIndex);
AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry = reinterpret_cast<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>(sourceIndex.internalPointer());
ProcessEntry(entry);
}
}
void GraphPivotTreeRoot::OnScriptCanvasGraphAssetRemoved(const QModelIndex& parentIndex, int first, int last)
{
// TODO: This likely needs to be handled better
for (int i = first; i <= last; ++i)
{
QModelIndex modelIndex = m_assetModel->index(i, 0, parentIndex);
QModelIndex sourceIndex = m_assetModel->mapToSource(modelIndex);
AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry = reinterpret_cast<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>(sourceIndex.internalPointer());
if (entry && entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
{
auto mapIter = m_graphTreeItemMapping.find(productEntry->GetAssetId());
if (mapIter != m_graphTreeItemMapping.end() && mapIter->second)
{
GraphCanvas::GraphCanvasTreeItem* currentItem = mapIter->second;
currentItem->ClearChildren();
m_graphTreeItemMapping.erase(mapIter);
m_categorizer.PruneNode(currentItem);
}
OnEntityGraphUnregistered(AZ::NamedEntityId(), ScriptCanvas::GraphIdentifier(productEntry->GetAssetId(), k_dynamicallySpawnedControllerId));
}
}
}
}
void GraphPivotTreeRoot::ProcessEntry(AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
if (entry && entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = static_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
{
OnEntityGraphRegistered(AZ::NamedEntityId(), ScriptCanvas::GraphIdentifier(productEntry->GetAssetId(), k_dynamicallySpawnedControllerId));
}
}
}
void GraphPivotTreeRoot::TraverseTree(QModelIndex index)
{
QModelIndex sourceIndex = m_assetModel->mapToSource(index);
AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry = reinterpret_cast<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>(sourceIndex.internalPointer());
ProcessEntry(entry);
int rowCount = m_assetModel->rowCount(index);
for (int i = 0; i < rowCount; ++i)
{
QModelIndex nextIndex = m_assetModel->index(i, 0, index);
TraverseTree(nextIndex);
}
}
/////////////////////////
// GraphPivotTreeWidget
/////////////////////////
GraphPivotTreeWidget::GraphPivotTreeWidget(QWidget* parent)
: PivotTreeWidget(aznew GraphPivotTreeRoot(), AZ_CRC("GraphPivotTreeId", 0xed815ba3), parent)
{
static_cast<GraphPivotTreeRoot*>(GetTreeRoot())->TraverseTree();
}
#include <Editor/View/Widgets/LoggingPanel/PivotTree/GraphPivotTree/moc_GraphPivotTree.cpp>
}
@@ -0,0 +1,179 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <GraphCanvas/Widgets/GraphCanvasTreeCategorizer.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/PivotTreeWidget.h>
#include <Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.h>
#endif
namespace ScriptCanvasEditor
{
class GraphPivotTreeEntityItem
: public PivotTreeEntityItem
{
friend class EntityPivotTreeEntityItem;
public:
AZ_CLASS_ALLOCATOR(GraphPivotTreeEntityItem, AZ::SystemAllocator, 0);
AZ_RTTI(GraphPivotTreeEntityItem, "{17B2C45B-D63B-458E-9A2F-ED0A8218A77B}", PivotTreeEntityItem);
GraphPivotTreeEntityItem(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier);
Qt::CheckState GetCheckState() const override final;
void SetCheckState(Qt::CheckState checkState) override final;
const ScriptCanvas::GraphIdentifier& GetGraphIdentifier() const;
private:
Qt::CheckState m_checkState;
ScriptCanvas::GraphIdentifier m_graphIdentifier;
};
class GraphPivotTreeGraphItem
: public PivotTreeGraphItem
, public LoggingDataNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(GraphPivotTreeGraphItem, AZ::SystemAllocator, 0);
AZ_RTTI(GraphPivotTreeGraphItem, "{9B449D02-109E-4D9E-BA99-35C52106432C}", PivotTreeGraphItem);
GraphPivotTreeGraphItem(const AZ::Data::AssetId& assetId);
void OnDataSwitch();
void RegisterEntity(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier);
void UnregisterEntity(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier);
void OnChildDataChanged(GraphCanvasTreeItem* treeItem) override;
Qt::CheckState GetCheckState() const override final;
void SetCheckState(Qt::CheckState debugging) override final;
GraphPivotTreeEntityItem* FindDynamicallySpawnedTreeItem() const;
GraphPivotTreeEntityItem* FindEntityTreeItem(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) const;
// LoggingDataNotificationBus
void OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
////
protected:
void OnLoggingDataIdSet() override;
private:
void SetupDynamicallySpawnedElementItem(bool isChecked);
void CalculateCheckState();
Qt::CheckState m_checkState;
AZStd::unordered_multimap< AZ::EntityId, GraphPivotTreeEntityItem*> m_pivotItems;
};
class GraphPivotTreeFolder
: public PivotTreeItem
{
public:
AZ_CLASS_ALLOCATOR(GraphPivotTreeFolder, AZ::SystemAllocator, 0);
AZ_RTTI(GraphPivotTreeRoot, "{E67BBC27-6E0D-4D56-A7D4-9389FE30E909}", PivotTreeItem);
GraphPivotTreeFolder(AZStd::string_view folder);
~GraphPivotTreeFolder() override = default;
Qt::CheckState GetCheckState() const override final;
protected:
void SetCheckState(Qt::CheckState debugging) override final;
AZStd::string GetDisplayName() const override final;
void OnChildDataChanged(GraphCanvasTreeItem* treeItem) override;
private:
void CalculateCheckState();
AZStd::string m_folderName;
Qt::CheckState m_checkState;
};
class GraphPivotTreeRoot
: public PivotTreeRoot
, public LoggingDataNotificationBus::Handler
, public GraphCanvas::CategorizerInterface
, public QObject
{
public:
friend class GraphPivotTreeWidget;
AZ_CLASS_ALLOCATOR(GraphPivotTreeRoot, AZ::SystemAllocator, 0);
AZ_RTTI(GraphPivotTreeRoot, "{B4CD0FCF-F8C7-44D5-BF4D-12A52BB088CB}", PivotTreeRoot);
GraphPivotTreeRoot();
~GraphPivotTreeRoot() override = default;
// PivotTreeRoot
void OnDataSourceChanged(const LoggingDataId& aggregateDataSource) override;
////
// LoggedDataNotifications
void OnDataCaptureBegin() override;
void OnDataCaptureEnd() override;
void OnEntityGraphRegistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
void OnEntityGraphUnregistered(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& assetId) override;
void OnEnabledStateChanged(bool isEnabled, const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
////
// Category Interface
GraphCanvas::GraphCanvasTreeItem* CreateCategoryNode(AZStd::string_view categoryPath, AZStd::string_view categoryName, GraphCanvasTreeItem* parent) const override;
////
protected:
// Slots to hook up into the asset model
void OnScriptCanvasGraphAssetAdded(const QModelIndex& parentIndex, int first, int last);
void OnScriptCanvasGraphAssetRemoved(const QModelIndex& parentIndex, int first, int last);
////
private:
void ProcessEntry(AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void TraverseTree(QModelIndex index = QModelIndex());
LoggingDataId m_dataSource;
AZStd::unordered_map< AZ::Data::AssetId, GraphPivotTreeGraphItem* > m_graphTreeItemMapping;
GraphCanvas::GraphCanvasTreeCategorizer m_categorizer;
LoggingDataId m_loggedDataId;
bool m_capturingData;
AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_assetModel;
};
class GraphPivotTreeWidget
: public PivotTreeWidget
{
Q_OBJECT
public:
GraphPivotTreeWidget(QWidget* parent);
};
}
@@ -0,0 +1,430 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "precompiled.h"
#include <AzCore/Asset/AssetManagerBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/PivotTreeWidget.h>
// Disable warnings in moc code
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <Editor/View/Widgets/LoggingPanel/PivotTree/ui_PivotTreeWidget.h>
AZ_POP_DISABLE_OVERRIDE_WARNING
namespace ScriptCanvasEditor
{
//////////////////
// PivotTreeItem
//////////////////
PivotTreeItem::PivotTreeItem()
: m_isPivotElement(false)
{
}
PivotTreeItem::~PivotTreeItem()
{
}
const LoggingDataId& PivotTreeItem::GetLoggingDataId() const
{
return m_loggingDataId;
}
int PivotTreeItem::GetColumnCount() const
{
return Column::Count;
}
Qt::ItemFlags PivotTreeItem::Flags([[maybe_unused]] const QModelIndex& index) const
{
Qt::ItemFlags flags = Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsUserCheckable;
if (m_isPivotElement)
{
flags |= Qt::ItemFlag::ItemIsAutoTristate;
}
return flags;
}
QVariant PivotTreeItem::Data(const QModelIndex& index, int role) const
{
switch (index.column())
{
case Column::Name:
{
if (role == Qt::DisplayRole
|| role == Qt::ToolTip)
{
return QString(GetDisplayName().c_str());
}
else if (role == Qt::CheckStateRole)
{
return GetCheckState();
}
}
break;
default:
break;
}
return QVariant();
}
bool PivotTreeItem::SetData(const QModelIndex& index, const QVariant& value, int role)
{
switch (index.column())
{
case Column::Name:
{
if (role == Qt::CheckStateRole)
{
Qt::CheckState checkState = value.value<Qt::CheckState>();
// Never want to let the user interaction set it to
if (checkState == Qt::CheckState::PartiallyChecked)
{
if (GetCheckState() == Qt::CheckState::Unchecked)
{
checkState = Qt::CheckState::Checked;
}
else
{
checkState = Qt::CheckState::Unchecked;
}
}
SetCheckState(checkState);
}
}
break;
default:
break;
}
return false;
}
void PivotTreeItem::OnChildAdded(GraphCanvasTreeItem* treeItem)
{
if (m_loggingDataId.IsValid())
{
static_cast<PivotTreeItem*>(treeItem)->SetLoggingDataId(m_loggingDataId);
}
}
void PivotTreeItem::OnLoggingDataIdSet()
{
}
void PivotTreeItem::SetLoggingDataId(const LoggingDataId& dataId)
{
if (dataId != m_loggingDataId)
{
m_loggingDataId = dataId;
for (int i = 0; i < GetChildCount(); ++i)
{
PivotTreeItem* treeItem = static_cast<PivotTreeItem*>(FindChildByRow(i));
treeItem->SetLoggingDataId(dataId);
}
OnLoggingDataIdSet();
}
}
void PivotTreeItem::SetIsPivotedElement(bool isPivotElement)
{
m_isPivotElement = isPivotElement;
}
////////////////////////
// PivotTreeEntityItem
////////////////////////
PivotTreeEntityItem::PivotTreeEntityItem(const AZ::NamedEntityId& namedEntityId)
: m_namedEntityId(namedEntityId)
{
}
const AZ::NamedEntityId& PivotTreeEntityItem::GetNamedEntityId() const
{
return m_namedEntityId;
}
AZStd::string PivotTreeEntityItem::GetDisplayName() const
{
return m_namedEntityId.ToString();
}
const AZ::EntityId& PivotTreeEntityItem::GetEntityId() const
{
return m_namedEntityId;
}
///////////////////////
// PivotTreeGraphItem
///////////////////////
PivotTreeGraphItem::PivotTreeGraphItem(const AZ::Data::AssetId& assetId)
: m_assetId(assetId)
{
// Determine the file name for our asset
AZStd::string fullPath;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(fullPath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_assetId);
AZStd::size_t indexOf = fullPath.find_last_of('/');
if (indexOf == AZStd::string::npos)
{
m_assetName = fullPath;
m_assetPath = "";
}
else
{
m_assetPath = fullPath.substr(0, indexOf);
m_assetName = fullPath.substr(indexOf + 1);
}
}
AZStd::string PivotTreeGraphItem::GetDisplayName() const
{
return m_assetName;
}
const AZ::Data::AssetId& PivotTreeGraphItem::GetAssetId() const
{
return m_assetId;
}
AZStd::string_view PivotTreeGraphItem::GetAssetPath() const
{
return m_assetPath;
}
//////////////////
// PivotTreeRoot
//////////////////
void PivotTreeRoot::SwitchDataSource(const LoggingDataId& aggregateDataSource)
{
SetLoggingDataId(aggregateDataSource);
OnDataSourceChanged(aggregateDataSource);
}
Qt::CheckState PivotTreeRoot::GetCheckState() const
{
return Qt::CheckState::Unchecked;
}
void PivotTreeRoot::SetCheckState(Qt::CheckState checkState)
{
AZ_UNUSED(checkState);
}
AZStd::string PivotTreeRoot::GetDisplayName() const
{
return "";
}
////////////////////////////
// PivotTreeSortProxyModel
////////////////////////////
bool PivotTreeSortProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
if (m_filter.isEmpty())
{
return true;
}
QAbstractItemModel* model = sourceModel();
QModelIndex index = model->index(sourceRow, PivotTreeItem::Column::Name, sourceParent);
PivotTreeItem* basePivotTreeItem = static_cast<PivotTreeItem*>(index.internalPointer());
QString test = model->data(index, Qt::DisplayRole).toString();
bool showRow = test.lastIndexOf(m_filterRegex) >= 0;
// Handle showing ourselves if a child is being displayed
if (!showRow && sourceModel()->hasChildren(index))
{
for (int i = 0; i < sourceModel()->rowCount(index); ++i)
{
if (filterAcceptsRow(i, index))
{
showRow = true;
break;
}
}
}
// We also want to display ourselves if any of our parents match the filter
QModelIndex parentIndex = sourceModel()->parent(index);
while (!showRow && parentIndex.isValid())
{
QString test2 = model->data(parentIndex).toString();
showRow = test2.contains(m_filterRegex);
parentIndex = sourceModel()->parent(parentIndex);
}
return showRow;
}
bool PivotTreeSortProxyModel::HasFilter() const
{
return !m_filter.isEmpty();
}
void PivotTreeSortProxyModel::SetFilter(const QString& filter)
{
m_filter = filter;
m_filterRegex = QRegExp(m_filter, Qt::CaseInsensitive);
invalidateFilter();
}
void PivotTreeSortProxyModel::ClearFilter()
{
if (HasFilter())
{
SetFilter("");
}
}
////////////////////
// PivotTreeWidget
////////////////////
PivotTreeWidget::PivotTreeWidget(PivotTreeRoot* pivotRoot, const AZ::Crc32& savingId, QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::PivotTreeWidget())
{
m_ui->setupUi(this);
m_pivotRoot = pivotRoot;
m_treeModel = aznew GraphCanvas::GraphCanvasTreeModel(pivotRoot);
m_proxyModel = aznew PivotTreeSortProxyModel();
m_proxyModel->ClearFilter();
m_proxyModel->setSourceModel(m_treeModel);
m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
m_ui->pivotTreeView->setModel(m_proxyModel);
m_ui->pivotTreeView->sortByColumn(PivotTreeItem::Column::Name, Qt::SortOrder::AscendingOrder);
m_ui->pivotTreeView->header()->setHidden(true);
m_ui->pivotTreeView->header()->setStretchLastSection(false);
m_ui->pivotTreeView->header()->setSectionResizeMode(PivotTreeItem::Column::Name, QHeaderView::ResizeMode::Stretch);
m_ui->pivotTreeView->header()->setSectionResizeMode(PivotTreeItem::Column::QT_NEEDS_A_SECOND_COLUMN_FOR_THIS_MODEL_TO_WORK_FOR_SOME_REASON, QHeaderView::ResizeMode::Fixed);
m_ui->pivotTreeView->header()->resizeSection(PivotTreeItem::Column::QT_NEEDS_A_SECOND_COLUMN_FOR_THIS_MODEL_TO_WORK_FOR_SOME_REASON, 1);
QObject::connect(m_ui->filterWidget, &AzQtComponents::FilteredSearchWidget::TextFilterChanged, this, &PivotTreeWidget::OnFilterChanged);
m_ui->filterWidget->SetFilterInputInterval(AZStd::chrono::milliseconds(250));
m_ui->pivotTreeView->InitializeTreeViewSaving(savingId);
m_ui->pivotTreeView->PauseTreeViewSaving();
QObject::connect(m_ui->pivotTreeView, &QTreeView::doubleClicked, this, &PivotTreeWidget::OnItemDoubleClicked);
}
PivotTreeWidget::~PivotTreeWidget()
{
}
void PivotTreeWidget::DisplayTree()
{
OnTreeDisplayed();
}
void PivotTreeWidget::SwitchDataSource(const LoggingDataId& aggregateDataSource)
{
{
QSignalBlocker signalBlocker(m_ui->filterWidget);
m_ui->filterWidget->ClearTextFilter();
OnFilterChanged("");
}
m_pivotRoot->SwitchDataSource(aggregateDataSource);
}
void PivotTreeWidget::OnFilterChanged(const QString& activeTextFilter)
{
bool hadFilter = m_proxyModel->HasFilter();
if (!m_proxyModel->HasFilter() && !activeTextFilter.isEmpty())
{
m_ui->pivotTreeView->UnpauseTreeViewSaving();
m_ui->pivotTreeView->CaptureTreeViewSnapshot();
m_ui->pivotTreeView->PauseTreeViewSaving();
}
m_proxyModel->SetFilter(activeTextFilter);
if (hadFilter && !m_proxyModel->HasFilter())
{
m_ui->pivotTreeView->UnpauseTreeViewSaving();
m_ui->pivotTreeView->ApplyTreeViewSnapshot();
m_ui->pivotTreeView->PauseTreeViewSaving();
}
else if (m_proxyModel->HasFilter())
{
m_ui->pivotTreeView->expandAll();
}
}
PivotTreeRoot* PivotTreeWidget::GetTreeRoot()
{
return m_pivotRoot;
}
void PivotTreeWidget::OnTreeDisplayed()
{
}
void PivotTreeWidget::OnItemDoubleClicked(const QModelIndex& modelIndex)
{
QModelIndex sourceIndex = modelIndex;
QSortFilterProxyModel* proxyModel = qobject_cast<QSortFilterProxyModel*>(m_ui->pivotTreeView->model());
if (proxyModel)
{
sourceIndex = proxyModel->mapToSource(modelIndex);
}
PivotTreeItem* pivotTreeItem = static_cast<PivotTreeItem*>(sourceIndex.internalPointer());
if (pivotTreeItem)
{
PivotTreeGraphItem* graphItem = azrtti_cast<PivotTreeGraphItem*>(pivotTreeItem);
if (graphItem)
{
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, graphItem->GetAssetId());
}
}
}
#include <Editor/View/Widgets/LoggingPanel/PivotTree/moc_PivotTreeWidget.cpp>
}
@@ -0,0 +1,208 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/PlatformDef.h>
// qbrush.h(118): warning C4251: 'QBrush::d': class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
// qwidget.h(858): warning C4800: 'uint': forcing value to bool 'true' or 'false' (performance warning)
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <QTimer>
#include <QTreeView>
#include <QSortFilterProxyModel>
AZ_POP_DISABLE_WARNING
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <GraphCanvas/Widgets/GraphCanvasTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasTreeModel.h>
#include <Editor/View/Widgets/LoggingPanel/LoggingWindowSession.h>
#endif
namespace Ui
{
class PivotTreeWidget;
}
namespace ScriptCanvasEditor
{
class PivotTreeItem
: public GraphCanvas::GraphCanvasTreeItem
{
public:
AZ_CLASS_ALLOCATOR(PivotTreeItem, AZ::SystemAllocator, 0);
AZ_RTTI(PivotTreeItem, "{F310C0EA-9CFE-4A8F-9CDA-46E24673B01A}", GraphCanvas::GraphCanvasTreeItem);
enum Column
{
IndexForce = -1,
Name,
// Seriously. Returning 1 causes the data to only ask for the tool tip.
// No idea why.
QT_NEEDS_A_SECOND_COLUMN_FOR_THIS_MODEL_TO_WORK_FOR_SOME_REASON,
Count
};
PivotTreeItem();
~PivotTreeItem();
const LoggingDataId& GetLoggingDataId() const;
// GraphCanvasTreeItem
int GetColumnCount() const override final;
Qt::ItemFlags Flags(const QModelIndex& index) const override final;
QVariant Data(const QModelIndex& index, int role) const override final;
bool SetData(const QModelIndex& index, const QVariant& value, int role) override final;
void OnChildAdded(GraphCanvasTreeItem* treeItem) override final;
////
virtual Qt::CheckState GetCheckState() const = 0;
virtual void SetCheckState(Qt::CheckState checkState) = 0;
protected:
virtual AZStd::string GetDisplayName() const = 0;
virtual void OnLoggingDataIdSet();
void SetLoggingDataId(const LoggingDataId& dataId);
void SetIsPivotedElement(bool isPivotedElement);
private:
bool m_isPivotElement;
LoggingDataId m_loggingDataId;
};
class PivotTreeEntityItem
: public PivotTreeItem
{
public:
AZ_CLASS_ALLOCATOR(PivotTreeEntityItem, AZ::SystemAllocator, 0);
AZ_RTTI(PivotTreeEntityItem, "{67725865-7004-441D-84BB-D38FF491A3FD}", PivotTreeItem);
PivotTreeEntityItem(const AZ::NamedEntityId& entityId);
const AZ::NamedEntityId& GetNamedEntityId() const;
protected:
AZStd::string GetDisplayName() const override final;
const AZ::EntityId& GetEntityId() const;
private:
AZ::NamedEntityId m_namedEntityId;
};
class PivotTreeGraphItem
: public PivotTreeItem
{
public:
AZ_CLASS_ALLOCATOR(PivotTreeGraphItem, AZ::SystemAllocator, 0);
AZ_RTTI(PivotTreeGraphItem, "{37FCAC77-DE32-4B1B-97FD-66852EC31CAB}", PivotTreeItem);
PivotTreeGraphItem(const AZ::Data::AssetId& assetId);
const AZ::Data::AssetId& GetAssetId() const;
protected:
AZStd::string GetDisplayName() const override final;
AZStd::string_view GetAssetPath() const;
private:
AZ::Data::AssetId m_assetId;
AZStd::string m_assetPath;
AZStd::string m_assetName;
};
class PivotTreeRoot
: public PivotTreeItem
{
public:
AZ_CLASS_ALLOCATOR(PivotTreeRoot, AZ::SystemAllocator, 0);
AZ_RTTI(PivotTreeRoot, "{E172AB89-49BA-429F-AC83-9CCBD6A3B1B9}", PivotTreeItem);
PivotTreeRoot() = default;
void SwitchDataSource(const LoggingDataId& aggregateDataSource);
protected:
Qt::CheckState GetCheckState() const override final;
void SetCheckState(Qt::CheckState checkState) override final;
AZStd::string GetDisplayName() const override final;
virtual void OnDataSourceChanged(const LoggingDataId& aggregateDataSource) = 0;
private:
LoggingDataId m_loggingDataId;
};
class PivotTreeSortProxyModel
: public QSortFilterProxyModel
{
public:
AZ_CLASS_ALLOCATOR(PivotTreeSortProxyModel, AZ::SystemAllocator, 0);
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
bool HasFilter() const;
void SetFilter(const QString& filter);
void ClearFilter();
private:
QString m_filter;
QRegExp m_filterRegex;
};
class PivotTreeWidget
: public QWidget
{
Q_OBJECT
public:
~PivotTreeWidget();
void DisplayTree();
void SwitchDataSource(const LoggingDataId& aggregateDataSource);
public Q_SLOT:
void OnFilterChanged(const QString& activeTextFilter);
protected:
PivotTreeWidget(PivotTreeRoot* pivotRoot, const AZ::Crc32& savingId, QWidget* parent);
PivotTreeRoot* GetTreeRoot();
virtual void OnTreeDisplayed();
private:
void OnItemDoubleClicked(const QModelIndex& modelIndex);
AZStd::unique_ptr<Ui::PivotTreeWidget> m_ui;
PivotTreeRoot* m_pivotRoot;
GraphCanvas::GraphCanvasTreeModel* m_treeModel;
PivotTreeSortProxyModel* m_proxyModel;
};
}
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PivotTreeWidget</class>
<widget class="QWidget" name="PivotTreeWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>372</width>
<height>476</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="AzQtComponents::FilteredSearchWidget" name="filterWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="AzToolsFramework::QTreeViewWithStateSaving" name="pivotTreeView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>AzQtComponents::FilteredSearchWidget</class>
<extends>QWidget</extends>
<header location="global">AzQtComponents/Components/FilteredSearchWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AzToolsFramework::QTreeViewWithStateSaving</class>
<extends>QTreeView</extends>
<header location="global">AzToolsFramework/UI/UICore/QTreeViewStateSaver.hxx</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>