MaterialBrowserInteractions.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 <Atom/RPI.Edit/Common/AssetUtils.h>
  9. #include <Atom/RPI.Edit/Common/JsonUtils.h>
  10. #include <Atom/RPI.Edit/Material/MaterialSourceData.h>
  11. #include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
  12. #include <Atom/RPI.Edit/Material/MaterialUtils.h>
  13. #include <Atom/RPI.Reflect/System/AnyAsset.h>
  14. #include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
  15. #include <AtomToolsFramework/Document/CreateDocumentDialog.h>
  16. #include <AtomToolsFramework/Util/Util.h>
  17. #include <AzCore/IO/FileIO.h>
  18. #include <AzCore/std/string/wildcard.h>
  19. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  20. #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
  21. #include <Material/EditorMaterialComponentUtil.h>
  22. #include <Material/MaterialBrowserInteractions.h>
  23. namespace AZ
  24. {
  25. namespace Render
  26. {
  27. MaterialBrowserInteractions::MaterialBrowserInteractions()
  28. {
  29. AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
  30. }
  31. MaterialBrowserInteractions::~MaterialBrowserInteractions()
  32. {
  33. AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
  34. }
  35. void MaterialBrowserInteractions::AddSourceFileOpeners(const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers)
  36. {
  37. const AZStd::string_view path(fullSourceFileName);
  38. if (path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialExtensionWithDot) ||
  39. path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialTypeExtensionWithDot))
  40. {
  41. openers.push_back({ "Material_Editor", "Open in Material Editor...", QIcon(":/Menu/material_editor.svg"),
  42. [&](const char* fullSourceFileNameInCallback, [[maybe_unused]] const AZ::Uuid& sourceUUID)
  43. {
  44. EditorMaterialSystemComponentRequestBus::Broadcast(
  45. &EditorMaterialSystemComponentRequestBus::Events::OpenMaterialEditor,
  46. fullSourceFileNameInCallback);
  47. } });
  48. return;
  49. }
  50. if (path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphExtensionWithDot) ||
  51. path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphNodeExtensionWithDot) ||
  52. path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphTemplateExtensionWithDot) ||
  53. path.ends_with(AZ::Render::EditorMaterialComponentUtil::ShaderExtensionWithDot))
  54. {
  55. openers.push_back({ "Material_Canvas", "Open in Material Canvas...", QIcon(":/Menu/material_canvas.svg"),
  56. [&](const char* fullSourceFileNameInCallback, [[maybe_unused]] const AZ::Uuid& sourceUUID)
  57. {
  58. EditorMaterialSystemComponentRequestBus::Broadcast(
  59. &EditorMaterialSystemComponentRequestBus::Events::OpenMaterialCanvas,
  60. fullSourceFileNameInCallback);
  61. } });
  62. return;
  63. }
  64. }
  65. void MaterialBrowserInteractions::AddSourceFileCreators(
  66. [[maybe_unused]] const char* fullSourceFolderName,
  67. [[maybe_unused]] const AZ::Uuid& sourceUUID,
  68. AzToolsFramework::AssetBrowser::SourceFileCreatorList& creators)
  69. {
  70. using namespace AtomToolsFramework;
  71. creators.push_back(
  72. { "Material_Creator", "Material", QIcon(),
  73. [&](const AZStd::string& fullSourceFolderNameInCallback, [[maybe_unused]] const AZ::Uuid& sourceUUID)
  74. {
  75. const AZStd::string defaultMaterialType =
  76. AtomToolsFramework::GetPathWithoutAlias(AtomToolsFramework::GetSettingsValue<AZStd::string>(
  77. "/O3DE/Atom/MaterialEditor/DefaultMaterialType",
  78. "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype"));
  79. QWidget* mainWindow = nullptr;
  80. AzToolsFramework::EditorRequests::Bus::BroadcastResult(
  81. mainWindow, &AzToolsFramework::EditorRequests::Bus::Events::GetMainWindow);
  82. CreateDocumentDialog dialog(
  83. QObject::tr("Create Material"),
  84. QObject::tr("Select Material Type"),
  85. fullSourceFolderNameInCallback.empty() ? QObject::tr("Select Material Path") : QString(),
  86. fullSourceFolderNameInCallback.c_str(),
  87. { "material" },
  88. defaultMaterialType.c_str(),
  89. [](const AZStd::string& path)
  90. {
  91. return IsDocumentPathEditable(path) &&
  92. path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialTypeExtensionWithDot);
  93. },
  94. mainWindow);
  95. dialog.adjustSize();
  96. if (dialog.exec() == QDialog::Accepted && !dialog.m_sourcePath.isEmpty() && !dialog.m_targetPath.isEmpty())
  97. {
  98. uint32_t defaultMaterialVersion = 5;
  99. const char* fullSourcePath = dialog.m_sourcePath.toUtf8().constData();
  100. auto materialTypeSourceData = AZ::RPI::MaterialUtils::LoadMaterialTypeSourceData(fullSourcePath);
  101. if (materialTypeSourceData.IsSuccess())
  102. {
  103. defaultMaterialVersion = materialTypeSourceData.GetValue().m_version;
  104. }
  105. AZ::RPI::MaterialSourceData materialData;
  106. materialData.m_materialTypeVersion = defaultMaterialVersion;
  107. materialData.m_materialType = AtomToolsFramework::GetPathToExteralReference(
  108. dialog.m_targetPath.toUtf8().constData(), dialog.m_sourcePath.toUtf8().constData());
  109. dialog.m_sourcePath.toUtf8().constData();
  110. materialData.m_parentMaterial = "";
  111. AZ::RPI::JsonUtils::SaveObjectToFile(dialog.m_targetPath.toUtf8().constData(), materialData);
  112. AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotificationBus::Event(
  113. AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotifications::FileCreationNotificationBusId,
  114. &AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotifications::HandleAssetCreatedInEditor,
  115. dialog.m_targetPath.toUtf8().constData(),
  116. AZ::Crc32(),
  117. false);
  118. }
  119. } });
  120. creators.push_back(
  121. { "Material_Graph_Creator", "Material Graph", QIcon(),
  122. [&](const AZStd::string& fullSourceFolderNameInCallback, [[maybe_unused]] const AZ::Uuid& sourceUUID)
  123. {
  124. const AZStd::string defaultMaterialGraphTemplate =
  125. AtomToolsFramework::GetPathWithoutAlias(AtomToolsFramework::GetSettingsValue<AZStd::string>(
  126. "/O3DE/Atom/MaterialCanvas/DefaultMaterialGraphTemplate",
  127. "@gemroot:MaterialCanvas@/Assets/MaterialCanvas/GraphData/blank_graph.materialgraphtemplate"));
  128. QWidget* mainWindow = nullptr;
  129. AzToolsFramework::EditorRequests::Bus::BroadcastResult(
  130. mainWindow, &AzToolsFramework::EditorRequests::Bus::Events::GetMainWindow);
  131. CreateDocumentDialog dialog(
  132. QObject::tr("Create Material Graph"),
  133. QObject::tr("Select Material Graph Template"),
  134. fullSourceFolderNameInCallback.empty() ? QObject::tr("Select Material Path") : QString(),
  135. fullSourceFolderNameInCallback.c_str(),
  136. { "materialgraph" },
  137. defaultMaterialGraphTemplate.c_str(),
  138. [](const AZStd::string& path)
  139. {
  140. return IsDocumentPathEditable(path) &&
  141. path.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphTemplateExtensionWithDot);
  142. },
  143. mainWindow);
  144. dialog.adjustSize();
  145. if (dialog.exec() == QDialog::Accepted && !dialog.m_sourcePath.isEmpty() && !dialog.m_targetPath.isEmpty())
  146. {
  147. AZ::IO::FileIOBase::GetInstance()->Copy(
  148. dialog.m_sourcePath.toUtf8().constData(), dialog.m_targetPath.toUtf8().constData());
  149. AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotificationBus::Event(
  150. AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotifications::FileCreationNotificationBusId,
  151. &AzToolsFramework::AssetBrowser::AssetBrowserFileCreationNotifications::HandleAssetCreatedInEditor,
  152. dialog.m_targetPath.toUtf8().constData(),
  153. AZ::Crc32(),
  154. false);
  155. }
  156. } });
  157. }
  158. bool MaterialBrowserInteractions::HandlesSource(AZStd::string_view fileName) const
  159. {
  160. return fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialExtensionWithDot) ||
  161. fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialTypeExtensionWithDot) ||
  162. fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphExtensionWithDot) ||
  163. fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphNodeExtensionWithDot) ||
  164. fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::MaterialGraphTemplateExtensionWithDot) ||
  165. fileName.ends_with(AZ::Render::EditorMaterialComponentUtil::ShaderExtensionWithDot);
  166. }
  167. } // namespace Render
  168. } // namespace AZ