| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /*
- * 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 <QScrollBar>
- #include <QGraphicsItem>
- #include <QScopedValueRollback>
- #include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
- #include <GraphCanvas/Components/SceneBus.h>
- #include <GraphCanvas/Components/Slots/SlotBus.h>
- #include <GraphCanvas/Components/VisualBus.h>
- #include <GraphCanvas/Widgets/StyledItemDelegates/IconDecoratedNameDelegate.h>
- #include <GraphCanvas/Utils/GraphUtils.h>
- #include <Editor/View/Widgets/AssetGraphSceneDataBus.h>
- #include <Editor/View/Widgets/LoggingPanel/LoggingWindowSession.h>
- #include <ScriptCanvas/Bus/RequestBus.h>
- #include <ScriptCanvas/GraphCanvas/MappingBus.h>
- #include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
- namespace ScriptCanvasEditor
- {
- /////////////////////////////
- // LoggingWindowFilterModel
- /////////////////////////////
- bool LoggingWindowFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
- {
- if (m_logFilter.IsEmpty())
- {
- return true;
- }
- QAbstractItemModel* model = sourceModel();
- QModelIndex index = model->index(sourceRow, 0, sourceParent);
- DebugLogTreeItem* treeItem = static_cast<DebugLogTreeItem*>(index.internalPointer());
- if (treeItem)
- {
- return treeItem->MatchesFilter(m_logFilter);
- }
- return false;
- }
- void LoggingWindowFilterModel::SetFilter(const QString& filter)
- {
- m_filter = filter;
- m_logFilter.m_filter = QRegExp(m_filter, Qt::CaseInsensitive);
- invalidateFilter();
- }
- void LoggingWindowFilterModel::ClearFilter()
- {
- SetFilter("");
- }
- bool LoggingWindowFilterModel::HasFilter() const
- {
- return !m_filter.isEmpty();
- }
- /////////////////////////
- // LoggingWindowSession
- /////////////////////////
- LoggingWindowSession::LoggingWindowSession(QWidget* parentWidget)
- : QWidget(parentWidget)
- , m_ui(new Ui::LoggingWindowSession())
- , m_clearSelectionOnSceneSelectionChange(true)
- , m_scrollToBottom(true)
- , m_debugRoot(nullptr)
- , m_treeModel(nullptr)
- , m_filterModel(nullptr)
- {
- m_ui->setupUi(this);
- QObject::connect(m_ui->captureButton, &QToolButton::clicked, this, &LoggingWindowSession::OnCaptureButtonPressed);
- QObject::connect(m_ui->expandAll, &QToolButton::clicked, this, &LoggingWindowSession::OnExpandAll);
- QObject::connect(m_ui->collapseAll, &QToolButton::clicked, this, &LoggingWindowSession::OnCollapseAll);
- QObject::connect(m_ui->targetSelector, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LoggingWindowSession::OnTargetChanged);
- QObject::connect(m_ui->logTree->verticalScrollBar(), &QScrollBar::valueChanged, this, &LoggingWindowSession::OnLogScrolled);
- QObject::connect(m_ui->logTree, &QTreeView::expanded, this, &LoggingWindowSession::OnLogItemExpanded);
- QObject::connect(m_ui->logTree->verticalScrollBar(), &QScrollBar::rangeChanged, this, &LoggingWindowSession::OnLogRangeChanged);
- QObject::connect(m_ui->filterWidget, &AzQtComponents::FilteredSearchWidget::TextFilterChanged, this, &LoggingWindowSession::OnSearchFilterChanged);
- m_ui->filterWidget->SetFilterInputInterval(AZStd::chrono::milliseconds(250));
-
- m_ui->logTree->setMouseTracking(true);
- QObject::connect(m_ui->logTree, &QTreeView::clicked, this, &LoggingWindowSession::OnLogClicked);
- QObject::connect(m_ui->logTree, &QTreeView::doubleClicked, this, &LoggingWindowSession::OnLogDoubleClicked);
- m_focusDelayTimer.setInterval(125);
- m_focusDelayTimer.setSingleShot(true);
- QObject::connect(&m_focusDelayTimer, &QTimer::timeout, this, &LoggingWindowSession::HandleQueuedFocus);
- GraphCanvas::AssetEditorNotificationBus::Handler::BusConnect(ScriptCanvasEditor::AssetEditorId);
- AZ::EntityId graphCanvasId;
- GeneralRequestBus::BroadcastResult(graphCanvasId, &GeneralRequests::GetActiveGraphCanvasGraphId);
- OnActiveGraphChanged(graphCanvasId);
- }
- LoggingWindowSession::~LoggingWindowSession()
- {
- }
- const LoggingDataId& LoggingWindowSession::GetDataId() const
- {
- return m_loggingDataId;
- }
- void LoggingWindowSession::ClearFilter()
- {
- m_ui->filterWidget->ClearTextFilter();
- }
- void LoggingWindowSession::OnActiveGraphChanged(const AZ::EntityId& graphId)
- {
- ClearLoggingSelection();
- if (GraphCanvas::SceneNotificationBus::Handler::BusIsConnected())
- {
- GraphCanvas::SceneNotificationBus::Handler::BusDisconnect();
- }
- if (graphId.IsValid())
- {
- GraphCanvas::SceneNotificationBus::Handler::BusConnect(graphId);
- }
- }
- void LoggingWindowSession::OnSelectionChanged()
- {
- ClearLoggingSelection();
- }
- void LoggingWindowSession::RegisterTreeRoot(DebugLogRootItem* debugRoot)
- {
- m_debugRoot = debugRoot;
- m_treeModel = aznew GraphCanvas::GraphCanvasTreeModel(debugRoot, this);
- m_filterModel = aznew LoggingWindowFilterModel();
- m_filterModel->setSourceModel(m_treeModel);
- m_ui->logTree->setModel(m_filterModel);
- m_ui->logTree->header()->setStretchLastSection(false);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::NodeName, QHeaderView::ResizeMode::Stretch);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::Input, QHeaderView::ResizeMode::Stretch);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::Output, QHeaderView::ResizeMode::Stretch);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::TimeStep, QHeaderView::ResizeMode::Fixed);
- m_ui->logTree->header()->resizeSection(DebugLogTreeItem::Column::TimeStep, 75);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::ScriptName, QHeaderView::ResizeMode::Fixed);
- m_ui->logTree->header()->resizeSection(DebugLogTreeItem::Column::ScriptName, 150);
- m_ui->logTree->header()->setSectionResizeMode(DebugLogTreeItem::Column::SourceEntity, QHeaderView::ResizeMode::Fixed);
- m_ui->logTree->header()->resizeSection(DebugLogTreeItem::Column::SourceEntity, 200);
- m_ui->logTree->setItemDelegateForColumn(DebugLogTreeItem::Column::NodeName, aznew GraphCanvas::IconDecoratedNameDelegate(this));
- QObject::connect(m_ui->logTree->selectionModel(), &QItemSelectionModel::selectionChanged, this, &LoggingWindowSession::OnLogSelectionChanged);
- }
- void LoggingWindowSession::SetDataId(const LoggingDataId& loggingDataId)
- {
- if (!m_loggingDataId.IsValid())
- {
- m_loggingDataId = loggingDataId;
- }
- }
- void LoggingWindowSession::OnExpandAll()
- {
- m_ui->logTree->expandAll();
- ScrollToSelection();
- }
- void LoggingWindowSession::OnCollapseAll()
- {
- m_ui->logTree->collapseAll();
- ScrollToSelection();
- }
- void LoggingWindowSession::OnSearchFilterChanged(const QString& filterString)
- {
- m_filterModel->SetFilter(filterString);
- }
- void LoggingWindowSession::OnLogScrolled(int value)
- {
- if (m_ui->logTree->verticalScrollBar()->isEnabled())
- {
- if (m_ui->logTree->verticalScrollBar()->maximum() == value)
- {
- m_scrollToBottom = true;
- }
- else
- {
- m_scrollToBottom = false;
- }
- }
- else
- {
- m_scrollToBottom = true;
- }
- }
- void LoggingWindowSession::OnLogItemExpanded([[maybe_unused]] const QModelIndex& modelIndex)
- {
- m_scrollToBottom = false;
- }
- void LoggingWindowSession::OnLogRangeChanged([[maybe_unused]] int min, int max)
- {
- if (m_scrollToBottom)
- {
- m_ui->logTree->verticalScrollBar()->setValue(max);
- }
- if (!m_ui->logTree->verticalScrollBar()->isEnabled())
- {
- m_scrollToBottom = true;
- }
- }
- void LoggingWindowSession::OnLogClicked(const QModelIndex& modelIndex)
- {
- if (modelIndex.column() == DebugLogTreeItem::Column::ScriptName)
- {
- QModelIndex sourceIndex = m_filterModel->mapToSource(modelIndex);
- DebugLogTreeItem* treeItem = static_cast<DebugLogTreeItem*>(sourceIndex.internalPointer());
- if (ExecutionLogTreeItem* executionItem = azrtti_cast<ExecutionLogTreeItem*>(treeItem))
- {
- QScopedValueRollback<bool> valueRollback(m_clearSelectionOnSceneSelectionChange, false);
- const AZ::Data::AssetId& assetId = executionItem->GetAssetId();
-
- GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId
- , SourceHandle(nullptr, assetId.m_guid), Tracker::ScriptCanvasFileState::UNMODIFIED);
- }
- }
- }
- void LoggingWindowSession::OnLogDoubleClicked(const QModelIndex& modelIndex)
- {
- ExecutionLogTreeItem* executionItem = ResolveExecutionItem(modelIndex);
- if (executionItem)
- {
- const AZ::Data::AssetId& assetId = executionItem->GetAssetId();
- bool isAssetOpen = false;
- GeneralRequestBus::BroadcastResult(isAssetOpen, &GeneralRequests::IsScriptCanvasAssetOpen, SourceHandle(nullptr, assetId.m_guid));
- GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId
- , SourceHandle(nullptr, assetId.m_guid), Tracker::ScriptCanvasFileState::UNMODIFIED);
- AZ::EntityId graphCanvasGraphId;
- GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId
- , SourceHandle(nullptr, assetId.m_guid));
-
- if (isAssetOpen)
- {
- FocusOnElement(assetId, executionItem->GetScriptCanvasAssetNodeId());
- }
- else
- {
- m_assetId = assetId;
- m_assetNodeId = executionItem->GetScriptCanvasAssetNodeId();
- m_focusDelayTimer.stop();
- m_focusDelayTimer.start();
- }
- }
- }
- void LoggingWindowSession::OnLogSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
- {
- for (const QModelIndex& deselectedIndex : deselected.indexes())
- {
- if (deselectedIndex.column() != 0)
- {
- continue;
- }
- ExecutionLogTreeItem* executionItem = ResolveExecutionItem(deselectedIndex);
- if (executionItem)
- {
- RemoveHighlight(executionItem->GetAssetId(), executionItem->GetScriptCanvasAssetNodeId());
- }
- }
- for (const QModelIndex& selectedIndex : selected.indexes())
- {
- if (selectedIndex.column() != 0)
- {
- continue;
- }
- ExecutionLogTreeItem* executionItem = ResolveExecutionItem(selectedIndex);
- if (executionItem)
- {
- HighlightElement(executionItem->GetAssetId(), executionItem->GetScriptCanvasAssetNodeId());
- }
- }
- }
- ExecutionLogTreeItem* LoggingWindowSession::ResolveExecutionItem(const QModelIndex& proxyModelIndex)
- {
- QModelIndex sourceIndex = m_filterModel->mapToSource(proxyModelIndex);
- DebugLogTreeItem* treeItem = static_cast<DebugLogTreeItem*>(sourceIndex.internalPointer());
- DebugLogTreeItem* parentItem = static_cast<DebugLogTreeItem*>(treeItem->GetParent());
- ExecutionLogTreeItem* executionItem = azrtti_cast<ExecutionLogTreeItem*>(treeItem);
- while (executionItem == nullptr && parentItem != nullptr)
- {
- executionItem = azrtti_cast<ExecutionLogTreeItem*>(parentItem);
- parentItem = static_cast<DebugLogTreeItem*>(parentItem->GetParent());
- }
- return executionItem;
- }
- void LoggingWindowSession::HandleQueuedFocus()
- {
- AZ::EntityId activeGraphCanvasGraphId;
- GeneralRequestBus::BroadcastResult(activeGraphCanvasGraphId, &GeneralRequests::GetActiveGraphCanvasGraphId);
- AZ::EntityId graphCanvasGraphId;
- GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, m_assetId.m_guid));
- if (activeGraphCanvasGraphId == graphCanvasGraphId)
- {
- FocusOnElement(m_assetId, m_assetNodeId);
-
- m_focusDelayTimer.stop();
- m_assetId.SetInvalid();
- m_assetNodeId.SetInvalid();
- }
- }
- void LoggingWindowSession::FocusOnElement(const AZ::Data::AssetId& assetId, const AZ::EntityId& assetNodeId)
- {
- GraphCanvas::FocusConfig focusConfig;
- AZ::EntityId scriptCanvasNodeId;
- AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, SourceHandle(nullptr, assetId.m_guid), assetNodeId);
- GraphCanvas::NodeId graphCanvasNodeId;
- SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
- if (GraphCanvas::GraphUtils::IsNodeGroup(graphCanvasNodeId))
- {
- focusConfig.m_spacingType = GraphCanvas::FocusConfig::SpacingType::GridStep;
- focusConfig.m_spacingAmount = 1;
- }
- else
- {
- focusConfig.m_spacingType = GraphCanvas::FocusConfig::SpacingType::Scalar;
- focusConfig.m_spacingAmount = 2;
- }
- AZStd::vector< AZ::EntityId > memberIds = { graphCanvasNodeId };
- GraphCanvas::GraphUtils::FocusOnElements(memberIds, focusConfig);
- {
- QScopedValueRollback<bool> maintainSelection(m_clearSelectionOnSceneSelectionChange, false);
- RemoveHighlight(assetId, assetNodeId);
- GraphCanvas::GraphId graphId;
- GraphCanvas::SceneMemberRequestBus::EventResult(graphId, graphCanvasNodeId, &GraphCanvas::SceneMemberRequests::GetScene);
- GraphCanvas::SceneRequestBus::Event(graphId, &GraphCanvas::SceneRequests::ClearSelection);
- GraphCanvas::SceneMemberUIRequestBus::Event(graphCanvasNodeId, &GraphCanvas::SceneMemberUIRequests::SetSelected, true);
- }
- }
- void LoggingWindowSession::HighlightElement(const AZ::Data::AssetId& assetId, const AZ::EntityId& assetNodeId)
- {
- AZ::EntityId graphCanvasGraphId;
- GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, assetId.m_guid));
- if (graphCanvasGraphId.IsValid())
- {
- AZ::EntityId scriptCanvasNodeId;
- AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, SourceHandle(nullptr, assetId.m_guid), assetNodeId);
- GraphCanvas::NodeId graphCanvasNodeId;
- SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
- GraphCanvas::SceneMemberGlowOutlineConfiguration glowConfiguration;
- glowConfiguration.m_sceneMember = graphCanvasNodeId;
- glowConfiguration.m_blurRadius = 0; // #17174 using blur degrades performance
- glowConfiguration.m_pen = QPen();
- glowConfiguration.m_pen.setBrush(QColor(243, 129, 29));
- glowConfiguration.m_pen.setWidth(5);
- glowConfiguration.m_pulseRate = AZStd::chrono::milliseconds(2500);
- glowConfiguration.m_zValue = 0;
- GraphCanvas::GraphicsEffectId effectId;
- GraphCanvas::SceneRequestBus::EventResult(effectId, graphCanvasGraphId, &GraphCanvas::SceneRequests::CreateGlowOnSceneMember, glowConfiguration);
- auto effectIter = m_highlightEffects.find(assetNodeId);
- if (effectIter != m_highlightEffects.end())
- {
- GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::CancelGraphicsEffect, effectIter->second);
- }
- m_highlightEffects[assetNodeId] = effectId;
- }
- }
- void LoggingWindowSession::RemoveHighlight(const AZ::Data::AssetId& assetId, const AZ::EntityId& assetNodeId)
- {
- auto effectIter = m_highlightEffects.find(assetNodeId);
- if (effectIter != m_highlightEffects.end())
- {
- AZ::EntityId graphCanvasGraphId;
- GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, assetId.m_guid));
- if (graphCanvasGraphId.IsValid())
- {
- GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::CancelGraphicsEffect, effectIter->second);
- }
- m_highlightEffects.erase(effectIter);
- }
- }
- void LoggingWindowSession::ScrollToSelection()
- {
- for (auto selectedIndex : m_ui->logTree->selectionModel()->selectedIndexes())
- {
- m_ui->logTree->scrollTo(selectedIndex);
- }
- }
- void LoggingWindowSession::ClearLoggingSelection()
- {
- if (m_clearSelectionOnSceneSelectionChange)
- {
- m_ui->logTree->clearSelection();
- }
- }
- #include <Editor/View/Widgets/LoggingPanel/moc_LoggingWindowSession.cpp>
- }
|