EntityMimeDataHandler.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EntityMimeDataHandler.h"
  9. #include <QMimeData>
  10. #include <QDragEnterEvent>
  11. #include <QDragMoveEvent>
  12. #include <QDropEvent>
  13. #include <QGraphicsView>
  14. #include <Editor/Nodes/NodeCreateUtils.h>
  15. #include <ScriptCanvas/Bus/RequestBus.h>
  16. #include <ScriptCanvas/Bus/NodeIdPair.h>
  17. #include <AzCore/Component/ComponentApplicationBus.h>
  18. #include <AzToolsFramework/ToolsComponents/EditorEntityIdContainer.h>
  19. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  20. #include <AzCore/Component/Entity.h>
  21. #include <GraphCanvas/Components/SceneBus.h>
  22. #include <GraphCanvas/Components/GridBus.h>
  23. #include <GraphCanvas/Components/ViewBus.h>
  24. #include <GraphCanvas/Components/VisualBus.h>
  25. #include <Core/GraphBus.h>
  26. #include <ScriptCanvas/Variable/VariableBus.h>
  27. #include <GraphCanvas/Utils/GraphUtils.h>
  28. namespace ScriptCanvasEditor
  29. {
  30. namespace EntityMimeData
  31. {
  32. static QString GetMimeType()
  33. {
  34. return AzToolsFramework::EditorEntityIdContainer::GetMimeType();
  35. }
  36. }
  37. void EntityMimeDataHandler::Reflect(AZ::ReflectContext* context)
  38. {
  39. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  40. if (!serializeContext)
  41. {
  42. return;
  43. }
  44. serializeContext->Class<EntityMimeDataHandler, AZ::Component>()
  45. ->Version(1)
  46. ;
  47. }
  48. EntityMimeDataHandler::EntityMimeDataHandler()
  49. {}
  50. void EntityMimeDataHandler::Activate()
  51. {
  52. GraphCanvas::SceneMimeDelegateHandlerRequestBus::Handler::BusConnect(GetEntityId());
  53. }
  54. void EntityMimeDataHandler::Deactivate()
  55. {
  56. GraphCanvas::SceneMimeDelegateHandlerRequestBus::Handler::BusDisconnect();
  57. }
  58. bool EntityMimeDataHandler::IsInterestedInMimeData(const AZ::EntityId& sceneId, const QMimeData* mimeData)
  59. {
  60. (void)sceneId;
  61. return mimeData->hasFormat(EntityMimeData::GetMimeType());
  62. }
  63. void EntityMimeDataHandler::HandleMove(const AZ::EntityId&, const QPointF&, const QMimeData*)
  64. {
  65. }
  66. void EntityMimeDataHandler::HandleDrop(const AZ::EntityId& graphCanvasGraphId, const QPointF& dropPoint, const QMimeData* mimeData)
  67. {
  68. if (!mimeData->hasFormat(EntityMimeData::GetMimeType()))
  69. {
  70. return;
  71. }
  72. QByteArray arrayData = mimeData->data(EntityMimeData::GetMimeType());
  73. AzToolsFramework::EditorEntityIdContainer entityIdListContainer;
  74. if (!entityIdListContainer.FromBuffer(arrayData.constData(), arrayData.size()) || entityIdListContainer.m_entityIds.empty())
  75. {
  76. return;
  77. }
  78. bool areEntitiesEditable = true;
  79. AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(areEntitiesEditable, &AzToolsFramework::ToolsApplicationRequests::AreEntitiesEditable, entityIdListContainer.m_entityIds);
  80. if (!areEntitiesEditable)
  81. {
  82. return;
  83. }
  84. ScriptCanvas::ScriptCanvasId scriptCanvasId;
  85. GeneralRequestBus::BroadcastResult(scriptCanvasId, &GeneralRequests::GetScriptCanvasId, graphCanvasGraphId);
  86. ScriptCanvas::GraphVariableManagerRequests* variableManagerRequests = ScriptCanvas::GraphVariableManagerRequestBus::FindFirstHandler(scriptCanvasId);
  87. if (variableManagerRequests == nullptr)
  88. {
  89. return;
  90. }
  91. AZStd::vector< ScriptCanvas::VariableId > variableIds;
  92. variableIds.reserve(entityIdListContainer.m_entityIds.size());
  93. {
  94. GraphCanvas::ScopedGraphUndoBlocker undoBlocker(graphCanvasGraphId);
  95. AZ::Vector2 pos(aznumeric_cast<float>(dropPoint.x()), aznumeric_cast<float>(dropPoint.y()));
  96. for (const AZ::EntityId& entityId : entityIdListContainer.m_entityIds)
  97. {
  98. AZStd::string variableName;
  99. AZ::Entity* entity = nullptr;
  100. AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
  101. if (entity)
  102. {
  103. // Because we add in the entity id to this.
  104. // we make the name mostly unique.
  105. // If we just use the name, we'll run into some potential rename issues when looking things up.
  106. variableName = AZStd::string::format("%s %s", entity->GetName().c_str(), entityId.ToString().c_str());
  107. ScriptCanvas::GraphVariable* graphVariable = variableManagerRequests->FindVariable(variableName);
  108. int counter = 0;
  109. AZStd::string baseName = variableName;
  110. baseName.append(" (Copy)");
  111. // If the variable datum already exists. That means we already have a reference to that. So we don't need to create it.
  112. while (graphVariable != nullptr)
  113. {
  114. if (graphVariable->GetDataType() == ScriptCanvas::Data::Type::EntityID())
  115. {
  116. variableIds.emplace_back(graphVariable->GetVariableId());
  117. break;
  118. }
  119. if (counter == 0)
  120. {
  121. variableName = baseName;
  122. }
  123. else
  124. {
  125. variableName = AZStd::string::format("%s (%i)", baseName.c_str(), counter);
  126. }
  127. ++counter;
  128. graphVariable = variableManagerRequests->FindVariable(variableName);
  129. }
  130. if (graphVariable == nullptr)
  131. {
  132. ScriptCanvas::Datum datum = ScriptCanvas::Datum(entityId);
  133. AZ::Outcome<ScriptCanvas::VariableId, AZStd::string > addVariableOutcome = variableManagerRequests->AddVariable(variableName, datum, false);
  134. if (addVariableOutcome.IsSuccess())
  135. {
  136. variableIds.emplace_back(addVariableOutcome.GetValue());
  137. }
  138. }
  139. }
  140. }
  141. if (!variableIds.empty())
  142. {
  143. AZ::EntityId gridId;
  144. GraphCanvas::SceneRequestBus::EventResult(gridId, graphCanvasGraphId, &GraphCanvas::SceneRequests::GetGrid);
  145. AZ::Vector2 gridStep;
  146. GraphCanvas::GridRequestBus::EventResult(gridStep, gridId, &GraphCanvas::GridRequests::GetMinorPitch);
  147. for (const ScriptCanvas::VariableId& variableId : variableIds)
  148. {
  149. NodeIdPair nodePair = Nodes::CreateGetVariableNode(variableId, scriptCanvasId);
  150. GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, nodePair.m_graphCanvasId, pos, false);
  151. pos += gridStep;
  152. }
  153. }
  154. }
  155. if (!variableIds.empty())
  156. {
  157. GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, scriptCanvasId);
  158. }
  159. }
  160. void EntityMimeDataHandler::HandleLeave(const AZ::EntityId&, const QMimeData*)
  161. {
  162. }
  163. }