Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
@@ -711,7 +711,7 @@ namespace ScriptCanvasEditor
AZStd::string tempFilename;
AzFramework::StringFunc::Path::GetFullFileName(targetFilename.data(), tempFilename);
AZStd::string tempPath = AZStd::string::format("@cache@/scriptcanvas/%s.temp", tempFilename.data());
AZStd::string tempPath = AZStd::string::format("@usercache@/scriptcanvas/%s.temp", tempFilename.data());
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
AZ::IO::FileIOBase::GetInstance()->ResolvePath(tempPath.data(), resolvedPath.data(), resolvedPath.size());
@@ -584,6 +584,74 @@ namespace ScriptCanvasEditor
return true;
}
void Graph::HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId)
{
// Special-case for the execution nodeling extensions, which are adding input/output data slots.
// We want to automatically promote them to variables so that the user can refer to them more easily
auto functionDefintionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(node);
if (functionDefintionNode && graphCanvasSlotId.IsValid())
{
GraphCanvas::Endpoint endpoint;
GraphCanvas::SlotRequestBus::EventResult(endpoint, graphCanvasSlotId, &GraphCanvas::SlotRequests::GetEndpoint);
const ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint);
if (scEndpoint.IsValid())
{
ScriptCanvas::Slot* slot = FindSlot(scEndpoint);
if (slot)
{
AZ::Vector2 position;
GraphCanvas::GeometryRequestBus::EventResult(position, nodeId, &GraphCanvas::GeometryRequests::GetPosition);
// First we need to automatically display the ShowSlotTypeSelector dialog so the user
// can assign a type and name to the slot they are adding
VariablePaletteRequests::SlotSetup selectedSlotSetup;
bool createSlot = false;
QPoint scenePoint(aznumeric_cast<int>(position.GetX()), aznumeric_cast<int>(position.GetY()));
VariablePaletteRequestBus::BroadcastResult(createSlot, &VariablePaletteRequests::ShowSlotTypeSelector, slot, scenePoint, selectedSlotSetup);
if (createSlot && !selectedSlotSetup.m_type.IsNull())
{
if (slot)
{
auto displayType = ScriptCanvas::Data::FromAZType(selectedSlotSetup.m_type);
if (displayType.IsValid())
{
slot->SetDisplayType(displayType);
}
if (!selectedSlotSetup.m_name.empty())
{
slot->Rename(selectedSlotSetup.m_name);
}
}
// Now that the slot has a valid type/name, we can actually promote it to a variable
if (PromoteToVariableAction(endpoint) /*&& slot->IsVariableReference()*/)
{
ScriptCanvas::GraphVariable* variable = slot->GetVariable();
if (variable)
{
// functions 2.0 set variable scope to function
auto connectionType = slot->GetConnectionType();
if (variable->GetScope() != ScriptCanvas::VariableFlags::Scope::Function)
{
variable->SetScope(ScriptCanvas::VariableFlags::Scope::Function);
}
}
}
}
else
{
RemoveSlot(endpoint);
}
}
}
}
}
AZ::Outcome<ScriptCanvas::Node*> Graph::ReplaceNodeByConfig(ScriptCanvas::Node* oldNode, const ScriptCanvas::NodeConfiguration& nodeConfig,
ScriptCanvas::ReplacementConnectionMap& remapConnections)
{
@@ -917,17 +985,6 @@ namespace ScriptCanvasEditor
if (remapVariableOutcome)
{
node->SetSlotVariableId(slot.GetId(), remapVariableOutcome.GetValue());
ScriptCanvas::GraphVariable* variable2 = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(variable2, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, remapVariableOutcome.GetValue());
if (variable2)
{
if (IsRuntimeGraph())
{
variable2->RemoveScope(ScriptCanvas::VariableFlags::Scope::Output);
}
}
}
else
{
@@ -979,7 +1036,10 @@ namespace ScriptCanvasEditor
ScriptCanvas::Endpoint scTargetEndpoint = connection->GetTargetEndpoint();
GraphCanvas::Endpoint targetEndpoint = ConvertToGraphCanvasEndpoint(scTargetEndpoint);
ScriptCanvas::GraphNotificationBus::Event(GetScriptCanvasId(), &ScriptCanvas::GraphNotifications::OnDisonnectionComplete, connectionId);
DisconnectById(scConnectionId);
}
}
@@ -1003,6 +1063,12 @@ namespace ScriptCanvasEditor
scConnected = ConfigureConnectionUserData(scSourceEndpoint, scTargetEndpoint, connectionId);
}
if (scConnected)
{
ScriptCanvas::GraphNotificationBus::Event(GetScriptCanvasId(), &ScriptCanvas::GraphNotifications::OnConnectionComplete, connectionId);
}
return scConnected;
}
@@ -1777,38 +1843,21 @@ namespace ScriptCanvasEditor
if (isExecutionNodeling)
{
if (!IsFunctionGraph())
{
invalidNodes.insert(nodeId);
}
else
{
AZStd::any* userData = nullptr;
GraphCanvas::NodeRequestBus::EventResult(userData, nodeId, &GraphCanvas::NodeRequests::GetUserData);
AZ::EntityId scSourceNodeId = (userData && userData->is<AZ::EntityId>()) ? *AZStd::any_cast<AZ::EntityId>(userData) : AZ::EntityId();
AZStd::any* userData = nullptr;
GraphCanvas::NodeRequestBus::EventResult(userData, nodeId, &GraphCanvas::NodeRequests::GetUserData);
AZ::EntityId scSourceNodeId = (userData && userData->is<AZ::EntityId>()) ? *AZStd::any_cast<AZ::EntityId>(userData) : AZ::EntityId();
ScriptCanvas::Nodes::Core::FunctionDefinitionNode* nodeling = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(FindNode(scSourceNodeId));
if (nodeling)
{
nodeling->RemapId();
}
if (nodeling)
{
nodeling->RemapId();
}
}
// Going to disallow all functions nodes inside of functions nodes until we sort out a dependency checking situation to avoid recursion.
bool isFunctionNode = false;
NodeDescriptorRequestBus::EventResult(isFunctionNode, nodeId, &NodeDescriptorRequests::IsType, NodeDescriptorType::FunctionNode);
if (isFunctionNode)
{
if (IsFunctionGraph())
{
invalidNodes.insert(nodeId);
}
}
// Show all hidden slots on a paste, as a temporary fix until I can sort out what I want this to work like.
GraphCanvas::NodeRequestBus::Event(nodeId, &GraphCanvas::NodeRequests::ShowAllSlots);
@@ -2021,6 +2070,21 @@ namespace ScriptCanvasEditor
{
ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint);
ScriptCanvas::Slot* slot = FindSlot(scEndpoint);
if (slot)
{
ScriptCanvas::GraphVariable* variable = slot->GetVariable();
if (variable && variable->GetScope() == ScriptCanvas::VariableFlags::Scope::Function)
{
bool success = false;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(success, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::RemoveVariable, variable->GetVariableId());
if (!success)
{
AZ_Assert(success, "Failed to remove variable that corresponds to this slot");
}
}
}
ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId());
if (canvasNode)
@@ -2198,36 +2262,18 @@ namespace ScriptCanvasEditor
AZStd::string inBoxText = "";
while (!nameAvailable)
// Special case to try re-using the slot name if this is on an execution nodeling, since the user had just
// given it a name already with the ShowSlotTypeSelector dialog
if (azrtti_istypeof<ScriptCanvas::Nodes::Core::FunctionDefinitionNode>(activeNode))
{
bool accepted = false;
QString name = QInputDialog::getText(mainWindow, "Variable Name", inBoxText.c_str(), QLineEdit::Normal, defaultName.c_str(), &accepted);
if (!accepted)
{
break;
}
if (!name.isEmpty())
{
variableName = name.toUtf8().data();
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(nameAvailable, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::IsNameAvailable, variableName);
if (!nameAvailable)
{
inBoxText = AZStd::string::format("\"%s\" is already in use.", variableName.c_str());
}
}
else
{
inBoxText = "Variable names cannot be empty.";
}
variableName = activeSlot->GetName();
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(nameAvailable, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::IsNameAvailable, variableName);
}
if (!nameAvailable)
while (!nameAvailable)
{
ReleaseVariableCounter(variableCounter);
return false;
variableName.append(" (duplicate)");
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(nameAvailable, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::IsNameAvailable, variableName);
}
ScriptCanvas::Datum variableDatum;
@@ -2250,16 +2296,15 @@ namespace ScriptCanvasEditor
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> addOutcome;
// #functions2 slot<->variable re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion)
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum);
if (addOutcome.IsSuccess())
{
GraphCanvas::DataSlotRequestBus::Event(endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference);
if (activeSlot->IsVariableReference())
{
activeSlot->SetVariableReference(addOutcome.GetValue());
}
activeSlot->SetVariableReference(addOutcome.GetValue());
}
return addOutcome.IsSuccess();
@@ -2348,7 +2393,7 @@ namespace ScriptCanvasEditor
return false;
}
GraphCanvas::SlotId Graph::RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId)
GraphCanvas::SlotId Graph::RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId, GraphModelRequests::ExtensionRequestReason reason)
{
GraphCanvas::SlotId graphCanvasSlotId;
@@ -2363,8 +2408,20 @@ namespace ScriptCanvasEditor
ScriptCanvas::Node* canvasNode = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Node>(graphNodeEntity);
if (canvasNode)
{
ScriptCanvas::SlotId slotId = canvasNode->HandleExtension(extenderId);
SlotMappingRequestBus::EventResult(graphCanvasSlotId, nodeId, &SlotMappingRequests::MapToGraphCanvasId, slotId);
auto functionDefintionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(canvasNode);
if (functionDefintionNode && reason == GraphModelRequests::ExtensionRequestReason::ConnectionProposal)
{
}
else
{
ScriptCanvas::SlotId slotId = canvasNode->HandleExtension(extenderId);
if (slotId.IsValid())
{
SlotMappingRequestBus::EventResult(graphCanvasSlotId, nodeId, &SlotMappingRequests::MapToGraphCanvasId, slotId);
HandleFunctionDefinitionExtension(canvasNode, graphCanvasSlotId, nodeId);
}
}
}
}
@@ -3126,7 +3183,7 @@ namespace ScriptCanvasEditor
bool Graph::CanExposeEndpoint(const GraphCanvas::Endpoint& endpoint)
{
bool isEnabled = IsFunctionGraph();
bool isEnabled = false;
GraphCanvas::SlotType slotType;
GraphCanvas::SlotRequestBus::EventResult(slotType, endpoint.GetSlotId(), &GraphCanvas::SlotRequests::GetSlotType);
@@ -3171,6 +3228,10 @@ namespace ScriptCanvasEditor
isEnabled = false;
}
}
else
{
isEnabled = true;
}
bool isNodeling = false;
NodeDescriptorRequestBus::EventResult(isNodeling, endpoint.GetNodeId(), &NodeDescriptorRequests::IsType, NodeDescriptorType::FunctionDefinitionNode);
@@ -217,11 +217,6 @@ namespace ScriptCanvasEditor
ScriptCanvasMemoryAsset::pointer memoryAsset;
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, fileAssetId);
if (!memoryAsset)
{
AZ_Error("Script Canvas", false, AZStd::string::format("Could not find Script Canvas asset: %s", m_scriptCanvasAssetHolder.GetAssetHint().data()).c_str());
}
if (memoryAsset && memoryAsset->GetAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready)
{
OnScriptCanvasAssetReady(memoryAsset);
@@ -292,6 +287,7 @@ namespace ScriptCanvasEditor
}
*/
// #functions2 dependency-ctor-args make recursive
auto executionComponent = gameEntity->CreateComponent<ScriptCanvas::RuntimeComponent>(runtimeAsset);
ScriptCanvas::VariableData varData;
@@ -484,8 +480,8 @@ namespace ScriptCanvasEditor
/*! Start Variable Block Implementation */
void EditorScriptCanvasComponent::AddVariable(AZStd::string_view varName, const ScriptCanvas::GraphVariable& graphVariable)
{
bool exposeVariableToComponent = graphVariable.IsInScope(ScriptCanvas::VariableFlags::Scope::Input);
if (!exposeVariableToComponent)
// We only add component properties to the component
if (!graphVariable.IsComponentProperty())
{
return;
}
@@ -533,7 +529,7 @@ namespace ScriptCanvasEditor
const auto& variableId = varConfig.m_graphVariable.GetVariableId();
auto graphVariable = graphVarData.FindVariable(variableId);
if (!graphVariable || !graphVariable->IsInScope(ScriptCanvas::VariableFlags::Scope::Input))
if (!graphVariable->IsComponentProperty())
{
oldVariableIds.push_back(variableId);
}
@@ -79,7 +79,7 @@ namespace ScriptCanvasEditor
}
else if (auto functionTreeItem = azrtti_cast<const FunctionPaletteTreeItem*>(treeItem))
{
resultHash = ScriptCanvas::NodeUtils::ConstructFunctionNodeIdentifier(functionTreeItem->GetRuntimeAssetId());
resultHash = ScriptCanvas::NodeUtils::ConstructFunctionNodeIdentifier(functionTreeItem->GetAssetId());
}
return resultHash;
@@ -523,13 +523,13 @@ namespace ScriptCanvasEditor
ScriptCanvas::ValidationResults validationResults;
// Disable the s_saveRawTranslationOuputToFile CVar during Parse (not needed for upgrade) and restore to its set value after
bool saveRawTranslationOuputToFile = ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile;
ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile = false;
// Disable the g_saveRawTranslationOuputToFile CVar during Parse (not needed for upgrade) and restore to its set value after
bool saveRawTranslationOuputToFile = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile;
ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false;
graph->Parse(validationResults);
ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile = saveRawTranslationOuputToFile;
ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = saveRawTranslationOuputToFile;
if (validationResults.HasResults())
{
@@ -27,8 +27,6 @@ namespace ScriptCanvasEditor
using LoadedInterpretedDependencies = AZStd::vector<AZStd::pair<AZStd::string, ScriptCanvas::Translation::LuaAssetResult>>;
AZ_INLINE LoadedInterpretedDependencies LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet);
AZ_INLINE LoadTestFunctionResult LoadTestFunction(AZStd::string_view path);
AZ_INLINE LoadTestGraphResult LoadTestGraph(AZStd::string_view path);
struct RunSpec
@@ -58,12 +58,12 @@ namespace ScriptCanvasEditor
originalPath.resize(originalPath.size() - AZStd::string_view(Grammar::k_internalRuntimeSuffix).size());
}
AZStd::string path = AZStd::string::format("%s/%s.scriptcanvas_fn", k_unitTestDirPathRelative, originalPath.data());
LoadTestFunctionResult loadResult = LoadTestFunction(path);
AZ_Assert(loadResult.m_runtimeAsset, "failed to load function asset");
AZStd::string path = AZStd::string::format("%s/%s.scriptcanvas", k_unitTestDirPathRelative, originalPath.data());
LoadTestGraphResult loadResult = LoadTestGraph(path);
AZ_Assert(loadResult.m_runtimeAsset, "failed to load dependent asset");
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> luaAssetOutcome = AZ::Failure(AZStd::string("lua asset creation for function failed"));
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaFunctionAsset, loadResult.m_editorAsset, loadResult.m_graphPath);
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_graphPath);
AZ_Assert(luaAssetOutcome.IsSuccess(), "failed to create Lua asset");
AZStd::string modulePath = namespacePath[0].data();
@@ -97,29 +97,6 @@ namespace ScriptCanvasEditor
return spec;
}
AZ_INLINE LoadTestFunctionResult LoadTestFunction(AZStd::string_view path)
{
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> editorAsset;
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(editorAsset, &ScriptCanvasEditor::EditorAssetConversionBusTraits::LoadFunctionAsset, path);
if (editorAsset.GetData())
{
AZ::Outcome< AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> assetOutcome = AZ::Failure(AZStd::string("asset creation failed"));
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(assetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateFunctionRuntimeAsset, editorAsset);
if (assetOutcome.IsSuccess())
{
LoadTestFunctionResult result;
result.m_graphPath = path;
result.m_editorAsset = editorAsset;
result.m_runtimeAsset = assetOutcome.GetValue();
result.m_entity = AZStd::make_unique<AZ::Entity>("Loaded Graph");
return result;
}
}
return {};
}
AZ_INLINE LoadTestGraphResult LoadTestGraph(AZStd::string_view graphPath)
{
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> editorAsset;
@@ -230,7 +207,7 @@ namespace ScriptCanvasEditor
if (!reporter.IsProcessOnly())
{
dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.userSubgraphs);
dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.source.userSubgraphs);
if (!dependencies.empty())
{
@@ -260,7 +237,7 @@ namespace ScriptCanvasEditor
dependencyData.m_input = depencyAssetResult.m_runtimeInputs;
dependencyData.m_debugMap = depencyAssetResult.m_debugMap;
dependencyData.m_script = depencyAssetResult.m_scriptAsset;
Execution::Context::IntializeAssetData(dependencyData);
Execution::Context::InitializeActivationData(dependencyData);
Execution::InitializeInterpretedStatics(dependencyData);
}
}
@@ -270,7 +247,7 @@ namespace ScriptCanvasEditor
loadResult.m_runtimeAsset.Get()->GetData().m_input = luaAssetResult.m_runtimeInputs;
loadResult.m_runtimeAsset.Get()->GetData().m_debugMap = luaAssetResult.m_debugMap;
loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent<ScriptCanvas::RuntimeComponent>(loadResult.m_runtimeAsset);
Execution::Context::IntializeAssetData(loadResult.m_runtimeAsset->GetData());
Execution::Context::InitializeActivationData(loadResult.m_runtimeAsset->GetData());
Execution::InitializeInterpretedStatics(loadResult.m_runtimeAsset->GetData());
}
else
@@ -1,4 +1,4 @@
/*
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
@@ -1,4 +1,4 @@
/*
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
@@ -57,8 +57,8 @@ namespace ScriptCanvasEditor
if (requestInterface)
{
AZStd::vector< const ScriptCanvas::Slot* > scriptSlots;
ScriptCanvas::NodeRequestBus::EventResult(scriptSlots, GetScriptCanvasNodeId(), &ScriptCanvas::NodeRequests::GetAllSlots);
AZStd::vector<ScriptCanvas::Slot*> scriptSlots;
ScriptCanvas::NodeRequestBus::EventResult(scriptSlots, GetScriptCanvasNodeId(), &ScriptCanvas::NodeRequests::ModAllSlots);
for (int i = 0; i < scriptSlots.size(); ++i)
{
@@ -110,7 +110,7 @@ namespace ScriptCanvasEditor
////
protected:
void OnAddedToGraphCanvasGraph(const GraphCanvas::GraphId& graphId, const AZ::EntityId& scriptCanvasNodeId);
void OnAddedToGraphCanvasGraph(const GraphCanvas::GraphId& graphId, const AZ::EntityId& scriptCanvasNodeId) override;
private:
@@ -0,0 +1,102 @@
/*
* 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 "FunctionDefinitionNodeDescriptorComponent.h"
#include <QInputDialog>
#include <QMainWindow>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/NodelingBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
namespace ScriptCanvasEditor
{
FunctionDefinitionNodeDescriptorComponent::FunctionDefinitionNodeDescriptorComponent()
: NodelingDescriptorComponent(NodeDescriptorType::FunctionDefinitionNode)
{
}
void FunctionDefinitionNodeDescriptorComponent::Activate()
{
NodelingDescriptorComponent::Activate();
GraphCanvas::VisualNotificationBus::Handler::BusConnect(GetEntityId());
}
void FunctionDefinitionNodeDescriptorComponent::Deactivate()
{
NodelingDescriptorComponent::Deactivate();
GraphCanvas::VisualNotificationBus::Handler::BusDisconnect();
}
void FunctionDefinitionNodeDescriptorComponent::Reflect(AZ::ReflectContext* reflectContext)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<FunctionDefinitionNodeDescriptorComponent, NodelingDescriptorComponent>()
->Version(1)
;
}
}
bool FunctionDefinitionNodeDescriptorComponent::RenameDialog(FunctionDefinitionNodeDescriptorComponent* descriptor)
{
if (!descriptor)
{
return false;
}
AZStd::string inBoxText{};
AZStd::string defaultName{};
GraphCanvas::NodeId nodeId = descriptor->GetEntityId();
GraphCanvas::NodeTitleRequestBus::EventResult(defaultName, nodeId, &GraphCanvas::NodeTitleRequests::GetTitle);
QMainWindow* editorWindow = nullptr;
UIRequestBus::BroadcastResult(editorWindow, &UIRequests::GetMainWindow);
bool accepted = false;
QString name = QInputDialog::getText(qobject_cast<QWidget*>(editorWindow->parent()), "Name", inBoxText.c_str(), QLineEdit::Normal, defaultName.c_str(), &accepted);
const AZStd::string newName = name.toUtf8().data();
if (!name.isEmpty() && newName.compare(defaultName) != 0)
{
GraphCanvas::NodeTitleRequestBus::Event(nodeId, &GraphCanvas::NodeTitleRequests::SetTitle, newName);
AZ::EntityId graphCanvasGraphId;
GraphCanvas::SceneMemberRequestBus::EventResult(graphCanvasGraphId, descriptor->GetEntityId(), &GraphCanvas::SceneMemberRequests::GetScene);
ScriptCanvas::ScriptCanvasId scriptCanvasId;
GeneralRequestBus::BroadcastResult(scriptCanvasId, &GeneralRequests::GetScriptCanvasId, graphCanvasGraphId);
ScriptCanvas::GraphScopedNodeId scopedNodeId = ScriptCanvas::GraphScopedNodeId(scriptCanvasId, descriptor->FindScriptCanvasNodeId());
ScriptCanvas::NodelingRequestBus::Event(scopedNodeId, &ScriptCanvas::NodelingRequests::SetDisplayName, newName);
return true;
}
return false;
}
bool FunctionDefinitionNodeDescriptorComponent::OnMouseDoubleClick(const QGraphicsSceneMouseEvent*)
{
return RenameDialog(this);
}
}
@@ -0,0 +1,47 @@
/*
* 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
#include "NodelingDescriptorComponent.h"
#include <Editor/GraphCanvas/Components/NodeDescriptors/NodeDescriptorComponent.h>
#include <ScriptCanvas/Core/NodelingBus.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <GraphCanvas/Components/VisualBus.h>
namespace ScriptCanvasEditor
{
class FunctionDefinitionNodeDescriptorComponent
: public NodelingDescriptorComponent
, GraphCanvas::VisualNotificationBus::Handler
{
public:
AZ_COMPONENT(FunctionDefinitionNodeDescriptorComponent, "{F433EC33-D8A7-40E0-97E7-B29C3C68323E}", NodelingDescriptorComponent);
static void Reflect(AZ::ReflectContext* reflectContext);
FunctionDefinitionNodeDescriptorComponent();
~FunctionDefinitionNodeDescriptorComponent() override = default;
static bool RenameDialog(FunctionDefinitionNodeDescriptorComponent* descriptor);
protected:
void Activate() override;
void Deactivate() override;
// GraphCanvas::VisualNotificationBus::Handler...
bool OnMouseDoubleClick(const QGraphicsSceneMouseEvent*) override;
/////
};
}
@@ -26,7 +26,7 @@
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Libraries/Core/ScriptEventBase.h>
#include <ScriptCanvas/Libraries/Core/FunctionNode.h>
#include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
namespace ScriptCanvasEditor
{
@@ -51,7 +51,7 @@ namespace ScriptCanvasEditor
void OnVersionConversionEnd() override;
////
// GraphCanvas::NodeNotificationBus
// GraphCanvas::VisualNotificationBus
bool OnMouseDoubleClick(const QGraphicsSceneMouseEvent*) override;
//
@@ -44,6 +44,7 @@ namespace ScriptCanvasEditor
// NodeDescriptorBus::Handler
NodeDescriptorType GetType() const override { return m_nodeDescriptorType; }
NodeDescriptorComponent* GetDescriptorComponent() override { return this; }
////
// GraphCanvas::NodeNotificationBus
@@ -11,11 +11,13 @@
*/
#include "precompiled.h"
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include "NodelingDescriptorComponent.h"
#include "ScriptCanvas/Bus/EditorScriptCanvasBus.h"
#include "ScriptCanvas/GraphCanvas/MappingBus.h"
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Core/Slot.h>
#include <ScriptCanvas/Libraries/Core/Nodeling.h>
namespace ScriptCanvasEditor
{
@@ -35,11 +37,18 @@ namespace ScriptCanvasEditor
}
}
NodelingDescriptorComponent::NodelingDescriptorComponent()
: NodeDescriptorComponent(NodeDescriptorType::FunctionDefinitionNode)
NodelingDescriptorComponent::NodelingDescriptorComponent(NodeDescriptorType descriptorType)
: NodeDescriptorComponent(descriptorType)
{
}
void NodelingDescriptorComponent::Deactivate()
{
NodeDescriptorComponent::Deactivate();
ScriptCanvas::GraphNotificationBus::Handler::BusDisconnect();
}
void NodelingDescriptorComponent::OnNameChanged(const AZStd::string& displayName)
{
GraphCanvas::NodeTitleRequestBus::Event(GetEntityId(), &GraphCanvas::NodeTitleRequests::SetTitle, displayName);
@@ -56,7 +65,180 @@ namespace ScriptCanvasEditor
AZStd::string displayName;
ScriptCanvas::NodelingRequestBus::EventResult(displayName, scopedNodeId, &ScriptCanvas::NodelingRequests::GetDisplayName);
OnNameChanged(displayName);
ScriptCanvas::GraphNotificationBus::Handler::BusConnect(scriptCanvasId);
}
ScriptCanvas::Slot* NodelingDescriptorComponent::GetSlotFromNodeling(const AZ::EntityId& connectionId)
{
GraphCanvas::Endpoint sourceEndpoint;
GraphCanvas::ConnectionRequestBus::EventResult(sourceEndpoint, connectionId, &GraphCanvas::ConnectionRequests::GetSourceEndpoint);
GraphCanvas::Endpoint targetEndpoint;
GraphCanvas::ConnectionRequestBus::EventResult(targetEndpoint, connectionId, &GraphCanvas::ConnectionRequests::GetTargetEndpoint);
ScriptCanvas::ScriptCanvasId scriptCanvasId;
AZ::EntityId scriptCanvasNodeId = FindScriptCanvasNodeId();
ScriptCanvas::NodeRequestBus::EventResult(scriptCanvasId, scriptCanvasNodeId, &ScriptCanvas::NodeRequests::GetOwningScriptCanvasId);
AZStd::vector<GraphCanvas::Endpoint> endpoints = { sourceEndpoint, targetEndpoint };
for (auto& endpoint : endpoints)
{
ScriptCanvas::Endpoint scEndpoint;
EditorGraphRequestBus::EventResult(scEndpoint, scriptCanvasId, &EditorGraphRequests::ConvertToScriptCanvasEndpoint, endpoint);
ScriptCanvas::Slot* slot = nullptr;
ScriptCanvas::NodeRequestBus::EventResult(slot, scEndpoint.GetNodeId(), &ScriptCanvas::NodeRequests::GetSlot, scEndpoint.GetSlotId());
if (slot)
{
if (azrtti_istypeof<ScriptCanvas::Nodes::Core::Internal::Nodeling>(slot->GetNode()))
{
return slot;
}
}
}
return nullptr;
}
void NodelingDescriptorComponent::OnConnectionComplete(const AZ::EntityId& connectionId)
{
AZStd::vector< AZ::EntityId > graphCanvasSlotIds;
GraphCanvas::NodeRequestBus::EventResult(graphCanvasSlotIds, GetEntityId(), &GraphCanvas::NodeRequests::GetSlotIds);
ScriptCanvas::Slot* slot = GetSlotFromNodeling(connectionId);
if (slot)
{
const auto& descriptor = slot->GetDescriptor();
if (descriptor.IsExecution())
{
AZStd::vector<ScriptCanvas::Slot*> scriptSlots;
ScriptCanvas::NodeRequestBus::EventResult(scriptSlots, slot->GetNodeId(), &ScriptCanvas::NodeRequests::ModAllSlots);
if (descriptor.IsInput())
{
// Hide the output slot
for (ScriptCanvas::Slot* s : scriptSlots)
{
if (s->IsExecution() && s->IsOutput())
{
// Need the GC slot Id
AZ::EntityId graphCanvasGraphId;
ScriptCanvasEditor::SlotMappingRequestBus::EventResult(graphCanvasGraphId, s->GetNodeId(), &ScriptCanvasEditor::SlotMappingRequests::MapToGraphCanvasId, s->GetId());
if (graphCanvasGraphId.IsValid())
{
m_removedSlotId = graphCanvasGraphId;
//m_removedSlot = *s; // copy the slot?
GraphCanvas::NodeRequestBus::Event(GetEntityId(), &GraphCanvas::NodeRequests::RemoveSlot, graphCanvasGraphId);
}
s->SetVisible(false);
}
}
}
else
{
// Hide the input slot
for (ScriptCanvas::Slot* s : scriptSlots)
{
if (s->IsExecution() && s->IsInput())
{
AZ::EntityId graphCanvasGraphId;
ScriptCanvasEditor::SlotMappingRequestBus::EventResult(graphCanvasGraphId, s->GetNodeId(), &ScriptCanvasEditor::SlotMappingRequests::MapToGraphCanvasId, s->GetId());
if (graphCanvasGraphId.IsValid())
{
GraphCanvas::NodeRequestBus::Event(GetEntityId(), &GraphCanvas::NodeRequests::RemoveSlot, graphCanvasGraphId);
}
s->SetVisible(false);
}
}
}
}
}
}
void NodelingDescriptorComponent::OnDisonnectionComplete(const AZ::EntityId& connectionId)
{
ScriptCanvas::Slot* slot = GetSlotFromNodeling(connectionId);
if (slot)
{
const auto& descriptor = slot->GetDescriptor();
if (descriptor.IsExecution())
{
AZStd::vector<ScriptCanvas::Slot*> scriptSlots;
ScriptCanvas::NodeRequestBus::EventResult(scriptSlots, slot->GetNodeId(), &ScriptCanvas::NodeRequests::ModAllSlots);
if (descriptor.IsInput())
{
// Hide the output slot
for (ScriptCanvas::Slot* s : scriptSlots)
{
if (s->IsExecution() && s->IsOutput())
{
AZ::EntityId graphCanvasGraphId;
ScriptCanvasEditor::SlotMappingRequestBus::EventResult(graphCanvasGraphId, s->GetNodeId(), &ScriptCanvasEditor::SlotMappingRequests::MapToGraphCanvasId, s->GetId());
if (graphCanvasGraphId.IsValid())
{
GraphCanvas::NodeRequestBus::Event(GetEntityId(), &GraphCanvas::NodeRequests::AddSlot, m_removedSlotId);
}
s->SetVisible(true);
}
}
}
else
{
// Hide the input slot
for (ScriptCanvas::Slot* s : scriptSlots)
{
if (s->IsExecution() && s->IsInput())
{
AZ::EntityId graphCanvasGraphId;
ScriptCanvasEditor::SlotMappingRequestBus::EventResult(graphCanvasGraphId, s->GetNodeId(), &ScriptCanvasEditor::SlotMappingRequests::MapToGraphCanvasId, s->GetId());
if (graphCanvasGraphId.IsValid())
{
GraphCanvas::NodeRequestBus::Event(GetEntityId(), &GraphCanvas::NodeRequests::AddSlot, graphCanvasGraphId);
}
s->SetVisible(true);
}
}
}
}
}
}
void NodelingDescriptorComponent::OnPreConnectionRemoved(const AZ::EntityId& connectionId)
{
ScriptCanvas::Slot* slot = GetSlotFromNodeling(connectionId);
if (slot)
{
const auto& descriptor = slot->GetDescriptor();
if (descriptor.IsExecution())
{
AZStd::vector<ScriptCanvas::Slot*> scriptSlots;
ScriptCanvas::NodeRequestBus::EventResult(scriptSlots, slot->GetNodeId(), &ScriptCanvas::NodeRequests::ModAllSlots);
// Show all the slots
for (ScriptCanvas::Slot* s : scriptSlots)
{
s->SetVisible(true);
}
}
}
}
}
@@ -16,25 +16,41 @@
#include <Editor/GraphCanvas/Components/NodeDescriptors/NodeDescriptorComponent.h>
#include <ScriptCanvas/Core/NodelingBus.h>
#include <ScriptCanvas/Core/GraphBus.h>
namespace ScriptCanvasEditor
{
class NodelingDescriptorComponent
: public NodeDescriptorComponent
, public ScriptCanvas::NodelingNotificationBus::Handler
, private ScriptCanvas::GraphNotificationBus::Handler
{
public:
AZ_COMPONENT(NodelingDescriptorComponent, "{9EFA1DA5-2CCB-4A6D-AA84-BD121C75773A}", NodeDescriptorComponent);
static void Reflect(AZ::ReflectContext* reflectContext);
NodelingDescriptorComponent();
~NodelingDescriptorComponent() = default;
NodelingDescriptorComponent(NodeDescriptorType descriptorType = NodeDescriptorType::FunctionDefinitionNode);
~NodelingDescriptorComponent() override = default;
void Deactivate() override;
// NodelingNotificationBus
void OnNameChanged(const AZStd::string& newName) override;
////
// GraphCanvas::GraphNotificationBus
void OnConnectionComplete(const AZ::EntityId& connectionId) override;
void OnDisonnectionComplete(const AZ::EntityId& connectionId) override;
void OnPreConnectionRemoved(const AZ::EntityId& connectionId) override;
////
protected:
void OnAddedToGraphCanvasGraph(const GraphCanvas::GraphId& graphId, const AZ::EntityId& scriptCanvasNodeId) override;
ScriptCanvas::Slot* GetSlotFromNodeling(const AZ::EntityId& connectionId);
AZ::Entity* m_slotEntity;
ScriptCanvas::Slot* m_removedSlot;
AZ::EntityId m_removedSlotId;
};
}
@@ -193,17 +193,6 @@ namespace ScriptCanvasEditor
if (remapVariableOutcome)
{
SetVariableId(remapVariableOutcome.GetValue());
bool runtimeGraph = false;
EditorGraphRequestBus::EventResult(runtimeGraph, scriptCanvasId2, &EditorGraphRequests::IsRuntimeGraph);
ScriptCanvas::GraphVariable* variable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(variable, scriptCanvasId2, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, remapVariableOutcome.GetValue());
if (variable)
{
variable->RemoveScope(ScriptCanvas::VariableFlags::Scope::Output);
}
}
}
}
@@ -31,6 +31,8 @@ class QPushButton;
class QTableView;
class QToolButton;
namespace ScriptCanvas { class Slot; }
namespace GraphCanvas
{
struct Endpoint;
@@ -83,7 +85,6 @@ namespace ScriptCanvasEditor
virtual void OnChangeActiveGraphTab(AZ::Data::AssetId) {}
virtual void CreateNewFunctionAsset() = 0;
virtual void CreateNewRuntimeAsset() = 0;
virtual ScriptCanvas::ScriptCanvasId GetActiveScriptCanvasId() const
@@ -195,6 +196,14 @@ namespace ScriptCanvasEditor
virtual void RegisterVariableType(const ScriptCanvas::Data::Type& variabletype) = 0;
virtual bool IsValidVariableType(const ScriptCanvas::Data::Type& variableType) const = 0;
struct SlotSetup
{
AZStd::string m_name;
AZ::Uuid m_type = AZ::Uuid::CreateNull();
};
virtual bool ShowSlotTypeSelector(ScriptCanvas::Slot* slot, const QPoint& scenePosition, SlotSetup&) = 0;
};
using VariablePaletteRequestBus = AZ::EBus<VariablePaletteRequests>;
@@ -196,7 +196,7 @@ namespace ScriptCanvasEditor
GraphCanvas::CanHandleMimeEventOutcome CanHandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) override;
bool HandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) override;
GraphCanvas::SlotId RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) override;
GraphCanvas::SlotId RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId, GraphModelRequests::ExtensionRequestReason ) override;
void ExtensionCancelled(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) override;
void FinalizeExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) override;
@@ -357,6 +357,9 @@ namespace ScriptCanvasEditor
AZStd::unordered_map< GraphCanvas::ToastId, AZ::EntityId > m_toastNodeIds;
// Function Definition Node Extension
void HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId);
//// Version Update code
AZ::Outcome<ScriptCanvas::Node*> ReplaceNodeByConfig(ScriptCanvas::Node*, const ScriptCanvas::NodeConfiguration&, ScriptCanvas::ReplacementConnectionMap&);
bool SanityCheckNodeReplacement(ScriptCanvas::Node*, ScriptCanvas::Node*, AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>>&);
@@ -146,8 +146,6 @@ namespace ScriptCanvasEditor
void LoadVariables(const ScriptCanvasMemoryAsset::pointer memoryAsset);
void ClearVariables();
void GetScriptCanvasId();
private:
AZ::Data::AssetId m_removedCatalogId;
AZ::Data::AssetId m_previousAssetId;
@@ -53,7 +53,9 @@ namespace ScriptCanvasEditor
AzEventHandler,
Invalid
};
class NodeDescriptorComponent;
class NodeDescriptorRequests : public AZ::EBusTraits
{
public:
@@ -74,6 +76,8 @@ namespace ScriptCanvasEditor
return GetType() == descriptorType;
}
virtual NodeDescriptorComponent* GetDescriptorComponent() = 0;
};
using NodeDescriptorRequestBus = AZ::EBus<NodeDescriptorRequests>;
@@ -15,6 +15,7 @@
#include <Editor/Nodes/NodeCreateUtils.h>
#include <Editor/Nodes/NodeDisplayUtils.h>
#include <GraphCanvas/Components/Nodes/NodeBus.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
@@ -23,7 +24,7 @@
#include <ScriptCanvas/Libraries/Core/AzEventHandler.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <ScriptCanvas/Libraries/Core/FunctionNode.h>
#include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
#include <ScriptCanvas/Libraries/Core/GetVariable.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
#include <ScriptCanvas/Libraries/Core/MethodOverloaded.h>
@@ -34,12 +35,15 @@
namespace ScriptCanvasEditor::Nodes
{
NodeIdPair CreateExecutionNodeling(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, AZStd::string_view rootName)
NodeIdPair CreateFunctionDefinitionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, bool isInput, AZStd::string rootName)
{
ScriptCanvasEditor::Nodes::StyleConfiguration styleConfiguration;
NodeIdPair createdPair = CreateNode(azrtti_typeid<ScriptCanvas::Nodes::Core::FunctionDefinitionNode>(), scriptCanvasId, styleConfiguration);
auto nodeAndPair = CreateAndGetNode(azrtti_typeid<ScriptCanvas::Nodes::Core::FunctionDefinitionNode>(), scriptCanvasId, styleConfiguration);
NodeIdPair createdPair = nodeAndPair.second;
if (createdPair.m_scriptCanvasId.IsValid())
auto functionDefinitionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(nodeAndPair.first);
if (functionDefinitionNode && createdPair.m_scriptCanvasId.IsValid())
{
AZStd::unordered_set<AZStd::string> nodelingNames;
@@ -71,12 +75,43 @@ namespace ScriptCanvasEditor::Nodes
nodelingId.m_scriptCanvasId = scriptCanvasId;
ScriptCanvas::NodelingRequestBus::Event(nodelingId, &ScriptCanvas::NodelingRequests::SetDisplayName, nodelingName);
if (!isInput)
{
functionDefinitionNode->MarkExecutionExit();
}
GraphCanvas::NodeTitleRequestBus::Event(createdPair.m_graphCanvasId, &GraphCanvas::NodeTitleRequests::SetSubTitle, "Function");
// Because of how the extender slots are registered, there isn't an easy way to only create one or the other based on
// the type of nodeling, so instead they both get created and we need to remove the inapplicable one
GraphCanvas::ConnectionType typeToRemove = (isInput) ? GraphCanvas::CT_Input : GraphCanvas::CT_Output;
AZStd::vector<GraphCanvas::SlotId> extenderSlotIds, executionSlotIds;
GraphCanvas::NodeRequestBus::EventResult(extenderSlotIds, createdPair.m_graphCanvasId, &GraphCanvas::NodeRequests::FindVisibleSlotIdsByType, typeToRemove, GraphCanvas::SlotTypes::ExtenderSlot);
if (!extenderSlotIds.empty())
{
GraphCanvas::NodeRequestBus::Event(createdPair.m_graphCanvasId, &GraphCanvas::NodeRequests::RemoveSlot, *extenderSlotIds.begin());
}
GraphCanvas::NodeRequestBus::EventResult(executionSlotIds, createdPair.m_graphCanvasId, &GraphCanvas::NodeRequests::FindVisibleSlotIdsByType, typeToRemove, GraphCanvas::SlotTypes::ExecutionSlot);
if (!executionSlotIds.empty())
{
GraphCanvas::NodeRequestBus::Event(createdPair.m_graphCanvasId, &GraphCanvas::NodeRequests::RemoveSlot, *executionSlotIds.begin());
}
}
return createdPair;
}
NodeIdPair CreateNode(const AZ::Uuid& classId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration)
{
return CreateAndGetNode(classId, scriptCanvasId, styleConfiguration).second;
}
AZStd::pair<ScriptCanvas::Node*, NodeIdPair> CreateAndGetNode(const AZ::Uuid& classId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration)
{
AZ_PROFILE_TIMER("ScriptCanvas", __FUNCTION__);
NodeIdPair nodeIdPair;
@@ -104,7 +139,7 @@ namespace ScriptCanvasEditor::Nodes
//nodeConfiguration.m_nodeSubStyle = styleConfiguration.m_nodeSubStyle;
}
return nodeIdPair;
return AZStd::make_pair(node, nodeIdPair);
}
NodeIdPair CreateEntityNode(const AZ::EntityId& sourceId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
@@ -367,7 +402,7 @@ namespace ScriptCanvasEditor::Nodes
return nodeIds;
}
NodeIdPair CreateFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId, const AZ::Data::AssetId& assetId)
NodeIdPair CreateFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId, const AZ::Data::AssetId& assetId, const ScriptCanvas::Grammar::FunctionSourceId& sourceId)
{
AZ_Assert(assetId.IsValid(), "CreateFunctionNode source asset Id must be valid");
@@ -381,11 +416,9 @@ namespace ScriptCanvasEditor::Nodes
scriptCanvasEntity->Init();
ScriptCanvas::Node* node = nullptr;
ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasGraphId, ScriptCanvas::Nodes::Core::FunctionNode::RTTI_Type());
auto* functionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionNode*>(node);
functionNode->Initialize(assetId);
functionNode->ConfigureNode(assetId);
ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::CreateNodeOnEntity, scriptCanvasEntity->GetId(), scriptCanvasGraphId, ScriptCanvas::Nodes::Core::FunctionCallNode::RTTI_Type());
auto functionNode = azrtti_cast<ScriptCanvas::Nodes::Core::FunctionCallNode*>(node);
functionNode->Initialize(assetId, sourceId);
functionNode->BuildNode();
nodeIdPair.m_scriptCanvasId = scriptCanvasEntity->GetId();
@@ -13,12 +13,16 @@
#pragma once
#include <AzCore/Component/EntityId.h>
#include <Editor/Nodes/NodeUtils.h>
#include <ScriptCanvas/Bus/NodeIdPair.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
#include <ScriptCanvas/Variable/VariableCore.h>
namespace ScriptCanvas
{
class Node;
}
namespace ScriptEvents
{
class Method;
@@ -27,6 +31,7 @@ namespace ScriptEvents
namespace ScriptCanvasEditor::Nodes
{
// Specific create methods which will also handle displaying the node.
AZStd::pair<ScriptCanvas::Node*, NodeIdPair> CreateAndGetNode(const AZ::Uuid& classData, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration);
NodeIdPair CreateNode(const AZ::Uuid& classData, const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const StyleConfiguration& styleConfiguration);
NodeIdPair CreateEntityNode(const AZ::EntityId& sourceId, const ScriptCanvas::ScriptCanvasId& scriptCanvasId);
NodeIdPair CreateObjectMethodNode(AZStd::string_view className, AZStd::string_view methodName, const ScriptCanvas::ScriptCanvasId& scriptCanvasId);
@@ -42,10 +47,8 @@ namespace ScriptCanvasEditor::Nodes
NodeIdPair CreateSetVariableNode(const ScriptCanvas::VariableId& variableId, ScriptCanvas::ScriptCanvasId scriptCanvasGraphId);
// Functions
NodeIdPair CreateFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId, const AZ::Data::AssetId& assetId);
// Nodelings
NodeIdPair CreateExecutionNodeling(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, AZStd::string_view rootName = "New Nodeling");
NodeIdPair CreateFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasGraphId, const AZ::Data::AssetId& assetId, const ScriptCanvas::Grammar::FunctionSourceId& sourceId);
NodeIdPair CreateFunctionDefinitionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, bool isInput, AZStd::string rootName = "New Nodeling");
// AZ Event
NodeIdPair CreateAzEventHandlerNode(const AZ::BehaviorMethod& methodWithAzEventReturn, ScriptCanvas::ScriptCanvasId scriptCanvasId,
@@ -30,6 +30,8 @@
#include <GraphCanvas/Components/NodeDescriptors/ScriptEventReceiverNodeDescriptorComponent.h>
#include <GraphCanvas/Components/NodeDescriptors/ScriptEventSenderNodeDescriptorComponent.h>
#include <GraphCanvas/Components/NodeDescriptors/UserDefinedNodeDescriptorComponent.h>
#include <GraphCanvas/Components/NodeDescriptors/FunctionDefinitionNodeDescriptorComponent.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <GraphCanvas/GraphCanvasBus.h>
#include <GraphCanvas/Components/Slots/Extender/ExtenderSlotBus.h>
@@ -39,7 +41,7 @@
#include <ScriptCanvas/Libraries/Core/AzEventHandler.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <ScriptCanvas/Libraries/Core/FunctionNode.h>
#include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
#include <ScriptCanvas/Libraries/Core/GetVariable.h>
#include <ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
@@ -47,6 +49,7 @@
#include <ScriptCanvas/Libraries/Core/SetVariable.h>
#include <ScriptCanvas/Libraries/Entity/EntityRef.h>
namespace ScriptCanvasEditor::Nodes::SlotDisplayHelper
{
AZ::EntityId DisplayPropertySlot(AZ::EntityId graphCanvasNodeId, const ScriptCanvas::VisualExtensionSlotConfiguration& propertyConfiguration);
@@ -819,12 +822,12 @@ namespace ScriptCanvasEditor::Nodes
}
// Function Nodes
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::FunctionNode* functionNode)
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::FunctionCallNode* functionNode)
{
return DisplayFunctionNode(graphCanvasGraphId, const_cast<ScriptCanvas::Nodes::Core::FunctionNode*>(functionNode));
return DisplayFunctionNode(graphCanvasGraphId, const_cast<ScriptCanvas::Nodes::Core::FunctionCallNode*>(functionNode));
}
AZ::EntityId DisplayFunctionNode(AZ::EntityId, ScriptCanvas::Nodes::Core::FunctionNode* functionNode)
AZ::EntityId DisplayFunctionNode(AZ::EntityId, ScriptCanvas::Nodes::Core::FunctionCallNode* functionNode)
{
AZ::EntityId graphCanvasNodeId;
@@ -892,6 +895,80 @@ namespace ScriptCanvasEditor::Nodes
return graphCanvasNodeId;
}
AZ::EntityId DisplayFunctionDefinitionNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::FunctionDefinitionNode* nodeling)
{
NodeConfiguration nodeConfiguration;
nodeConfiguration.PopulateComponentDescriptors<IconComponent, FunctionDefinitionNodeDescriptorComponent>();
if (nodeling->RequiresDynamicSlotOrdering())
{
nodeConfiguration.PopulateComponentDescriptors<DynamicOrderingDynamicSlotComponent>();
}
else
{
nodeConfiguration.PopulateComponentDescriptors<DynamicSlotComponent>();
}
nodeConfiguration.m_nodeSubStyle = ".nodeling";
nodeConfiguration.m_titlePalette = "NodelingTitlePalette";
nodeConfiguration.m_scriptCanvasId = nodeling->GetEntityId();
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
AZ_Assert(serializeContext, "Failed to acquire application serialize context.");
const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid(nodeling));
if (classData)
{
AZStd::string nodeContext = GetContextName(*classData);
nodeConfiguration.m_translationContext = TranslationHelper::GetUserDefinedContext(nodeContext);
nodeConfiguration.m_titleFallback = (classData->m_editData && classData->m_editData->m_name) ? classData->m_editData->m_name : classData->m_name;
nodeConfiguration.m_tooltipFallback = (classData->m_editData && classData->m_editData->m_description) ? classData->m_editData->m_description : "";
GraphCanvas::TranslationKeyedString subtitleKeyedString(nodeContext, nodeConfiguration.m_translationContext);
subtitleKeyedString.m_key = TranslationHelper::GetUserDefinedNodeKey(nodeContext, nodeConfiguration.m_titleFallback, ScriptCanvasEditor::TranslationKeyId::Category);
nodeConfiguration.m_subtitleFallback = subtitleKeyedString.GetDisplayString();
nodeConfiguration.m_translationKeyName = nodeConfiguration.m_titleFallback;
nodeConfiguration.m_translationKeyContext = nodeContext;
nodeConfiguration.m_translationGroup = TranslationContextGroup::ClassMethod;
ScriptCanvas::GraphScopedNodeId nodelingId;
nodelingId.m_identifier = nodeConfiguration.m_scriptCanvasId;
nodelingId.m_scriptCanvasId = nodeling->GetOwningScriptCanvasId();
AZStd::string nodelingName;
ScriptCanvas::NodelingRequestBus::EventResult(nodelingName, nodelingId, &ScriptCanvas::NodelingRequests::GetDisplayName);
if (classData->m_editData)
{
const AZ::Edit::ElementData* elementData = classData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData);
if (elementData)
{
if (auto nodeTypeAttribute = elementData->FindAttribute(ScriptCanvas::Attributes::Node::NodeType))
{
if (auto nodeTypeAttributeData = azdynamic_cast<const AZ::Edit::AttributeData<NodeType>*>(nodeTypeAttribute))
{
nodeConfiguration.m_nodeType = nodeTypeAttributeData->Get(nullptr);
}
}
}
}
}
nodeConfiguration.m_subtitleFallback = "";
return DisplayGeneralScriptCanvasNode(graphCanvasGraphId, nodeling, nodeConfiguration);
}
AZ::EntityId DisplayNodeling(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::Internal::Nodeling* nodeling)
{
NodeConfiguration nodeConfiguration;
@@ -1062,9 +1139,13 @@ namespace ScriptCanvasEditor::Nodes
{
graphCanvasNodeId = DisplayScriptEventSenderNode(graphCanvasGraphId, static_cast<const ScriptCanvas::Nodes::Core::SendScriptEvent*>(node));
}
else if (azrtti_istypeof<ScriptCanvas::Nodes::Core::FunctionNode>(node))
else if (azrtti_istypeof<ScriptCanvas::Nodes::Core::FunctionCallNode>(node))
{
graphCanvasNodeId = DisplayFunctionNode(graphCanvasGraphId, static_cast<const ScriptCanvas::Nodes::Core::FunctionNode*>(node));
graphCanvasNodeId = DisplayFunctionNode(graphCanvasGraphId, static_cast<const ScriptCanvas::Nodes::Core::FunctionCallNode*>(node));
}
else if (azrtti_istypeof<ScriptCanvas::Nodes::Core::FunctionDefinitionNode>(node))
{
graphCanvasNodeId = DisplayFunctionDefinitionNode(graphCanvasGraphId, static_cast<const ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>(node));
}
else if (azrtti_istypeof<ScriptCanvas::Nodes::Core::Internal::Nodeling>(node))
{
@@ -1138,7 +1219,7 @@ namespace ScriptCanvasEditor::Nodes
if (slot.IsLatent())
{
executionConfiguration.m_textDecoration = "🕒";
executionConfiguration.m_textDecoration = u8"\U0001f552";
executionConfiguration.m_textDecorationToolTip = "This slot will not be executed immediately.";
}
@@ -1163,7 +1244,7 @@ namespace ScriptCanvasEditor::Nodes
if (slot.IsLatent())
{
dataSlotConfiguration.m_textDecoration = "🕒";
dataSlotConfiguration.m_textDecoration = u8"\U0001f552";
dataSlotConfiguration.m_textDecorationToolTip = "This slot will not be executed immediately.";
}
@@ -28,7 +28,7 @@ namespace ScriptCanvas::Nodes::Core
{
class AzEventHandler;
class EBusEventHandler;
class FunctionNode;
class FunctionCallNode;
class GetVariableNode;
class Method;
class ReceiveScriptEvent;
@@ -66,8 +66,8 @@ namespace ScriptCanvasEditor::Nodes
AZ::EntityId DisplayScriptEventWrapperNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::ReceiveScriptEvent* busNode);
// Functions
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::FunctionNode* functionNode);
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, ScriptCanvas::Nodes::Core::FunctionNode* functionNode);
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, const ScriptCanvas::Nodes::Core::FunctionCallNode* functionNode);
AZ::EntityId DisplayFunctionNode(AZ::EntityId graphCanvasGraphId, ScriptCanvas::Nodes::Core::FunctionCallNode* functionNode);
// SlotGroup will control how elements are grouped.
@@ -66,6 +66,7 @@
#include <Editor/GraphCanvas/Components/NodeDescriptors/UserDefinedNodeDescriptorComponent.h>
#include <Editor/GraphCanvas/Components/NodeDescriptors/VariableNodeDescriptorComponent.h>
#include <Editor/GraphCanvas/Components/NodeDescriptors/FunctionNodeDescriptorComponent.h>
#include <Editor/GraphCanvas/Components/NodeDescriptors/FunctionDefinitionNodeDescriptorComponent.h>
#include <Editor/GraphCanvas/Components/MappingComponent.h>
#include <Editor/View/Widgets/VariablePanel/VariableDockWidget.h>
@@ -118,6 +119,7 @@ namespace ScriptCanvas
ScriptCanvasEditor::SetVariableNodeDescriptorComponent::CreateDescriptor(),
ScriptCanvasEditor::UserDefinedNodeDescriptorComponent::CreateDescriptor(),
ScriptCanvasEditor::FunctionNodeDescriptorComponent::CreateDescriptor(),
ScriptCanvasEditor::FunctionDefinitionNodeDescriptorComponent::CreateDescriptor(),
ScriptCanvasEditor::NodelingDescriptorComponent::CreateDescriptor()
});
+2 -2
View File
@@ -30,8 +30,8 @@ namespace SettingsCpp
{
if (auto userSettings = AZ::UserSettings::CreateFind<ScriptCanvasEditor::EditorSettings::ScriptCanvasEditorSettings>(AZ_CRC("ScriptCanvasPreviewSettings", 0x1c5a2965), AZ::UserSettings::CT_LOCAL))
{
ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile = userSettings->m_saveRawTranslationOuputToFile;
ScriptCanvas::Grammar::s_printAbstractCodeModel = userSettings->m_printAbstractCodeModel;
ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = userSettings->m_saveRawTranslationOuputToFile;
ScriptCanvas::Grammar::g_printAbstractCodeModel = userSettings->m_printAbstractCodeModel;
}
}
}
@@ -15,22 +15,19 @@
#include <QPixmap>
#include <AzToolsFramework/AssetEditor/AssetEditorUtils.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/Nodes/NodeCreateUtils.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/VisualBus.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <GraphCanvas/Components/GridBus.h>
#include <GraphCanvas/Components/Nodes/Wrapper/WrapperNodeBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/StyleBus.h>
#include <GraphCanvas/Components/VisualBus.h>
#include <GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
namespace ScriptCanvasEditor
{
@@ -51,50 +48,41 @@ namespace ScriptCanvasEditor
}
CreateFunctionMimeEvent::CreateFunctionMimeEvent(const AZ::Data::AssetId& assetId)
CreateFunctionMimeEvent::CreateFunctionMimeEvent(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const ScriptCanvas::Grammar::FunctionSourceId& sourceId)
: m_assetId(assetId)
, m_assetType(assetType)
, m_sourceId(sourceId)
{
}
bool CreateFunctionMimeEvent::CanGraphHandleEvent(const GraphCanvas::GraphId& graphId) const
bool CreateFunctionMimeEvent::CanGraphHandleEvent([[maybe_unused]] const GraphCanvas::GraphId& graphId) const
{
AZ::EntityId scGraphId;
GeneralRequestBus::BroadcastResult(scGraphId, &GeneralRequests::GetScriptCanvasId, graphId);
bool isFunctionGraph = false;
EditorGraphRequestBus::EventResult(isFunctionGraph, scGraphId, &EditorGraphRequests::IsFunctionGraph);
return !isFunctionGraph;
return true;
}
ScriptCanvasEditor::NodeIdPair CreateFunctionMimeEvent::CreateNode(const AZ::EntityId& scriptCanvasGraphId) const
{
return Nodes::CreateFunctionNode(scriptCanvasGraphId, m_assetId);
return Nodes::CreateFunctionNode(scriptCanvasGraphId, m_assetId, m_sourceId);
}
/////////////////////////////////////
// FunctionPaletteTreeItem
/////////////////////////////////////
FunctionPaletteTreeItem::FunctionPaletteTreeItem(const char* name, const AZ::Data::AssetId& sourceAssetId, const AZ::Data::AssetId& runtimeAssetId)
FunctionPaletteTreeItem::FunctionPaletteTreeItem(const char* name, const ScriptCanvas::Grammar::FunctionSourceId& sourceId, AZ::Data::Asset<AZ::Data::AssetData> asset)
: GraphCanvas::DraggableNodePaletteTreeItem(name, ScriptCanvasEditor::AssetEditorId)
, m_editIcon(":/ScriptCanvasEditorResources/Resources/edit_icon.png")
, m_sourceAssetId(sourceAssetId)
, m_runtimeAssetId(runtimeAssetId)
, m_sourceId(sourceId)
, m_asset(asset)
{
//TODO
// TODO
//SetToolTip(m_methodDefinition.GetTooltip().c_str());
SetTitlePalette("FunctionNodeTitlePalette");
}
void FunctionPaletteTreeItem::SetRuntimeAssetId(const AZ::Data::AssetId& assetId)
{
m_runtimeAssetId = assetId;
}
GraphCanvas::GraphCanvasMimeEvent* FunctionPaletteTreeItem::CreateMimeEvent() const
{
return aznew CreateFunctionMimeEvent(m_runtimeAssetId);
return aznew CreateFunctionMimeEvent(m_asset->GetId(), m_asset->GetType(), m_sourceId);
}
QVariant FunctionPaletteTreeItem::OnData(const QModelIndex& index, int role) const
@@ -117,14 +105,24 @@ namespace ScriptCanvasEditor
return GraphCanvas::DraggableNodePaletteTreeItem::OnData(index, role);
}
const AZ::Data::AssetId& FunctionPaletteTreeItem::GetSourceAssetId() const
ScriptCanvas::Grammar::FunctionSourceId FunctionPaletteTreeItem::GetFunctionSourceId() const
{
return m_sourceAssetId;
return m_sourceId;
}
const AZ::Data::AssetId& FunctionPaletteTreeItem::GetRuntimeAssetId() const
AZ::Data::AssetId FunctionPaletteTreeItem::GetSourceAssetId() const
{
return m_runtimeAssetId;
return AZ::Data::AssetId(GetAssetId().m_guid, 0);
}
AZ::Data::AssetId FunctionPaletteTreeItem::GetAssetId() const
{
return m_asset->GetId();
}
AZ::Data::AssetType FunctionPaletteTreeItem::GetAssetType() const
{
return m_asset->GetType();
}
void FunctionPaletteTreeItem::OnHoverStateChanged()
@@ -136,7 +134,7 @@ namespace ScriptCanvasEditor
{
if (row == NodePaletteTreeItem::Column::Customization)
{
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, m_sourceAssetId, -1);
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, GetSourceAssetId(), -1);
}
}
@@ -144,7 +142,7 @@ namespace ScriptCanvasEditor
{
if (row != NodePaletteTreeItem::Column::Customization)
{
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, m_sourceAssetId, -1);
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, GetSourceAssetId(), -1);
return true;
}
@@ -44,15 +44,16 @@ namespace ScriptCanvasEditor
static void Reflect(AZ::ReflectContext* reflectContext);
CreateFunctionMimeEvent() = default;
CreateFunctionMimeEvent(const AZ::Data::AssetId& assetId);
CreateFunctionMimeEvent(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const ScriptCanvas::Grammar::FunctionSourceId& sourceId);
~CreateFunctionMimeEvent() = default;
bool CanGraphHandleEvent(const GraphCanvas::GraphId& graphId) const override;
ScriptCanvasEditor::NodeIdPair CreateNode(const AZ::EntityId& graphId) const override;
private:
ScriptCanvas::Grammar::FunctionSourceId m_sourceId;
AZ::Data::AssetId m_assetId;
AZ::Data::AssetType m_assetType;
};
class FunctionPaletteTreeItem
@@ -62,30 +63,26 @@ namespace ScriptCanvasEditor
AZ_RTTI(FunctionPaletteTreeItem, "{AF75BBAD-BC8A-46D2-81B6-54C0E6CB3E41}", GraphCanvas::DraggableNodePaletteTreeItem);
AZ_CLASS_ALLOCATOR(FunctionPaletteTreeItem, AZ::SystemAllocator, 0);
FunctionPaletteTreeItem(const char* name, const AZ::Data::AssetId& sourceAssetId, const AZ::Data::AssetId& runtimeAssetId = {});
FunctionPaletteTreeItem(const char* name, const ScriptCanvas::Grammar::FunctionSourceId& sourceId, AZ::Data::Asset<AZ::Data::AssetData> asset);
~FunctionPaletteTreeItem() = default;
void SetRuntimeAssetId(const AZ::Data::AssetId& assetId);
GraphCanvas::GraphCanvasMimeEvent* CreateMimeEvent() const;
QVariant OnData(const QModelIndex& index, int role) const;
const AZ::Data::AssetId& GetSourceAssetId() const;
const AZ::Data::AssetId& GetRuntimeAssetId() const;
ScriptCanvas::Grammar::FunctionSourceId GetFunctionSourceId() const;
AZ::Data::AssetId GetSourceAssetId() const;
AZ::Data::AssetId GetAssetId() const;
AZ::Data::AssetType GetAssetType() const;
protected:
void OnHoverStateChanged() override;
void OnClicked(int row) override;
bool OnDoubleClicked(int row) override;
private:
QIcon m_editIcon;
AZ::Data::AssetId m_sourceAssetId;
AZ::Data::AssetId m_runtimeAssetId;
ScriptCanvas::Grammar::FunctionSourceId m_sourceId;
AZ::Data::Asset<AZ::Data::AssetData> m_asset;
};
}
@@ -583,6 +583,13 @@ namespace
{
if (!IsExplicitOverload(*methodIter.second))
{
// Respect the exclusion flags
auto attributeData = azdynamic_cast<const AZ::Edit::AttributeData<AZ::Script::Attributes::ExcludeFlags>*>(AZ::FindAttribute(AZ::Script::Attributes::ExcludeFrom, methodIter.second->m_attributes));
if (ShouldExcludeFromNodeList(attributeData , {}))
{
return;
}
RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, methodIter.first, *methodIter.second, behaviorClass->IsMethodOverloaded(methodIter.first));
}
}
@@ -1290,7 +1297,7 @@ namespace ScriptCanvasEditor
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
AZStd::string category = "Global Functions";
AZStd::string category = "User Functions";
AZStd::string relativePath;
if (AzFramework::StringFunc::Path::GetFolderPath(assetInfo.m_relativePath.c_str(), relativePath))
@@ -27,59 +27,48 @@
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/std/containers/map.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzCore/std/containers/map.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/AssetEditor/AssetEditorUtils.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
#include <AzToolsFramework/AssetEditor/AssetEditorUtils.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <ScriptEvents/ScriptEventsAsset.h>
#include <GraphCanvas/Widgets/NodePalette/TreeItems/NodePaletteTreeItem.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteWidget.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteTreeView.h>
#include <Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.h>
#include <Editor/View/Widgets/ui_ScriptCanvasNodePaletteToolbar.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/Nodes/NodeUtils.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/SpecializedNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Components/IconComponent.h>
#include <Editor/Include/ScriptCanvas/Bus/RequestBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <Editor/Include/ScriptCanvas/Bus/RequestBus.h>
#include <Editor/Nodes/NodeUtils.h>
#include <Editor/Settings.h>
#include <Editor/Translation/TranslationHelper.h>
#include <Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
#include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/SpecializedNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.h>
#include <Editor/View/Widgets/ui_ScriptCanvasNodePaletteToolbar.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteTreeView.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteWidget.h>
#include <GraphCanvas/Widgets/NodePalette/TreeItems/NodePaletteTreeItem.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Utils/NodeUtils.h>
#include <ScriptCanvas/Core/Attributes.h>
#include <ScriptCanvas/Libraries/Entity/EntityRef.h>
#include <ScriptCanvas/Libraries/Libraries.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Libraries/Core/GetVariable.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
#include <ScriptCanvas/Libraries/Core/SetVariable.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
#include <ScriptCanvas/Libraries/Entity/EntityRef.h>
#include <ScriptCanvas/Libraries/Libraries.h>
#include <ScriptCanvas/Utils/NodeUtils.h>
#include <ScriptEvents/ScriptEventsAsset.h>
namespace ScriptCanvasEditor
{
@@ -103,7 +92,7 @@ namespace ScriptCanvasEditor
GraphCanvas::NodePaletteTreeItem* customEventRoot = root->GetCategoryNode("Script Events");
customEventRoot->SetAllowPruneOnEmpty(false);
GraphCanvas::NodePaletteTreeItem* globalFunctionRoot = root->GetCategoryNode("Global Functions");
GraphCanvas::NodePaletteTreeItem* globalFunctionRoot = root->GetCategoryNode("User Functions");
globalFunctionRoot->SetAllowPruneOnEmpty(false);
}
@@ -167,7 +156,6 @@ namespace ScriptCanvasEditor
, m_nodePaletteModel(nodePaletteModel)
, m_assetModel(assetModel)
, m_categorizer(nodePaletteModel)
, m_isFunctionGraphActive(false)
{
UpgradeNotifications::Bus::Handler::BusConnect();
@@ -245,12 +233,9 @@ namespace ScriptCanvasEditor
{
ScriptCanvas::RuntimeRequestBus::EventResult(m_previousAssetId, scriptCanvasId, &ScriptCanvas::RuntimeRequests::GetAssetId);
m_isFunctionGraphActive = false;
EditorGraphRequestBus::EventResult(m_isFunctionGraphActive, scriptCanvasId, &EditorGraphRequests::IsFunctionGraph);
for (auto functionTreePair : m_globalFunctionTreeItems)
{
functionTreePair.second->SetEnabled(!m_isFunctionGraphActive);
functionTreePair.second->SetEnabled(true);
}
}
@@ -278,7 +263,6 @@ namespace ScriptCanvasEditor
if (entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
auto scriptEventElementIter = m_scriptEventElementTreeItems.find(assetId);
@@ -290,22 +274,10 @@ namespace ScriptCanvasEditor
}
else
{
bool isRuntimeAsset = (m_runtimeAssets.erase(assetId) > 0);
auto globalFunctionElementIter = m_globalFunctionTreeItems.find(assetId.m_guid);
auto globalFunctionElementIter = m_globalFunctionTreeItems.find(assetId);
if (globalFunctionElementIter != m_globalFunctionTreeItems.end())
{
if (isRuntimeAsset)
{
globalFunctionElementIter->second->SetError("Function has errors and cannot be created until these errors are resolved.");
}
else
{
globalFunctionElementIter->second->DetachItem();
delete globalFunctionElementIter->second;
m_globalFunctionTreeItems.erase(globalFunctionElementIter);
}
globalFunctionElementIter->second->SetError("Graph has errors or has been deleted");
}
}
}
@@ -337,35 +309,35 @@ namespace ScriptCanvasEditor
if (entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = static_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasFunctionAsset>())
const auto entryType = productEntry->GetAssetType();
if (entryType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
auto elementIter = m_globalFunctionTreeItems.find(assetId.m_guid);
const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
auto elementIter = m_globalFunctionTreeItems.find(assetId);
if (elementIter == m_globalFunctionTreeItems.end())
{
RequestAssetLoad(assetId, azrtti_typeid<ScriptCanvasFunctionAsset>());
}
}
else if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
auto elementIter = m_globalFunctionTreeItems.find(assetId.m_guid);
if (elementIter == m_globalFunctionTreeItems.end())
{
RequestAssetLoad(assetId, azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>());
RequestAssetLoad(assetId, productEntry->GetAssetType());
}
else
{
elementIter->second->SetRuntimeAssetId(assetId);
elementIter->second->ClearError();
if (elementIter->second->HasError())
{
m_pendingAssets.erase(assetId);
RequestAssetLoad(assetId, productEntry->GetAssetType());
}
}
}
else if (productEntry->GetAssetType() == azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
else if (entryType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
{
const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
auto elementIter = m_scriptEventElementTreeItems.find(assetId.m_guid);
if (elementIter == m_scriptEventElementTreeItems.end())
{
RequestAssetLoad(assetId, azrtti_typeid<ScriptEvents::ScriptEventsAsset>());
RequestAssetLoad(assetId, productEntry->GetAssetType());
}
}
}
@@ -376,17 +348,15 @@ namespace ScriptCanvasEditor
{
AZ::SystemTickBus::Handler::BusDisconnect();
while (!m_queuedLoads.empty())
while (!m_requestQueue.empty())
{
auto entry = m_queuedLoads.front();
m_queuedLoads.erase(m_queuedLoads.begin());
const auto entry = m_requestQueue.front();
m_requestQueue.pop();
if (m_pendingAssets.find(entry) == m_pendingAssets.end())
if (m_pendingAssets.find(entry.first) == m_pendingAssets.end())
{
m_pendingAssets.insert(entry);
AZ::Data::AssetBus::MultiHandler::BusConnect(entry.first);
AZ::Data::AssetManager::Instance().GetAsset(entry.first, entry.second, AZ::Data::AssetLoadBehavior::Default);
m_pendingAssets[entry.first] = AZ::Data::AssetManager::Instance().GetAsset(entry.first, entry.second, AZ::Data::AssetLoadBehavior::Default);
}
}
}
@@ -394,28 +364,28 @@ namespace ScriptCanvasEditor
void ScriptCanvasRootPaletteTreeItem::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
{
auto scriptEventIter = m_scriptEventElementTreeItems.find(assetId.m_guid);
if (scriptEventIter != m_scriptEventElementTreeItems.end())
{
RequestAssetLoad(assetId, azrtti_typeid<ScriptEvents::ScriptEventsAsset>());
}
else
{
AZ::Data::AssetType assetType = azrtti_typeid<ScriptCanvasFunctionAsset>();
auto elementIter = m_globalFunctionTreeItems.find(assetId.m_guid);
if (m_runtimeAssets.count(assetId) > 0)
auto functionIter = m_globalFunctionTreeItems.find(assetId);
if (functionIter != m_globalFunctionTreeItems.end())
{
assetType = azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>();
}
if (elementIter != m_globalFunctionTreeItems.end())
{
RequestAssetLoad(assetId, assetType);
RequestAssetLoad(assetId, azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>());
}
}
}
void ScriptCanvasRootPaletteTreeItem::OnCatalogAssetAdded(const AZ::Data::AssetId&)
{
}
void ScriptCanvasRootPaletteTreeItem::OnCatalogAssetRemoved(const AZ::Data::AssetId&, const AZ::Data::AssetInfo&)
{
}
void ScriptCanvasRootPaletteTreeItem::OnUpgradeStart()
{
DisconnectLambdas();
@@ -450,15 +420,20 @@ namespace ScriptCanvasEditor
{
// Delay handling loads until the top of the next tick in case we are handling this on an asset callback thread to avoid potential deadlocks.
AZ::SystemTickBus::Handler::BusConnect();
m_queuedLoads.emplace_back(AZStd::make_pair(assetId, assetType));
m_requestQueue.emplace(AZStd::make_pair(assetId, assetType));
}
void ScriptCanvasRootPaletteTreeItem::OnAssetError(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
// mark the function on error... if possible
AZ::Data::AssetId assetId = asset.GetId();
m_pendingAssets.erase(assetId);
}
void ScriptCanvasRootPaletteTreeItem::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
AZ::Data::AssetId assetId = asset.GetId();
m_pendingAssets.erase(AZStd::make_pair(assetId, asset.GetType()));
AZ::Data::AssetBus::MultiHandler::BusDisconnect(assetId);
m_pendingAssets.erase(assetId);
if (asset.GetType() == azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
{
@@ -480,125 +455,193 @@ namespace ScriptCanvasEditor
}
else if (asset.GetType() == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
ScriptCanvas::SubgraphInterfaceAsset* data = asset.GetAs<ScriptCanvas::SubgraphInterfaceAsset>();
AZStd::string rootPath, absolutePath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
AZ::Data::AssetId sourceAssetId;
AZStd::string normPath = absolutePath;
AzFramework::StringFunc::Path::Normalize(normPath);
AZStd::string watchFolder;
bool sourceInfoFound{};
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, normPath.c_str(), assetInfo, watchFolder);
if (!sourceInfoFound)
{
// TODO-LS: report the problem
return;
}
sourceAssetId = assetInfo.m_assetId;
AZ::Data::AssetId runtimeAssetId = asset.GetId();
if (m_runtimeAssets.count(runtimeAssetId) == 0)
{
m_runtimeAssets.insert(runtimeAssetId);
auto treePaletteIter = m_globalFunctionTreeItems.find(sourceAssetId.m_guid);
if (treePaletteIter == m_globalFunctionTreeItems.end())
{
CreateFunctionPaletteItem(data->m_runtimeData.m_name, assetInfo, sourceAssetId, runtimeAssetId);
}
else
{
treePaletteIter->second->SetRuntimeAssetId(runtimeAssetId);
treePaletteIter->second->ClearError();
}
}
}
else if (asset.GetType() == azrtti_typeid<ScriptCanvasFunctionAsset>())
{
ScriptCanvasFunctionAsset* data = asset.GetAs<ScriptCanvasFunctionAsset>();
AZStd::string rootPath, absolutePath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
AZ::Data::AssetId sourceAssetId;
AZStd::string normPath = absolutePath;
AzFramework::StringFunc::Path::Normalize(normPath);
AZStd::string watchFolder;
bool sourceInfoFound{};
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, normPath.c_str(), assetInfo, watchFolder);
if (!sourceInfoFound)
{
return;
}
sourceAssetId = assetInfo.m_assetId;
// We only need to add
auto treePaletteIter = m_globalFunctionTreeItems.find(sourceAssetId.m_guid);
// We only need to add
auto treePaletteIter = m_globalFunctionTreeItems.find(asset->GetId());
if (treePaletteIter == m_globalFunctionTreeItems.end())
{
CreateFunctionPaletteItem(data->GetFunctionData()->GetPrettyName(), assetInfo, sourceAssetId);
ScriptCanvas::SubgraphInterfaceAsset* data = asset.GetAs<ScriptCanvas::SubgraphInterfaceAsset>();
if (!data)
{
return;
}
treePaletteIter = m_globalFunctionTreeItems.find(sourceAssetId.m_guid);
if (!data->m_runtimeData.m_interface.HasAnyFunctionality())
{
// check for deleting the old entry
return;
}
AZStd::string rootPath, absolutePath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
AZStd::string normPath = absolutePath;
AzFramework::StringFunc::Path::Normalize(normPath);
AZStd::string watchFolder;
bool sourceInfoFound{};
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, normPath.c_str(), assetInfo, watchFolder);
if (!sourceInfoFound)
{
return;
}
CreateFunctionPaletteItem(asset, assetInfo);
treePaletteIter = m_globalFunctionTreeItems.find(asset->GetId());
if (treePaletteIter != m_globalFunctionTreeItems.end())
{
treePaletteIter->second->SetError("Function has errors and cannot be created until these errors are resolved.");
treePaletteIter->second->ClearError();
}
m_monitoredAssets.emplace(asset->GetId(), asset);
}
else
{
RequestBuildChildrenFromSubgraphInterface(treePaletteIter->second, asset);
treePaletteIter->second->ClearError();
}
}
}
void ScriptCanvasRootPaletteTreeItem::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
OnAssetReady(asset);
}
bool ScriptCanvasRootPaletteTreeItem::HasAssetTreeItem(AZ::Data::AssetId assetId) const
{
return m_scriptEventElementTreeItems.find(assetId) != m_scriptEventElementTreeItems.end()
|| m_globalFunctionTreeItems.find(assetId) != m_globalFunctionTreeItems.end();
}
void ScriptCanvasRootPaletteTreeItem::CreateFunctionPaletteItem(const AZStd::string& displayName, const AZ::Data::AssetInfo& assetInfo, const AZ::Data::AssetId& sourceId, const AZ::Data::AssetId& runtimeId)
void ScriptCanvasRootPaletteTreeItem::CreateFunctionPaletteItem(AZ::Data::Asset<AZ::Data::AssetData> asset, const AZ::Data::AssetInfo& assetInfo)
{
ScriptCanvas::SubgraphInterfaceAsset* data = asset.GetAs<ScriptCanvas::SubgraphInterfaceAsset>();
if (!data)
{
return;
}
const ScriptCanvas::Grammar::SubgraphInterface& graphInterface = data->m_runtimeData.m_interface;
if (!graphInterface.HasAnyFunctionality())
{
return;
}
AZStd::string name;
AzFramework::StringFunc::Path::GetFileName(assetInfo.m_relativePath.c_str(), name);
AZStd::string prettyName = displayName;
AZStd::string category = "User Functions";
AZStd::string category = "Global Functions";
AZStd::string relativePath;
if (AzFramework::StringFunc::Path::GetFolderPath(assetInfo.m_relativePath.c_str(), relativePath))
{
AZStd::to_lower(relativePath.begin(), relativePath.end());
const AZStd::string root = "scriptcanvas/functions/";
if (relativePath.starts_with(root))
auto stripPathStart = [&](const AZStd::string root)
{
relativePath = relativePath.substr(root.size(), relativePath.size() - root.size());
}
if (relativePath.starts_with(root))
{
relativePath = relativePath.substr(root.size(), relativePath.size() - root.size());
}
};
stripPathStart("scriptcanvas/functions");
stripPathStart("scriptcanvas");
stripPathStart("/");
category.append("/");
category.append(relativePath);
}
GraphCanvas::NodePaletteTreeItem* categoryRoot = GetCategoryNode(category.c_str());
FunctionPaletteTreeItem* treeItem = categoryRoot->CreateChildNode<FunctionPaletteTreeItem>(prettyName.empty() ? name.c_str() : prettyName.c_str(), sourceId, runtimeId);
NodePaletteTreeItem* categoryRoot = GetCategoryNode(category.c_str());
auto functionCategory = categoryRoot->CreateChildNode<NodePaletteTreeItem>(name.c_str(), ScriptCanvasEditor::AssetEditorId);
RequestBuildChildrenFromSubgraphInterface(functionCategory, asset);
m_globalFunctionTreeItems[asset->GetId()] = functionCategory;
categoryRoot->SetEnabled(true);
}
if (treeItem)
void ScriptCanvasRootPaletteTreeItem::RequestBuildChildrenFromSubgraphInterface(NodePaletteTreeItem* functionCategory, AZ::Data::Asset<AZ::Data::AssetData> asset)
{
functionCategory->ClearChildren();
ScriptCanvas::SubgraphInterfaceAsset* data = asset.GetAs<ScriptCanvas::SubgraphInterfaceAsset>();
if (!data)
{
m_globalFunctionTreeItems[sourceId.m_guid] = treeItem;
treeItem->SetEnabled(!m_isFunctionGraphActive);
return;
}
const ScriptCanvas::Grammar::SubgraphInterface& graphInterface = data->m_runtimeData.m_interface;
if (!graphInterface.HasAnyFunctionality())
{
return;
}
auto parent = functionCategory;
parent->SetEnabled(true);
if (graphInterface.IsUserNodeable())
{
auto name = functionCategory->GetName().toUtf8().constData();
parent = parent->CreateChildNode<FunctionPaletteTreeItem>(AZStd::string::format("%s Node", name).c_str(), ScriptCanvas::Grammar::MakeFunctionSourceIdNodeable(), asset);
parent->SetEnabled(true);
}
if (graphInterface.IsMarkedPure())
{
for (auto& in : graphInterface.GetIns())
{
auto childNode = parent->CreateChildNode<FunctionPaletteTreeItem>(in.displayName.c_str(), in.sourceID, asset);
childNode->SetEnabled(true);
}
}
else
{
auto& ins = graphInterface.GetIns();
AZStd::vector<const ScriptCanvas::Grammar::In*> onNodeIns;
AZStd::vector<const ScriptCanvas::Grammar::In*> pureIns;
auto onNodeParent = parent;
auto pureParent = functionCategory;
for (auto& in : ins)
{
if (in.isPure)
{
pureIns.push_back(&in);
}
else
{
onNodeIns.push_back(&in);
}
}
if (!onNodeIns.empty())
{
parent->SetEnabled(true);
for (auto in : onNodeIns)
{
auto childNode = parent->CreateChildNode<NodePaletteTreeItem>(in->displayName.c_str(), ScriptCanvasEditor::AssetEditorId);
childNode->SetEnabled(true);
}
}
if (!pureIns.empty())
{
parent = pureParent->CreateChildNode<NodePaletteTreeItem>("Pure Functions", ScriptCanvasEditor::AssetEditorId);
parent->SetEnabled(true);
for (auto in : pureIns)
{
auto childNode = parent->CreateChildNode<FunctionPaletteTreeItem>(in->displayName.c_str(), in->sourceID, asset);
childNode->SetEnabled(true);
}
}
}
}
@@ -643,9 +686,6 @@ namespace ScriptCanvasEditor
auto scriptEventAction = creationMenu->addAction("New Script Event");
QObject::connect(scriptEventAction, &QAction::triggered, this, &NodePaletteDockWidget::OnNewCustomEvent);
auto functionAction = creationMenu->addAction("New Function");
QObject::connect(functionAction, &QAction::triggered, this, &NodePaletteDockWidget::OnNewFunctionEvent);
m_newCustomEvent = new QToolButton(this);
m_newCustomEvent->setIcon(QIcon(":/ScriptCanvasEditorResources/Resources/add.png"));
m_newCustomEvent->setToolTip("Click to create a new Script Event or Function");
@@ -696,11 +736,6 @@ namespace ScriptCanvasEditor
AzToolsFramework::AssetEditor::AssetEditorRequestsBus::Broadcast(&AzToolsFramework::AssetEditor::AssetEditorRequests::CreateNewAsset, azrtti_typeid<ScriptEvents::ScriptEventsAsset>());
}
void NodePaletteDockWidget::OnNewFunctionEvent()
{
GeneralRequestBus::Broadcast(&GeneralRequests::CreateNewFunctionAsset);
}
void NodePaletteDockWidget::OnActiveGraphChanged(const GraphCanvas::GraphId& graphCanvasGraphId)
{
GraphCanvas::SceneNotificationBus::Handler::BusDisconnect();
@@ -89,7 +89,9 @@ namespace ScriptCanvasEditor
////
// AssetCatalogEventBus
void OnCatalogAssetChanged(const AZ::Data::AssetId& /*assetId*/) override;
void OnCatalogAssetChanged(const AZ::Data::AssetId&) override;
void OnCatalogAssetAdded(const AZ::Data::AssetId&) override;
void OnCatalogAssetRemoved(const AZ::Data::AssetId&, const AZ::Data::AssetInfo&) override;
////
// UpgradeNotifications::Bus
@@ -104,30 +106,35 @@ namespace ScriptCanvasEditor
// Requests an async load of a given asset of a type
void RequestAssetLoad(AZ::Data::AssetId assetId, AZ::Data::AssetType assetType);
// When the asset loading is ready, this allows to use the asset in some meaningful way
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetError(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
bool HasAssetTreeItem(AZ::Data::AssetId assetId) const;
void CreateFunctionPaletteItem(const AZStd::string& displayName, const AZ::Data::AssetInfo& assetInfo, const AZ::Data::AssetId& sourceId, const AZ::Data::AssetId& runtimeId = {});
void CreateFunctionPaletteItem(AZ::Data::Asset<AZ::Data::AssetData> asset, const AZ::Data::AssetInfo& assetInfo);
void RequestBuildChildrenFromSubgraphInterface(NodePaletteTreeItem* item, AZ::Data::Asset<AZ::Data::AssetData> asset);
const NodePaletteModel& m_nodePaletteModel;
AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_assetModel;
GraphCanvas::GraphCanvasTreeCategorizer m_categorizer;
bool m_isFunctionGraphActive;
AZ::Data::AssetId m_previousAssetId;
AZStd::unordered_map< AZ::Data::AssetId, ScriptEventsPaletteTreeItem* > m_scriptEventElementTreeItems;
AZStd::unordered_set< AZ::Data::AssetId > m_runtimeAssets;
AZStd::unordered_map< AZ::Data::AssetId, FunctionPaletteTreeItem* > m_globalFunctionTreeItems;
AZStd::unordered_map< AZ::Data::AssetId, GraphCanvas::NodePaletteTreeItem*> m_globalFunctionTreeItems;
AZStd::vector< AZStd::pair<AZ::Data::AssetId, AZ::Data::AssetType>> m_queuedLoads;
AZStd::queue<AZStd::pair<AZ::Data::AssetId, AZ::Data::AssetType>> m_requestQueue;
// RequestAssetLoad uses this set to track assets being asynchronously loaded
AZStd::unordered_set<AZStd::pair<AZ::Data::AssetId, AZ::Data::AssetType>> m_pendingAssets;
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::Data::AssetData>> m_pendingAssets;
AZStd::unordered_map< AZ::Data::AssetId, AZ::Data::Asset<AZ::Data::AssetData>> m_monitoredAssets;
AZStd::vector< QMetaObject::Connection > m_lambdaConnections;
};
@@ -40,8 +40,20 @@
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
namespace ScriptCanvasEditor
{
const char* GraphVariablesModel::m_columnNames[static_cast<int>(ColumnIndex::Count)] =
{
"Name",
"Type",
"Default Value",
"Scope",
"Initial Value"
};
////////////////////////
// GraphVariablesModel
////////////////////////
@@ -137,6 +149,16 @@ namespace ScriptCanvasEditor
return ScriptCanvas::VariableFlags::GetScopeDisplayLabel(graphVariable->GetScope());
}
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
if (graphVariable)
{
return graphVariable->GetInitialValueSourceName().data();
}
}
}
break;
@@ -232,6 +254,16 @@ namespace ScriptCanvasEditor
return ScriptCanvas::VariableFlags::GetScopeDisplayLabel(graphVariable->GetScope());
}
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
if (graphVariable)
{
return graphVariable->GetInitialValueSourceName().data();
}
}
}
break;
@@ -281,6 +313,19 @@ namespace ScriptCanvasEditor
return QVariant(type.c_str());
}
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
QString tooltipString = QString("The value of this variable can only be set within this graph");
if (graphVariable->GetInitialValueSource() == ScriptCanvas::VariableFlags::InitialValueSource::Component)
{
tooltipString = QString("The value of this variable can be set set on the component's properties");
}
return tooltipString;
}
else
{
AZStd::string variableName;
@@ -296,6 +341,7 @@ namespace ScriptCanvasEditor
return tooltipString;
}
}
break;
case Qt::DecorationRole:
@@ -381,22 +427,17 @@ namespace ScriptCanvasEditor
{
if (index.column() == ColumnIndex::Scope)
{
if (IsFunction())
{
return QStringList{
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Local),
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Input),
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Output),
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::InOut)
};
}
else
{
return QStringList{
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Local),
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Input)
};
}
return QStringList{
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Graph),
ScriptCanvas::VariableFlags::GetScopeDisplayLabel(ScriptCanvas::VariableFlags::Scope::Function)
};
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
return QStringList{
tr(ScriptCanvas::GraphVariable::s_InitialValueSourceNames[0]),
tr(ScriptCanvas::GraphVariable::s_InitialValueSourceNames[1])
};
}
}
break;
@@ -496,22 +537,25 @@ namespace ScriptCanvasEditor
}
}
else if (index.column() == ColumnIndex::Scope)
{
// Scope is not changed by users
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
if (graphVariable)
{
QString exposureValue = value.toString();
QString comboBoxValue = value.toString();
if (!exposureValue.isEmpty())
if (!comboBoxValue.isEmpty())
{
ScriptCanvas::VariableFlags::Scope newScope = ScriptCanvas::VariableFlags::GetScopeFromLabel(exposureValue.toUtf8().data());
if (graphVariable->GetScope() != newScope)
if (graphVariable->GetInitialValueSourceName().compare(comboBoxValue.toUtf8().data()) != 0)
{
modifiedData = true;
graphVariable->SetScope(newScope);
graphVariable->SetInitialValueSourceFromName(comboBoxValue.toUtf8().data());
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestRefresh, AzToolsFramework::Refresh_EntireTree);
}
}
}
@@ -563,8 +607,11 @@ namespace ScriptCanvasEditor
}
else if (index.column() == ColumnIndex::Scope)
{
// Disabling the editing column temporarily, since the combo box doesn't work.
//itemFlags |= Qt::ItemIsEditable;
itemFlags |= Qt::ItemIsEditable;
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
itemFlags |= Qt::ItemIsEditable;
}
return itemFlags;
@@ -778,6 +825,19 @@ namespace ScriptCanvasEditor
}
}
void GraphVariablesModel::OnVariableInitialValueSourceChanged()
{
const ScriptCanvas::GraphScopedVariableId* variableId = ScriptCanvas::VariableNotificationBus::GetCurrentBusId();
int index = FindRowForVariableId((*variableId).m_identifier);
if (index >= 0)
{
QModelIndex modelIndex = createIndex(index, ColumnIndex::InitialValueSource, nullptr);
dataChanged(modelIndex, modelIndex);
}
}
void GraphVariablesModel::OnVariablePriorityChanged()
{
const ScriptCanvas::GraphScopedVariableId* variableId = ScriptCanvas::VariableNotificationBus::GetCurrentBusId();
@@ -793,6 +853,16 @@ namespace ScriptCanvasEditor
}
}
QVariant GraphVariablesModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole*/) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
return tr(m_columnNames[section]);
}
return QAbstractItemModel::headerData(section, orientation, role);
}
ScriptCanvas::VariableId GraphVariablesModel::FindVariableIdForIndex(const QModelIndex& index) const
{
ScriptCanvas::VariableId variableId;
@@ -977,20 +1047,7 @@ namespace ScriptCanvasEditor
for (auto variableMapData : copiedVariableData.m_variableMapping)
{
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> variableOutcome = requests->CloneVariable(variableMapData.second);
if (isRuntimeGraph)
{
if (variableOutcome)
{
ScriptCanvas::GraphVariable* variable = requests->FindVariableById(variableOutcome.GetValue());
if (variable)
{
variable->RemoveScope(ScriptCanvas::VariableFlags::Scope::Output);
}
}
}
requests->CloneVariable(variableMapData.second);
}
GeneralRequestBus::Broadcast(&GeneralRequests::PopPreventUndoStateUpdate);
@@ -1015,12 +1072,15 @@ namespace ScriptCanvasEditor
ApplyPreferenceSort();
setItemDelegateForColumn(GraphVariablesModel::Name, aznew GraphCanvas::IconDecoratedNameDelegate(this));
setItemDelegateForColumn(GraphVariablesModel::Scope, aznew GraphCanvas::GenericComboBoxDelegate(this));
setItemDelegateForColumn(GraphVariablesModel::InitialValueSource, aznew GraphCanvas::GenericComboBoxDelegate(this));
horizontalHeader()->setStretchLastSection(false);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Type, QHeaderView::ResizeMode::Fixed);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Name, QHeaderView::ResizeMode::Stretch);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::DefaultValue, QHeaderView::ResizeMode::Fixed);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Scope, QHeaderView::ResizeMode::Fixed);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Name, QHeaderView::ResizeMode::ResizeToContents);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::DefaultValue, QHeaderView::ResizeMode::ResizeToContents);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Type, QHeaderView::ResizeMode::Stretch);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::Scope, QHeaderView::ResizeMode::Stretch);
horizontalHeader()->setSectionResizeMode(GraphVariablesModel::InitialValueSource, QHeaderView::ResizeMode::Stretch);
horizontalHeader()->show();
{
QAction* deleteAction = new QAction(this);
@@ -1229,16 +1289,18 @@ namespace ScriptCanvasEditor
horizontalHeader()->resizeSection(GraphVariablesModel::Type, typeLength);
horizontalHeader()->resizeSection(GraphVariablesModel::DefaultValue, defaultValueLength);
int exposureLength = aznumeric_cast<int>(availableWidth * 0.2f);
int maxExposureLength = 60;
if (exposureLength >= 60)
horizontalHeader()->resizeSection(GraphVariablesModel::Scope, 100);
int remainingLength = aznumeric_cast<int>(availableWidth * 0.1f);
int maxExposureLength = 80;
if (remainingLength >= maxExposureLength)
{
exposureLength = 60;
remainingLength = maxExposureLength;
}
horizontalHeader()->resizeSection(GraphVariablesModel::Scope, exposureLength);
horizontalHeader()->resizeSection(GraphVariablesModel::InitialValueSource, 120);
}
void GraphVariablesTableView::OnCopySelected()
@@ -45,9 +45,12 @@ namespace ScriptCanvasEditor
Type,
DefaultValue,
Scope,
InitialValueSource,
Count
};
static const char* m_columnNames[static_cast<int>(ColumnIndex::Count)];
enum CustomRole
{
VarIdRole = Qt::UserRole
@@ -84,9 +87,13 @@ namespace ScriptCanvasEditor
// ScriptCanvas::VariableRuntimeNotificationBus
void OnVariableValueChanged() override;
void OnVariableScopeChanged() override;
void OnVariableInitialValueSourceChanged() override;
void OnVariablePriorityChanged() override;
////
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
ScriptCanvas::VariableId FindVariableIdForIndex(const QModelIndex& index) const;
ScriptCanvas::GraphScopedVariableId FindScopedVariableIdForIndex(const QModelIndex& index) const;
@@ -0,0 +1,233 @@
/*
* 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 <QAction>
#include <QCompleter>
#include <QEvent>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <QScopedValueRollback>
#include <QLineEdit>
#include <QTimer>
#include <QPushButton>
#include <QHeaderView>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/Entity/EditorEntityContextPickingBus.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <GraphCanvas/Components/VisualBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/StyleBus.h>
#include <Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.h>
#include <Editor/View/Widgets/VariablePanel/ui_SlotTypeSelectorWidget.h>
#include <Data/Data.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/QtMetaTypes.h>
#include <Editor/Settings.h>
#include <Editor/Translation/TranslationHelper.h>
#include <Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.h>
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/PropertyGridBus.h>
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <Editor/Include/ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
namespace ScriptCanvasEditor
{
///////////////////////
// SlotTypeSelectorWidget
///////////////////////
SlotTypeSelectorWidget::SlotTypeSelectorWidget(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, QWidget* parent /*= nullptr*/)
: AzQtComponents::StyledDialog(parent)
, m_manipulatingSelection(false)
, ui(new Ui::SlotTypeSelectorWidget())
, m_scriptCanvasId(scriptCanvasId)
{
ui->setupUi(this);
ui->searchFilter->setClearButtonEnabled(true);
QObject::connect(ui->searchFilter, &QLineEdit::textChanged, this, &SlotTypeSelectorWidget::OnQuickFilterChanged);
QObject::connect(ui->slotName, &QLineEdit::returnPressed, this, &SlotTypeSelectorWidget::OnReturnPressed);
QObject::connect(ui->slotName, &QLineEdit::textChanged, this, &SlotTypeSelectorWidget::OnNameChanged);
QObject::connect(ui->variablePalette, &QTableView::clicked, this, [this]() { ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); });
// Tell the widget to auto create our context menu, for now
setContextMenuPolicy(Qt::ActionsContextMenu);
ui->searchFilter->setEnabled(true);
QObject::connect(ui->variablePalette, &VariablePaletteTableView::CreateVariable, this, &SlotTypeSelectorWidget::OnCreateVariable);
m_filterTimer.setInterval(250);
m_filterTimer.setSingleShot(true);
m_filterTimer.stop();
QObject::connect(&m_filterTimer, &QTimer::timeout, this, &SlotTypeSelectorWidget::UpdateFilter);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
SlotTypeSelectorWidget::~SlotTypeSelectorWidget()
{
}
void SlotTypeSelectorWidget::PopulateVariablePalette(const AZStd::unordered_set< AZ::Uuid >& objectTypes)
{
ui->variablePalette->PopulateVariablePalette(objectTypes);
}
void SlotTypeSelectorWidget::OnEscape()
{
reject();
}
void SlotTypeSelectorWidget::focusOutEvent(QFocusEvent* )
{
reject();
}
const ScriptCanvas::ScriptCanvasId& SlotTypeSelectorWidget::GetActiveScriptCanvasId() const
{
return m_scriptCanvasId;
}
void SlotTypeSelectorWidget::ShowVariablePalette()
{
ClearFilter();
ui->searchFilter->setPlaceholderText("Variable Type...");
FocusOnSearchFilter();
ui->searchFilter->setCompleter(ui->variablePalette->GetVariableCompleter());
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
}
void SlotTypeSelectorWidget::FocusOnSearchFilter()
{
ui->searchFilter->setFocus(Qt::FocusReason::MouseFocusReason);
}
void SlotTypeSelectorWidget::ClearFilter()
{
{
QSignalBlocker blocker(ui->searchFilter);
ui->searchFilter->setText("");
}
UpdateFilter();
}
void SlotTypeSelectorWidget::UpdateFilter()
{
ui->variablePalette->SetFilter(ui->searchFilter->userInputText());
}
void SlotTypeSelectorWidget::OnReturnPressed()
{
// Set the type to the slot
if (!m_selectedType.IsNull())
{
m_slotName = ui->slotName->text().toUtf8().data();
accept();
}
}
AZ::Uuid SlotTypeSelectorWidget::GetSelectedType() const
{
return m_selectedType;
}
AZStd::string SlotTypeSelectorWidget::GetSlotName() const
{
return m_slotName;
}
void SlotTypeSelectorWidget::SetSlotName(AZStd::string name)
{
m_slotName = name;
ui->slotName->setText(QString(name.c_str()));
}
void SlotTypeSelectorWidget::OnQuickFilterChanged(const QString& text)
{
if (text.isEmpty())
{
//If field was cleared, update immediately
UpdateFilter();
return;
}
m_filterTimer.stop();
m_filterTimer.start();
}
void SlotTypeSelectorWidget::OnNameChanged(const QString& text)
{
bool nameInUse = false;
const AZStd::unordered_map<ScriptCanvas::VariableId, ScriptCanvas::GraphVariable>* properties = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(properties, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::GetVariables);
if (properties)
{
for (const auto& variablePair : (*properties))
{
AZStd::string testName = text.toUtf8().data();
if (testName.compare(variablePair.second.GetVariableName()) == 0)
{
nameInUse = true;
break;
}
}
}
m_slotName = text.toUtf8().data();
if (nameInUse)
{
m_slotName.append(" (duplicate)");
ui->slotName->setText(m_slotName.c_str());
}
}
void SlotTypeSelectorWidget::OnContextMenuRequested(const QPoint&)
{
}
void SlotTypeSelectorWidget::OnCreateVariable(ScriptCanvas::Data::Type varType)
{
m_selectedType = varType.GetAZType();
}
#include <Editor/View/Widgets/VariablePanel/moc_SlotTypeSelectorWidget.cpp>
}
@@ -0,0 +1,131 @@
/*
* 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>
#include <QAbstractListModel>
#include <QAbstractItemView>
#include <QListView>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QTimer>
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
#include <QFocusEvent>
#include <QMenu>
#include <AzCore/Component/EntityId.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzQtComponents/Components/StyledDialog.h>
#include <GraphCanvas/Editor/AssetEditorBus.h>
#include <GraphCanvas/Components/GraphCanvasPropertyBus.h>
#include <GraphCanvas/Components/SceneBus.h>
#include <GraphCanvas/Components/Nodes/NodeBus.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <GraphCanvas/Widgets/GraphCanvasTreeItem.h>
#include <GraphCanvas/Widgets/GraphCanvasTreeModel.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Variable/VariableBus.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <Editor/View/Widgets/VariablePanel/VariablePaletteTableView.h>
#include <Editor/View/Widgets/VariablePanel/GraphVariablesTableView.h>
#endif
class QAction;
class QLineEdit;
class QPushButton;
namespace Ui
{
class SlotTypeSelectorWidget;
}
namespace ScriptCanvasEditor
{
class SlotTypeSelectorWidget
: public AzQtComponents::StyledDialog
, public AzToolsFramework::EditorEvents::Bus::Handler
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(SlotTypeSelectorWidget, AZ::SystemAllocator, 0);
SlotTypeSelectorWidget(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, QWidget* parent = nullptr);
~SlotTypeSelectorWidget();
void PopulateVariablePalette(const AZStd::unordered_set< AZ::Uuid >& objectTypes);
// AzToolsFramework::EditorEvents::Bus
void OnEscape() override;
////
// QWidget
void focusOutEvent(QFocusEvent* focusEvent) override;
////
AZ::Uuid GetSelectedType() const;
AZStd::string GetSlotName() const;
void SetSlotName(AZStd::string);
const ScriptCanvas::ScriptCanvasId& GetActiveScriptCanvasId() const;
public Q_SLOTS:
void OnCreateVariable(ScriptCanvas::Data::Type varType);
Q_SIGNALS:
void OnVariableSelectionChanged(const AZStd::vector<AZ::EntityId>& variableIds);
private:
void ShowVariablePalette();
void FocusOnSearchFilter();
void ClearFilter();
void UpdateFilter();
void OnReturnPressed();
void OnQuickFilterChanged(const QString& text);
void OnNameChanged(const QString& text);
void OnContextMenuRequested(const QPoint& pos);
//bool event(QEvent* ev) override;
bool m_manipulatingSelection;
AZStd::vector< AZStd::unique_ptr<AZ::Entity> > m_propertyHelpers;
ScriptCanvas::ScriptCanvasId m_scriptCanvasId;
AZ::EntityId m_graphCanvasGraphId;
AZ::Uuid m_selectedType;
AZStd::string m_slotName;
AZStd::unique_ptr<Ui::SlotTypeSelectorWidget> ui;
QTimer m_filterTimer;
};
}
@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SlotTypeSelectorWidget</class>
<widget class="QWidget" name="SlotTypeSelectorWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>278</width>
<height>316</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Pick slot name/type</string>
</property>
<property name="floating" stdset="0">
<bool>false</bool>
</property>
<widget class="QWidget" name="widgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>278</width>
<height>278</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>30</number>
</property>
<item>
<widget class="AzQtComponents::SearchLineEdit" name="searchFilter">
<property name="inputMask">
<string/>
</property>
<property name="placeholderText">
<string>Search...</string>
</property>
</widget>
</item>
<item>
<widget class="ScriptCanvasEditor::VariablePaletteTableView" name="variablePalette">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLineEdit" name="slotName">
<property name="placeholderText">
<string>Type the name for your slot here...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>AzQtComponents::SearchLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">AzQtComponents/Components/SearchLineEdit.h</header>
</customwidget>
<customwidget>
<class>ScriptCanvasEditor::VariablePaletteTableView</class>
<extends>QTableView</extends>
<header location="global">Editor/View/Widgets/VariablePanel/VariablePaletteTableView.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SlotTypeSelectorWidget</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>77</x>
<y>294</y>
</hint>
<hint type="destinationlabel">
<x>7</x>
<y>296</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SlotTypeSelectorWidget</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -117,7 +117,7 @@ namespace ScriptCanvasEditor
{
if (variable)
{
ScriptCanvas::VariableNotificationBus::Handler::BusDisconnect();
ScriptCanvas::VariableNotificationBus::Handler::BusDisconnect();
m_variable = variable;
m_componentTitle.clear();
@@ -180,6 +180,7 @@ namespace ScriptCanvasEditor
{
GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, m_scriptCanvasGraphId);
PropertyGridRequestBus::Broadcast(&PropertyGridRequests::RefreshPropertyGrid);
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
}
void VariablePropertiesComponent::OnVariableRenamed(AZStd::string_view variableName)
@@ -292,6 +293,8 @@ namespace ScriptCanvasEditor
dockWidget->OnDeleteVariables(variableIds);
});
addAction(getAction);
addAction(setAction);
addSeparator();
@@ -299,56 +302,6 @@ namespace ScriptCanvasEditor
addAction(pasteAction);
addAction(duplicateAction);
addAction(deleteAction);
addSeparator();
// Setup exposure options
ScriptCanvas::GraphScopedVariableId variableId;
variableId.m_scriptCanvasId = scriptCanvasId;
variableId.m_identifier = varId;
ScriptCanvas::GraphVariable* variable = nullptr;
ScriptCanvas::VariableRequestBus::EventResult(variable, variableId, &ScriptCanvas::VariableRequests::GetVariable);
AZ_Assert(variable, "The variable must exist at this point");
AZ::Data::AssetType assetType;
AssetTrackerRequestBus::BroadcastResult(assetType, &AssetTrackerRequests::GetAssetType, scriptCanvasId);
// Exposing variables is only available for Function assets
QMenu* scopeSubMenu = new QMenu(QObject::tr("Scope"), this);
QActionGroup* actionGroup = new QActionGroup(scopeSubMenu);
actionGroup->setExclusive(true);
AZStd::vector<ScriptCanvas::VariableFlags::Scope> scopes = { ScriptCanvas::VariableFlags::Scope::Local, ScriptCanvas::VariableFlags::Scope::Input };
if (assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset >())
{
scopes.emplace_back(ScriptCanvas::VariableFlags::Scope::Output);
scopes.emplace_back(ScriptCanvas::VariableFlags::Scope::InOut);
}
for (auto scopeType : scopes)
{
QAction* exposureAction = new QAction(QObject::tr(ScriptCanvas::VariableFlags::GetScopeDisplayLabel(scopeType)), this);
exposureAction->setCheckable(true);
exposureAction->setChecked(variable->GetScope() == scopeType);
exposureAction->setActionGroup(actionGroup);
exposureAction->setToolTip(QObject::tr(ScriptCanvas::VariableFlags::GetScopeToolTip(scopeType)));
QObject::connect(exposureAction, &QAction::triggered, this, [variableId, scopeType](bool)
{
ScriptCanvas::GraphVariable* variable = nullptr;
ScriptCanvas::VariableRequestBus::EventResult(variable, variableId, &ScriptCanvas::VariableRequests::GetVariable);
if (variable)
{
variable->SetScope(scopeType);
}
});
scopeSubMenu->addAction(exposureAction);
}
addMenu(scopeSubMenu);
}
///////////////////////
@@ -79,7 +79,7 @@
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
@@ -142,6 +142,8 @@
#include <Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.h>
#include <Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h>
#include <Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.h>
// Save Format Conversion
#include <AzCore/Component/EntityUtils.h>
#include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
@@ -160,6 +162,7 @@
#include <Editor/QtMetaTypes.h>
#include <GraphCanvas/Components/SceneBus.h>
namespace ScriptCanvasEditor
{
using namespace AzToolsFramework;
@@ -470,8 +473,6 @@ namespace ScriptCanvasEditor
scriptEventAssetFilter->SetAssetGroup(ScriptEvents::ScriptEventsAsset::GetGroup());
scriptEventAssetFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
// Filter doesn't actually work for whatever reason
//m_scriptEventsAssetModel->SetFilter(AzToolsFramework::AssetBrowser::FilterConstType(scriptEventAssetFilter));
m_scriptEventsAssetModel->setSourceModel(assetBrowserModel);
}
@@ -482,8 +483,6 @@ namespace ScriptCanvasEditor
scriptCanvasAssetFilter->SetAssetGroup(ScriptCanvasAsset::Description::GetGroup(azrtti_typeid<ScriptCanvasAsset>()));
scriptCanvasAssetFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
// Filter doesn't actually work for whatever reason
//m_scriptCanvasAssetModel->SetFilter(AzToolsFramework::AssetBrowser::FilterConstType(scriptCanvasAssetFilter));
m_scriptCanvasAssetModel->setSourceModel(assetBrowserModel);
}
@@ -537,14 +536,6 @@ namespace ScriptCanvasEditor
m_editorToolbar->AddCreationAction(m_createScriptCanvas);
RegisterObject(AutomationIds::CreateScriptCanvasButton, m_createScriptCanvas);
m_createFunction = new QToolButton();
m_createFunction->setIcon(QIcon(ScriptCanvas::AssetDescription::GetIconPath<ScriptCanvasFunctionAsset>()));
m_createFunction->setToolTip("Creates a new Script Canvas Function Graph");
QObject::connect(m_createFunction, &QToolButton::clicked, this, &MainWindow::OnFileNewFunction);
m_editorToolbar->AddCreationAction(m_createFunction);
RegisterObject(AutomationIds::CreateScriptCanvasFunctionButton, m_createFunction);
}
{
@@ -836,11 +827,6 @@ namespace ScriptCanvasEditor
connect(ui->action_New_Script, &QAction::triggered, this, &MainWindow::OnFileNew);
ui->action_New_Script->setShortcut(QKeySequence(QKeySequence::New));
connect(ui->actionFunction, &QAction::triggered, this, &MainWindow::OnFileNewFunction);
//ui->action_New_Function->setShortcut(QKeySequence(QKeySequence::New));
connect(ui->actionEditor_Graph, &QAction::triggered, this, &MainWindow::OnFileNewFunction);
connect(ui->action_Open, &QAction::triggered, this, &MainWindow::OnFileOpen);
ui->action_Open->setShortcut(QKeySequence(QKeySequence::Open));
@@ -969,7 +955,8 @@ namespace ScriptCanvasEditor
}
}
UpdateMenuState(enabled);
UpdateMenuState(enabled);
}
void MainWindow::UpdateRecentMenu()
@@ -1159,6 +1146,44 @@ namespace ScriptCanvasEditor
return m_variableDockWidget->IsValidVariableType(dataType);
}
bool MainWindow::ShowSlotTypeSelector(ScriptCanvas::Slot* slot, const QPoint& scenePosition, VariablePaletteRequests::SlotSetup& outSetup)
{
AZ_Assert(slot, "A valid slot must be provided");
if (slot)
{
m_slotTypeSelector = new SlotTypeSelectorWidget(GetActiveScriptCanvasId(), this); // Recreate the widget every time because of https://bugreports.qt.io/browse/QTBUG-76509
m_slotTypeSelector->PopulateVariablePalette(m_variablePaletteTypes);
// Only set the slot name if the user has already configured this slot, so if they are creating
// for the first time they will see the placeholder text instead
bool isValidVariableType = false;
VariablePaletteRequestBus::BroadcastResult(isValidVariableType, &VariablePaletteRequests::IsValidVariableType, slot->GetDataType());
if (isValidVariableType)
{
m_slotTypeSelector->SetSlotName(slot->GetName());
}
m_slotTypeSelector->move(scenePosition);
m_slotTypeSelector->setEnabled(true);
m_slotTypeSelector->update();
if (m_slotTypeSelector->exec() != QDialog::Rejected)
{
outSetup.m_name = m_slotTypeSelector->GetSlotName();
outSetup.m_type = m_slotTypeSelector->GetSelectedType();
}
else
{
return false;
}
delete m_slotTypeSelector;
}
return true;
}
void MainWindow::OpenValidationPanel()
{
if (!m_validationDockWidget->isVisible())
@@ -1736,11 +1761,6 @@ namespace ScriptCanvasEditor
MakeNewFile<ScriptCanvasAsset, ScriptCanvasAssetHandler>();
}
void MainWindow::OnFileNewFunction()
{
MakeNewFile<ScriptCanvasFunctionAsset, ScriptCanvasFunctionAssetHandler>();
}
int MainWindow::InsertTabForAsset(AZStd::string_view assetPath, AZ::Data::AssetId assetId, int tabIndex)
{
int outTabIndex = -1;
@@ -3598,14 +3618,12 @@ namespace ScriptCanvasEditor
ui->action_EnableSelection->setEnabled(enabled);
ui->action_DisableSelection->setEnabled(enabled);
m_createFunctionOutput->setEnabled(enabled);
m_createFunctionInput->setEnabled(enabled);
// File Menu
ui->action_Close->setEnabled(enabled);
bool isFunctionGraph = false;
EditorGraphRequestBus::EventResult(isFunctionGraph, GetActiveScriptCanvasId(), &EditorGraphRequests::IsFunctionGraph);
m_createFunctionInput->setEnabled(isFunctionGraph && enabled);
m_createFunctionOutput->setEnabled(isFunctionGraph && enabled);
RefreshGraphPreferencesAction();
UpdateAssignToSelectionState();
@@ -3715,7 +3733,7 @@ namespace ScriptCanvasEditor
void MainWindow::CreateFunctionInput()
{
PushPreventUndoStateUpdate();
CreateExecutionNodeling(-1);
CreateFunctionDefinitionNode(-1);
PopPreventUndoStateUpdate();
PostUndoPoint(GetActiveScriptCanvasId());
@@ -3724,13 +3742,13 @@ namespace ScriptCanvasEditor
void MainWindow::CreateFunctionOutput()
{
PushPreventUndoStateUpdate();
CreateExecutionNodeling(1);
CreateFunctionDefinitionNode(1);
PopPreventUndoStateUpdate();
PostUndoPoint(GetActiveScriptCanvasId());
}
void MainWindow::CreateExecutionNodeling(int positionOffset)
void MainWindow::CreateFunctionDefinitionNode(int positionOffset)
{
ScriptCanvas::ScriptCanvasId scriptCanvasId = GetActiveScriptCanvasId();
@@ -3742,14 +3760,9 @@ namespace ScriptCanvasEditor
QRectF viewBounds;
GraphCanvas::ViewRequestBus::EventResult(viewBounds, viewId, &GraphCanvas::ViewRequests::GetCompleteArea);
AZStd::string rootName = "New Output";
if (positionOffset < 0)
{
rootName = "New Input";
}
NodeIdPair nodeIdPair = Nodes::CreateExecutionNodeling(scriptCanvasId, rootName);
const bool isInput = positionOffset < 0;
const AZStd::string rootName = isInput ? "New Input" : "New Output";
NodeIdPair nodeIdPair = Nodes::CreateFunctionDefinitionNode(scriptCanvasId, isInput, rootName);
GraphCanvas::SceneRequests* sceneRequests = GraphCanvas::SceneRequestBus::FindFirstHandler(graphCanvasGraphId);
@@ -4151,6 +4164,13 @@ namespace ScriptCanvasEditor
contextMenu.AddMenuAction(aznew ConvertVariableNodeToReferenceAction(&contextMenu));
}
if (descriptorType == NodeDescriptorType::FunctionDefinitionNode)
{
NodeDescriptorComponent* descriptor = nullptr;
NodeDescriptorRequestBus::EventResult(descriptor, nodeId, &NodeDescriptorRequests::GetDescriptorComponent);
contextMenu.AddMenuAction(aznew RenameFunctionDefinitionNodeAction(descriptor, &contextMenu));
}
return HandleContextMenu(contextMenu, nodeId, screenPoint, scenePoint);
}
@@ -4276,6 +4296,7 @@ namespace ScriptCanvasEditor
contextMenu.AddMenuAction(aznew ConvertReferenceToVariableNodeAction(&contextMenu));
contextMenu.AddMenuAction(aznew ExposeSlotMenuAction(&contextMenu));
contextMenu.AddMenuAction(aznew CreateAzEventHandlerSlotMenuAction(&contextMenu));
contextMenu.AddMenuAction(aznew SetDataSlotTypeMenuAction(&contextMenu));
return HandleContextMenu(contextMenu, slotId, screenPoint, scenePoint);
}
@@ -4870,12 +4891,13 @@ namespace ScriptCanvasEditor
m_variableDockWidget->setEnabled(false);
m_propertyGrid->DisableGrid();
m_editorToolbar->OnViewDisabled();
m_createFunction->setEnabled(false);
m_createFunctionInput->setEnabled(false);
m_createFunctionOutput->setEnabled(false);
m_createScriptCanvas->setEnabled(false);
UpdateMenuState(false);
ui->action_New_Function->setEnabled(false);
ui->action_New_Script->setEnabled(false);
m_autoSaveTimer.stop();
@@ -4894,10 +4916,8 @@ namespace ScriptCanvasEditor
m_propertyGrid->EnableGrid();
m_editorToolbar->OnViewEnabled();
m_createFunction->setEnabled(true);
m_createScriptCanvas->setEnabled(true);
ui->action_New_Function->setEnabled(true);
ui->action_New_Script->setEnabled(true);
UpdateMenuState(true);
@@ -224,10 +224,12 @@ namespace ScriptCanvasEditor
class GraphValidationDockWidget;
class MainWindowStatusWidget;
class StatisticsDialog;
class SlotTypeSelectorWidget;
// Custom Context Menus
class SceneContextMenu;
class ConnectionContextMenu;
class RenameFunctionDefinitionNodeAction;
class MainWindow
: public QMainWindow
@@ -289,8 +291,8 @@ namespace ScriptCanvasEditor
// VariablePaletteRequestBus
void RegisterVariableType(const ScriptCanvas::Data::Type& variableType) override;
bool IsValidVariableType(const ScriptCanvas::Data::Type& dataType) const override;
bool ShowSlotTypeSelector(ScriptCanvas::Slot* slot, const QPoint& scenePosition, VariablePaletteRequests::SlotSetup&) override;
////
// GraphCanvas::AssetEditorRequestBus
@@ -334,7 +336,6 @@ namespace ScriptCanvasEditor
// File menu
void OnFileNew();
void OnFileNewFunction();
bool OnFileSave(const Callbacks::OnSave& saveCB);
bool OnFileSaveAs(const Callbacks::OnSave& saveCB);
@@ -451,7 +452,6 @@ namespace ScriptCanvasEditor
void RemoveScriptCanvasAsset(const AZ::Data::AssetId& assetId);
void OnChangeActiveGraphTab(AZ::Data::AssetId) override;
void CreateNewFunctionAsset() override { OnFileNewFunction(); }
void CreateNewRuntimeAsset() override { OnFileNew(); }
GraphCanvas::GraphId GetActiveGraphCanvasGraphId() const override;
@@ -614,7 +614,7 @@ namespace ScriptCanvasEditor
void CreateFunctionInput();
void CreateFunctionOutput();
void CreateExecutionNodeling(int positionOffset);
void CreateFunctionDefinitionNode(int positionOffset);
int CreateAssetTab(const AZ::Data::AssetId& assetId, int tabIndex = -1);
@@ -713,7 +713,6 @@ namespace ScriptCanvasEditor
QToolButton* m_createFunctionOutput = nullptr;
QToolButton* m_createScriptCanvas = nullptr;
QToolButton* m_createFunction = nullptr;
QMenu* m_selectedEntityMenu = nullptr;
@@ -728,6 +727,8 @@ namespace ScriptCanvasEditor
GraphCanvas::BookmarkDockWidget* m_bookmarkDockWidget = nullptr;
GraphCanvas::MiniMapDockWidget* m_minimap = nullptr;
LoggingWindow* m_loggingWindow = nullptr;
SlotTypeSelectorWidget* m_slotTypeSelector = nullptr;
AzQtComponents::WindowDecorationWrapper* m_presetWrapper = nullptr;
GraphCanvas::ConstructPresetDialog* m_presetEditor = nullptr;
@@ -15,12 +15,14 @@
#include <QApplication>
#include <QClipboard>
#include <QMimeData>
#include <QInputDialog>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Editor/Nodes/NodeUtils.h>
#include <Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.h>
#include <Editor/View/Widgets/VariablePanel/GraphVariablesTableView.h>
#include <Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
@@ -54,6 +56,8 @@
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/GraphCanvas/MappingBus.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <GraphCanvas/Components/NodeDescriptors/FunctionDefinitionNodeDescriptorComponent.h>
namespace ScriptCanvasEditor
{
//////////////////////////////
@@ -173,7 +177,7 @@ namespace ScriptCanvasEditor
}
ScriptCanvas::Slot* SlotManipulationMenuAction::GetScriptCanvasSlot(const GraphCanvas::Endpoint& endpoint) const
ScriptCanvas::Slot* SlotManipulationMenuAction::GetScriptCanvasSlot(const GraphCanvas::Endpoint& endpoint)
{
GraphCanvas::GraphId graphId;
GraphCanvas::SceneMemberRequestBus::EventResult(graphId, endpoint.GetNodeId(), &GraphCanvas::SceneMemberRequests::GetScene);
@@ -467,7 +471,12 @@ namespace ScriptCanvasEditor
GraphCanvas::NodeId nodeId;
GraphCanvas::SlotRequestBus::EventResult(nodeId, slotId, &GraphCanvas::SlotRequests::GetNode);
NodeIdPair nodePair = ScriptCanvasEditor::Nodes::CreateExecutionNodeling(scriptCanvasGraphId);
// Set the connection type for the node opposite of what it actually is because we're interested in the connection type of the node we're
// exposing, not the type of the slot we just created
ScriptCanvas::ConnectionType scriptCanvasConnectionType = (connectionType == GraphCanvas::CT_Input) ? ScriptCanvas::ConnectionType::Input : ScriptCanvas::ConnectionType::Output;
bool isInput = (scriptCanvasConnectionType == ScriptCanvas::ConnectionType::Output);
NodeIdPair nodePair = ScriptCanvasEditor::Nodes::CreateFunctionDefinitionNode(scriptCanvasGraphId, isInput);
GraphCanvas::SceneRequestBus::Event(graphId, &GraphCanvas::SceneRequests::AddNode, nodePair.m_graphCanvasId, scenePos, false);
@@ -490,13 +499,8 @@ namespace ScriptCanvasEditor
// Set the node title, subtitle, tooltip
GraphCanvas::NodeTitleRequestBus::Event(nodePair.m_graphCanvasId, &GraphCanvas::NodeTitleRequests::SetTitle, fullTitle);
GraphCanvas::NodeTitleRequestBus::Event(nodePair.m_graphCanvasId, &GraphCanvas::NodeTitleRequests::SetSubTitle, "Function");
GraphCanvas::NodeRequestBus::Event(nodePair.m_graphCanvasId, &GraphCanvas::NodeRequests::SetTooltip, name);
// Set the connection type for the node opposite of what it actually is because we're interested in the connection type of the node we're
// exposing, not the type of the slot we just created
ScriptCanvas::ConnectionType scriptCanvasConnectionType = (connectionType == GraphCanvas::CT_Input) ? ScriptCanvas::ConnectionType::Input : ScriptCanvas::ConnectionType::Output;
ScriptCanvas::SlotDescriptor descriptor;
descriptor.m_slotType = ScriptCanvas::SlotTypeDescriptor::Execution;
descriptor.m_connectionType = scriptCanvasConnectionType;
@@ -584,20 +588,7 @@ namespace ScriptCanvasEditor
if (variable)
{
if (connectionType == GraphCanvas::CT_Input)
{
if (!variable->IsInScope(ScriptCanvas::VariableFlags::Scope::Input))
{
variable->SetScope(ScriptCanvas::VariableFlags::Scope::Input);
}
}
else if (connectionType == GraphCanvas::CT_Output)
{
if (!variable->IsInScope(ScriptCanvas::VariableFlags::Scope::Output))
{
variable->SetScope(ScriptCanvas::VariableFlags::Scope::Output);
}
}
variable->SetScope(ScriptCanvas::VariableFlags::Scope::Function);
}
}
}
@@ -607,6 +598,100 @@ namespace ScriptCanvasEditor
return GraphCanvas::ContextMenuAction::SceneReaction::PostUndo;
}
//////////////////////////////////
// SetDataSlotTypeMenuAction
//////////////////////////////////
SetDataSlotTypeMenuAction::SetDataSlotTypeMenuAction(QObject* parent)
: GraphCanvas::SlotContextMenuAction("Set Slot Type", parent)
{
}
void SetDataSlotTypeMenuAction::RefreshAction(const GraphCanvas::GraphId& graphId, const AZ::EntityId& targetId)
{
ScriptCanvas::Slot* slot = GetSlot(graphId, targetId);
bool isEnabled = slot && slot->IsUserAdded() && slot->GetDescriptor().IsData();
setEnabled(isEnabled);
}
GraphCanvas::ContextMenuAction::SceneReaction SetDataSlotTypeMenuAction::TriggerAction(const GraphCanvas::GraphId& graphId, const AZ::Vector2& scenePos)
{
ScriptCanvas::Slot* slot = GetSlot(graphId, GetTargetId());
if (!slot)
{
return GraphCanvas::ContextMenuAction::SceneReaction::Nothing;
}
// Show the selection dialog
bool createSlot = false;
VariablePaletteRequests::SlotSetup selectedSlotSetup;
QPoint scenePoint(scenePos.GetX(), scenePos.GetY());
VariablePaletteRequestBus::BroadcastResult(createSlot, &VariablePaletteRequests::ShowSlotTypeSelector, slot, scenePoint, selectedSlotSetup);
bool changed = false;
if (createSlot && !selectedSlotSetup.m_type.IsNull())
{
if (slot)
{
auto displayType = ScriptCanvas::Data::FromAZType(selectedSlotSetup.m_type);
if (displayType.IsValid())
{
slot->SetDisplayType(displayType);
changed = true;
}
if (!selectedSlotSetup.m_name.empty())
{
slot->Rename(selectedSlotSetup.m_name);
changed = true;
}
}
}
return changed ? GraphCanvas::ContextMenuAction::SceneReaction::PostUndo : GraphCanvas::ContextMenuAction::SceneReaction::Nothing;
}
bool SetDataSlotTypeMenuAction::IsSupportedSlotType(const AZ::EntityId& slotId)
{
GraphCanvas::Endpoint endpoint;
GraphCanvas::SlotRequestBus::EventResult(endpoint, slotId, &GraphCanvas::SlotRequests::GetEndpoint);
const ScriptCanvas::Slot* slot = SlotManipulationMenuAction::GetScriptCanvasSlot(endpoint);
if (slot)
{
if (slot->GetDescriptor().IsData())
{
return true;
}
}
return false;
}
ScriptCanvas::Slot* SetDataSlotTypeMenuAction::GetSlot(const GraphCanvas::GraphId& graphId, const AZ::EntityId& targetId)
{
ScriptCanvas::ScriptCanvasId scriptCanvasGraphId;
GeneralRequestBus::BroadcastResult(scriptCanvasGraphId, &GeneralRequests::GetScriptCanvasId, graphId);
GraphCanvas::Endpoint endpoint;
GraphCanvas::SlotRequestBus::EventResult(endpoint, targetId, &GraphCanvas::SlotRequests::GetEndpoint);
ScriptCanvas::Endpoint scEndpoint;
EditorGraphRequestBus::EventResult(scEndpoint, scriptCanvasGraphId, &EditorGraphRequests::ConvertToScriptCanvasEndpoint, endpoint);
ScriptCanvas::Slot* slot = nullptr;
ScriptCanvas::NodeRequestBus::EventResult(slot, scEndpoint.GetNodeId(), &ScriptCanvas::NodeRequests::GetSlot, scEndpoint.GetSlotId());
return slot;
}
//////////////////////////////////
// CreateAzEventHandlerSlotMenuAction
//////////////////////////////////
CreateAzEventHandlerSlotMenuAction::CreateAzEventHandlerSlotMenuAction(QObject* parent)
: SlotContextMenuAction("Create event handler", parent)
{
@@ -853,6 +938,34 @@ namespace ScriptCanvasEditor
// TODO: Filter nodes.
}
//////////////////////////
// RenameFunctionDefinitionNodeAction
//////////////////////////
RenameFunctionDefinitionNodeAction::RenameFunctionDefinitionNodeAction(NodeDescriptorComponent* descriptor, QObject* parent)
: NodeContextMenuAction("Rename Function", parent)
, m_descriptor(descriptor)
{}
void RenameFunctionDefinitionNodeAction::RefreshAction(const GraphCanvas::GraphId& graphId, const AZ::EntityId& /*targetId*/)
{
AZStd::vector<AZ::EntityId> selectedNodes;
GraphCanvas::SceneRequestBus::EventResult(selectedNodes, graphId, &GraphCanvas::SceneRequests::GetSelectedNodes);
setEnabled(selectedNodes.size() == 1);
}
GraphCanvas::ContextMenuAction::SceneReaction RenameFunctionDefinitionNodeAction::TriggerAction(const GraphCanvas::GraphId&, const AZ::Vector2&)
{
if (FunctionDefinitionNodeDescriptorComponent::RenameDialog(azrtti_cast<FunctionDefinitionNodeDescriptorComponent*>(m_descriptor)))
{
return GraphCanvas::ContextMenuAction::SceneReaction::PostUndo;
}
return GraphCanvas::ContextMenuAction::SceneReaction::Nothing;
}
#include "Editor/View/Windows/moc_ScriptCanvasContextMenus.cpp"
}
@@ -23,8 +23,10 @@
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenus/SceneContextMenu.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenus/ConnectionContextMenu.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenus/SlotContextMenu.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenus/NodeContextMenu.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SceneMenuActions/SceneContextMenuAction.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SlotMenuActions/SlotContextMenuAction.h>
#include <GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/NodeMenuActions/NodeContextMenuAction.h>
#endif
namespace ScriptCanvasEditor
@@ -112,8 +114,8 @@ namespace ScriptCanvasEditor
SlotManipulationMenuAction(AZStd::string_view actionName, QObject* parent);
protected:
ScriptCanvas::Slot* GetScriptCanvasSlot(const GraphCanvas::Endpoint& endpoint) const;
static ScriptCanvas::Slot* GetScriptCanvasSlot(const GraphCanvas::Endpoint& endpoint) ;
};
class ConvertReferenceToVariableNodeAction
@@ -153,6 +155,25 @@ namespace ScriptCanvasEditor
void CreateNodeling(const GraphCanvas::GraphId& graphId, AZ::EntityId scriptCanvasGraphId, GraphCanvas::GraphId slotId, const AZ::Vector2& scenePos, GraphCanvas::ConnectionType connectionType);
};
class SetDataSlotTypeMenuAction
: public GraphCanvas::SlotContextMenuAction
{
public:
AZ_CLASS_ALLOCATOR(SetDataSlotTypeMenuAction, AZ::SystemAllocator, 0);
explicit SetDataSlotTypeMenuAction(QObject* parent);
virtual ~SetDataSlotTypeMenuAction() = default;
static bool IsSupportedSlotType(const AZ::EntityId& slotId);
void RefreshAction(const GraphCanvas::GraphId& graphId, const AZ::EntityId& targetId) override;
GraphCanvas::ContextMenuAction::SceneReaction TriggerAction(const GraphCanvas::GraphId& graphId, const AZ::Vector2& scenePos) override;
private:
ScriptCanvas::Slot* GetSlot(const GraphCanvas::GraphId& graphId, const AZ::EntityId& targetId);
};
//! Context Menu Action for Creating an AzEventHandler node from a data slot of a Behavior Method node
//! which returns an AZ::Event<Params...> type
class CreateAzEventHandlerSlotMenuAction
@@ -172,6 +193,7 @@ namespace ScriptCanvasEditor
const AZ::BehaviorMethod* m_methodWithAzEventReturn{};
GraphCanvas::Endpoint m_methodNodeAzEventEndpoint;
};
/////////////////
@@ -222,4 +244,27 @@ namespace ScriptCanvasEditor
AZ::EntityId m_connectionId;
};
//////////////////////////
// RenameFunctionDefinitionNode
//////////////////////////
class NodeDescriptorComponent;
//! Context menu to rename a node
class RenameFunctionDefinitionNodeAction
: public GraphCanvas::NodeContextMenuAction
{
public:
AZ_CLASS_ALLOCATOR(RenameFunctionDefinitionNodeAction, AZ::SystemAllocator, 0);
RenameFunctionDefinitionNodeAction(NodeDescriptorComponent* descriptor, QObject* parent);
virtual ~RenameFunctionDefinitionNodeAction() = default;
void RefreshAction(const GraphCanvas::GraphId& graphId, const AZ::EntityId& targetId) override;
GraphCanvas::ContextMenuAction::SceneReaction TriggerAction(const GraphCanvas::GraphId& graphId, const AZ::Vector2& scenePos) override;
NodeDescriptorComponent* m_descriptor;
};
}
@@ -57,7 +57,6 @@
<string>&amp;File</string>
</property>
<addaction name="action_New_Script"/>
<addaction name="actionFunction"/>
<addaction name="action_Open"/>
<addaction name="action_Save"/>
<addaction name="action_Save_As"/>
@@ -180,11 +179,6 @@
<string>&amp;New Script</string>
</property>
</action>
<action name="action_New_Function">
<property name="text">
<string>&amp;Function</string>
</property>
</action>
<action name="action_New_Editor_Graph">
<property name="text">
<string>&amp;Editor Graph</string>
@@ -781,11 +775,6 @@
<string>Editor Graph</string>
</property>
</action>
<action name="actionFunction">
<property name="text">
<string>New Function</string>
</property>
</action>
<addaction name="action_ViewNodePalette"/>
<addaction name="action_ViewOutline"/>
<addaction name="action_ViewDynamicEBusAssets"/>