From 26c55514d5cb1d8b7352b53d570f9c3458b98f8e Mon Sep 17 00:00:00 2001 From: scottr Date: Mon, 24 May 2021 09:27:03 -0700 Subject: [PATCH 01/12] [ext_project_packaging_fix] replaced incorrect usage of CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR in cmake packaging scripts --- cmake/Packaging.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake index ba610b1883..fbeffa94eb 100644 --- a/cmake/Packaging.cmake +++ b/cmake/Packaging.cmake @@ -29,15 +29,15 @@ string(TOLOWER ${PROJECT_NAME} _project_name_lower) set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_${LY_VERSION_STRING}_installer") set(DEFAULT_LICENSE_NAME "Apache-2.0") -set(DEFAULT_LICENSE_FILE "${CMAKE_SOURCE_DIR}/LICENSE.txt") +set(DEFAULT_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE}) set(CPACK_LICENSE_URL ${LY_INSTALLER_LICENSE_URL}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}") -# CMAKE_SOURCE_DIR doesn't equate to anything during execution of pre/post build scripts -set(CPACK_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cmake) +# neither of the SOURCE_DIR variables equate to anything during execution of pre/post build scripts +set(CPACK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # attempt to apply platform specific settings ly_get_absolute_pal_filename(pal_dir ${CPACK_SOURCE_DIR}/Platform/${PAL_HOST_PLATFORM_NAME}) From e57e1b3ba21eb61116ca9a3331e57ff9e35cbdaf Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 24 May 2021 18:19:09 -0700 Subject: [PATCH 02/12] remove testrail info from tests --- .../atom_renderer/test_Atom_MainSuite.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index b64a592c1d..fccd750573 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -26,19 +26,23 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("level", ["auto_test"]) class TestAtomEditorComponentsMain(object): + """Holds tests for Atom components.""" - @pytest.mark.test_case_id( - "C32078130", # Display Mapper - "C32078129", # Light - "C32078131", # Radius Weight Modifier - "C32078127", # PostFX Layer - "C32078125", # Physical Sky - "C32078115", # Global Skylight (IBL) - "C32078121", # Exposure Control - "C32078120", # Directional Light - "C32078119", # DepthOfField - "C32078118") # Decal (Atom) def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): + """ + Please review the hydra script run by this test for more specific test info. + Tests the following Atom components and verifies all "expected_lines" appear in Editor.log: + 1. Display Mapper + 2. Light + 3. Radius Weight Modifier + 4. PostFX Layer + 5. Physical Sky + 6. Global Skylight (IBL) + 7. Exposure Control + 8. Directional Light + 9. DepthOfField + 10. Decal (Atom) + """ cfg_args = [level] expected_lines = [ From 1da8c50e8e81cc51c84eed0e560672e8121f27a3 Mon Sep 17 00:00:00 2001 From: AMZN-stankowi Date: Tue, 25 May 2021 08:54:42 -0700 Subject: [PATCH 03/12] Temporarily backing out STL changes to unblock mainline (#921) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "FBX settings can be opened again: g_fbxImporter is set, and if the ex… (#878)" This reverts commit 58adcf168fcab0da94b25004482a6edabb2b0fad. * Revert "Merge pull request #753 from aws-lumberyard-dev/Helios_DataDrivenAssetImporter" This reverts commit 798d96f1a2056cc71156797a88d96e0a67f1f9d3, reversing changes made to eb31d90ad94da7cca7a13b8e1385f1edc4bc42b4. --- .../SceneAPI/FbxSceneBuilder/DllMain.cpp | 19 ++++--- .../FbxImportRequestHandler.cpp | 51 +++---------------- .../FbxSceneBuilder/FbxImportRequestHandler.h | 20 ++------ .../SceneBuilder/SceneBuilderComponent.cpp | 6 +-- .../SceneBuilder/SceneBuilderComponent.h | 2 - Registry/sceneassetimporter.setreg | 16 ------ 6 files changed, 23 insertions(+), 91 deletions(-) delete mode 100644 Registry/sceneassetimporter.setreg diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp index 6fd664eee4..3dc14814de 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp @@ -41,6 +41,18 @@ namespace AZ static AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler* g_fbxImporter = nullptr; static AZStd::vector g_componentDescriptors; + void Initialize() + { + // Currently it's still needed to explicitly create an instance of this instead of letting + // it be a normal component. This is because ResourceCompilerScene needs to return + // the list of available extensions before it can start the application. + if (!g_fbxImporter) + { + g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler(); + g_fbxImporter->Activate(); + } + } + void Reflect(AZ::SerializeContext* /*context*/) { // Descriptor registration is done in Reflect instead of Initialize because the ResourceCompilerScene initializes the libraries before @@ -52,7 +64,6 @@ namespace AZ { // Global importer and behavior g_componentDescriptors.push_back(FbxSceneBuilder::FbxImporter::CreateDescriptor()); - g_componentDescriptors.push_back(FbxSceneImporter::FbxImportRequestHandler::CreateDescriptor()); // Node and attribute importers g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor()); @@ -114,11 +125,7 @@ namespace AZ extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env) { AZ::Environment::Attach(static_cast(env)); - if (!AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter) - { - AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler(); - AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter->Activate(); - } + AZ::SceneAPI::FbxSceneBuilder::Initialize(); } extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context) { diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp index ebdb57e452..155209f1b5 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp @@ -10,16 +10,12 @@ * */ -#include -#include #include -#include -#include -#include -#include +#include #include #include #include +#include namespace AZ { @@ -27,23 +23,10 @@ namespace AZ { namespace FbxSceneImporter { - void SceneImporterSettings::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context); serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("SupportedFileTypeExtensions", &SceneImporterSettings::m_supportedFileTypeExtensions); - } - } + const char* FbxImportRequestHandler::s_extension = ".fbx"; void FbxImportRequestHandler::Activate() { - if (auto* settingsRegistry = AZ::SettingsRegistry::Get()) - { - settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter"); - } - BusConnect(); } @@ -54,38 +37,21 @@ namespace AZ void FbxImportRequestHandler::Reflect(ReflectContext* context) { - SceneImporterSettings::Reflect(context); - SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(1)->Attribute( - AZ::Edit::Attributes::SystemComponentTags, - AZStd::vector({AssetBuilderSDK::ComponentTags::AssetBuilder})); - + serializeContext->Class()->Version(1); } } void FbxImportRequestHandler::GetSupportedFileExtensions(AZStd::unordered_set& extensions) { - // It's unlikely an empty file extension list is intentional, - // so if it's empty, try reloading it from the registry. - if (m_settings.m_supportedFileTypeExtensions.empty()) - { - if (auto* settingsRegistry = AZ::SettingsRegistry::Get()) - { - settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter"); - } - } - extensions.insert(m_settings.m_supportedFileTypeExtensions.begin(), m_settings.m_supportedFileTypeExtensions.end()); + extensions.insert(s_extension); } Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester) { - AZStd::string extension; - StringFunc::Path::GetExtension(path.c_str(), extension); - - if (!m_settings.m_supportedFileTypeExtensions.contains(extension)) + if (!AzFramework::StringFunc::Path::IsExtension(path.c_str(), s_extension)) { return Events::LoadingResult::Ignored; } @@ -107,11 +73,6 @@ namespace AZ return Events::LoadingResult::AssetFailure; } } - - void FbxImportRequestHandler::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided) - { - provided.emplace_back(AZ_CRC_CE("AssetImportRequestHandler")); - } } // namespace Import } // namespace SceneAPI } // namespace AZ diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h index 12c7c6f877..8b33051f1e 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h @@ -21,21 +21,12 @@ namespace AZ { namespace FbxSceneImporter { - struct SceneImporterSettings - { - AZ_TYPE_INFO(SceneImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}"); - - static void Reflect(AZ::ReflectContext* context); - - AZStd::unordered_set m_supportedFileTypeExtensions; - }; - class FbxImportRequestHandler - : public AZ::Component + : public SceneCore::BehaviorComponent , public Events::AssetImportRequestBus::Handler { public: - AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}"); + AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}", SceneCore::BehaviorComponent); ~FbxImportRequestHandler() override = default; @@ -47,13 +38,8 @@ namespace AZ Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, RequestingApplication requester) override; - static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided); - private: - - SceneImporterSettings m_settings; - - static constexpr const char* SettingsFilename = "AssetImporterSettings.json"; + static const char* s_extension; }; } // namespace FbxSceneImporter } // namespace SceneAPI diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp index 25faca3667..e71a5207d0 100644 --- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp @@ -72,11 +72,6 @@ namespace SceneBuilder m_sceneBuilder.BusDisconnect(); } - void BuilderPluginComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.emplace_back(AZ_CRC_CE("AssetImportRequestHandler")); - } - void BuilderPluginComponent::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -86,4 +81,5 @@ namespace SceneBuilder ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })); } } + } // namespace SceneBuilder diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h index aed5e1b026..c1fc6ebb36 100644 --- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h +++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h @@ -32,8 +32,6 @@ namespace SceneBuilder void Activate() override; void Deactivate() override; - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - private: SceneBuilderWorker m_sceneBuilder; }; diff --git a/Registry/sceneassetimporter.setreg b/Registry/sceneassetimporter.setreg deleted file mode 100644 index bd7c4d0705..0000000000 --- a/Registry/sceneassetimporter.setreg +++ /dev/null @@ -1,16 +0,0 @@ -{ - "O3DE": - { - "SceneAPI": - { - "AssetImporter": - { - "SupportedFileTypeExtensions": - [ - ".fbx", - ".stl" - ] - } - } - } -} \ No newline at end of file From 50f5976e59d212e48dc641504d0bc80691c1d874 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 25 May 2021 17:28:51 +0100 Subject: [PATCH 04/12] Rename and move ModernViewportCameraController (#866) * rename ModernViewportCameraController to ModularViewportCameraController and move to AtomToolsFramework * update names and includes after file moves --- Code/Sandbox/Editor/CryEditDoc.cpp | 6 ++---- Code/Sandbox/Editor/EditorViewportWidget.cpp | 4 ++-- Code/Sandbox/Editor/editor_lib_files.cmake | 3 --- .../CMakeLists.txt | 1 + .../SandboxIntegration.cpp | 8 ++++---- .../ModularViewportCameraController.h | 17 ++++++++--------- ...odularViewportCameraControllerRequestBus.h | 10 +++++----- .../ModularViewportCameraController.cpp | 19 +++++++++---------- .../Code/atomtoolsframework_files.cmake | 3 +++ 9 files changed, 34 insertions(+), 37 deletions(-) rename Code/Sandbox/Editor/ModernViewportCameraController.h => Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h (87%) rename Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h => Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h (78%) rename Code/Sandbox/Editor/ModernViewportCameraController.cpp => Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp (91%) diff --git a/Code/Sandbox/Editor/CryEditDoc.cpp b/Code/Sandbox/Editor/CryEditDoc.cpp index a6c5f73c7f..747921d401 100644 --- a/Code/Sandbox/Editor/CryEditDoc.cpp +++ b/Code/Sandbox/Editor/CryEditDoc.cpp @@ -58,13 +58,11 @@ #include "LevelFileDialog.h" #include "StatObjBus.h" -// LmbrCentral -#include #include #include -#include // for LmbrCentral::EditorLightComponentRequestBus - +// LmbrCentral +#include // for LmbrCentral::EditorLightComponentRequestBus //#define PROFILE_LOADING_WITH_VTUNE diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index f72801a4d3..ecd11da817 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -53,6 +53,7 @@ // AtomToolsFramework #include +#include // CryCommon #include @@ -75,7 +76,6 @@ #include "EditorPreferencesPageGeneral.h" #include "ViewportManipulatorController.h" #include "LegacyViewportCameraController.h" -#include "ModernViewportCameraController.h" #include "EditorViewportSettings.h" #include "ViewPane.h" @@ -1220,7 +1220,7 @@ void EditorViewportWidget::SetViewportId(int id) { AzFramework::ReloadCameraKeyBindings(); - auto controller = AZStd::make_shared(); + auto controller = AZStd::make_shared(); controller->SetCameraListBuilderCallback([](AzFramework::Cameras& cameras) { auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::CameraFreeLookButton); diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 0646fb566e..e1cf18df55 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -823,9 +823,6 @@ set(FILES ViewportManipulatorController.h LegacyViewportCameraController.cpp LegacyViewportCameraController.h - ModernViewportCameraController.cpp - ModernViewportCameraController.h - ModernViewportCameraControllerRequestBus.h RenderViewport.cpp RenderViewport.h TopRendererWnd.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt index 72d88b06b4..d02c656b8f 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt @@ -38,6 +38,7 @@ ly_add_target( Gem::LmbrCentral AZ::AtomCore Gem::Atom_RPI.Public + Gem::AtomToolsFramework.Static ) ly_add_dependencies(Editor ComponentEntityEditorPlugin) diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 884e1f9e51..5ff2debe3d 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -66,8 +66,8 @@ #include #include +#include -#include #include "Objects/ComponentEntityObject.h" #include "ISourceControl.h" @@ -1736,9 +1736,9 @@ void SandboxIntegrationManager::GoToEntitiesInViewports(const AzToolsFramework:: const AZ::Transform nextCameraTransform = AZ::Transform::CreateLookAt(aabb.GetCenter() - (forward * distanceToTarget), aabb.GetCenter()); - SandboxEditor::ModernViewportCameraControllerRequestBus::Event( - viewportContext->GetId(), &SandboxEditor::ModernViewportCameraControllerRequestBus::Events::InterpolateToTransform, - nextCameraTransform); + AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event( + viewportContext->GetId(), + &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform); } } } diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h similarity index 87% rename from Code/Sandbox/Editor/ModernViewportCameraController.h rename to Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h index 39e3c9cbb3..1318deb355 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h @@ -12,17 +12,16 @@ #pragma once -#include - #include +#include #include #include #include -namespace SandboxEditor +namespace AtomToolsFramework { class ModernViewportCameraControllerInstance; - class ModernViewportCameraController + class ModularViewportCameraController : public AzFramework::MultiViewportController< ModernViewportCameraControllerInstance, AzFramework::ViewportControllerPriority::DispatchToAllPriorities> { @@ -39,19 +38,19 @@ namespace SandboxEditor }; class ModernViewportCameraControllerInstance final - : public AzFramework::MultiViewportControllerInstanceInterface, - public ModernViewportCameraControllerRequestBus::Handler, + : public AzFramework::MultiViewportControllerInstanceInterface, + public ModularViewportCameraControllerRequestBus::Handler, private AzFramework::ViewportDebugDisplayEventBus::Handler { public: - explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModernViewportCameraController* controller); + explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModularViewportCameraController* controller); ~ModernViewportCameraControllerInstance() override; // MultiViewportControllerInstanceInterface overrides ... bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override; - // ModernViewportCameraControllerRequestBus overrides ... + // ModularViewportCameraControllerRequestBus overrides ... void InterpolateToTransform(const AZ::Transform& worldFromLocal) override; private: @@ -76,4 +75,4 @@ namespace SandboxEditor AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler; }; -} // namespace SandboxEditor +} // namespace AtomToolsFramework diff --git a/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h similarity index 78% rename from Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h rename to Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h index 966facc8e9..5b90119372 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h @@ -20,11 +20,11 @@ namespace AZ class Transform; } -namespace SandboxEditor +namespace AtomToolsFramework { //! Provides an interface to control the modern viewport camera controller from the Editor. //! @note The bus is addressed by viewport id. - class ModernViewportCameraControllerRequests : public AZ::EBusTraits + class ModularViewportCameraControllerRequests : public AZ::EBusTraits { public: using BusIdType = AzFramework::ViewportId; @@ -35,8 +35,8 @@ namespace SandboxEditor virtual void InterpolateToTransform(const AZ::Transform& worldFromLocal) = 0; protected: - ~ModernViewportCameraControllerRequests() = default; + ~ModularViewportCameraControllerRequests() = default; }; - using ModernViewportCameraControllerRequestBus = AZ::EBus; -} // namespace SandboxEditor + using ModularViewportCameraControllerRequestBus = AZ::EBus; +} // namespace AtomToolsFramework diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp similarity index 91% rename from Code/Sandbox/Editor/ModernViewportCameraController.cpp rename to Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp index 0779542878..6fb3edfa22 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp @@ -10,10 +10,9 @@ * */ -#include "ModernViewportCameraController.h" - #include #include +#include #include #include #include @@ -23,7 +22,7 @@ #include #include -namespace SandboxEditor +namespace AtomToolsFramework { // debug void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength) @@ -53,12 +52,12 @@ namespace SandboxEditor return viewportContext; } - void ModernViewportCameraController::SetCameraListBuilderCallback(const CameraListBuilder& builder) + void ModularViewportCameraController::SetCameraListBuilderCallback(const CameraListBuilder& builder) { m_cameraListBuilder = builder; } - void ModernViewportCameraController::SetupCameras(AzFramework::Cameras& cameras) + void ModularViewportCameraController::SetupCameras(AzFramework::Cameras& cameras) { if (m_cameraListBuilder) { @@ -67,8 +66,8 @@ namespace SandboxEditor } ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance( - const AzFramework::ViewportId viewportId, ModernViewportCameraController* controller) - : MultiViewportControllerInstanceInterface(viewportId, controller) + const AzFramework::ViewportId viewportId, ModularViewportCameraController* controller) + : MultiViewportControllerInstanceInterface(viewportId, controller) { controller->SetupCameras(m_cameraSystem.m_cameras); @@ -88,12 +87,12 @@ namespace SandboxEditor } AzFramework::ViewportDebugDisplayEventBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId()); - ModernViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); + ModularViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); } ModernViewportCameraControllerInstance::~ModernViewportCameraControllerInstance() { - ModernViewportCameraControllerRequestBus::Handler::BusDisconnect(); + ModularViewportCameraControllerRequestBus::Handler::BusDisconnect(); AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect(); } @@ -182,4 +181,4 @@ namespace SandboxEditor m_transformStart = m_camera.Transform(); m_transformEnd = worldFromLocal; } -} // namespace SandboxEditor +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index d8ceccc724..f28ba89b92 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -24,6 +24,8 @@ set(FILES Include/AtomToolsFramework/Util/MaterialPropertyUtil.h Include/AtomToolsFramework/Util/Util.h Include/AtomToolsFramework/Viewport/RenderViewportWidget.h + Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h + Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h Source/Communication/LocalServer.cpp Source/Communication/LocalSocket.cpp Source/Debug/TraceRecorder.cpp @@ -38,4 +40,5 @@ set(FILES Source/Util/MaterialPropertyUtil.cpp Source/Util/Util.cpp Source/Viewport/RenderViewportWidget.cpp + Source/Viewport/ModularViewportCameraController.cpp ) From ad3625c2a2687d7247671590a90e54f7e270fe3f Mon Sep 17 00:00:00 2001 From: Terry Michaels <81711813+tjmichaels@users.noreply.github.com> Date: Tue, 25 May 2021 11:57:49 -0500 Subject: [PATCH 05/12] Added ability to specify a default directory for the asset picker in the asset property control (#903) * Framework for setting default directory in asset picker * Asset Picker will default to a passed in default directory in the selection model * Added comment to the property to help define what is expected. * Fixed string assignment * Removed commented out #pragma * Addressed review feedback * Addressed review feedback --- .../AssetPicker/AssetPickerDialog.cpp | 13 +++- .../AssetBrowser/AssetSelectionModel.cpp | 10 +++ .../AssetBrowser/AssetSelectionModel.h | 4 ++ .../Views/AssetBrowserTreeView.cpp | 63 +++++++++++++------ .../AssetBrowser/Views/AssetBrowserTreeView.h | 5 +- .../UI/PropertyEditor/PropertyAssetCtrl.cpp | 18 ++++++ .../UI/PropertyEditor/PropertyAssetCtrl.hxx | 3 + 7 files changed, 96 insertions(+), 20 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp index 9ab50a803c..92711f45b2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp @@ -81,9 +81,20 @@ namespace AzToolsFramework m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_" + name); + bool selectedAsset = false; + for (auto& assetId : selection.GetSelectedAssetIds()) { - m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId); + if (assetId.IsValid()) + { + selectedAsset = true; + m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId); + } + } + + if (!selectedAsset) + { + m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory()); } setWindowTitle(tr("Pick %1").arg(m_selection.GetTitle())); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp index 65f361dc83..83734a24c3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp @@ -93,6 +93,16 @@ namespace AzToolsFramework m_selectedAssetIds.push_back(selectedAssetId); } + void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory) + { + m_defaultDirectory = defaultDirectory; + } + + AZStd::string_view AssetSelectionModel::GetDefaultDirectory() const + { + return m_defaultDirectory; + } + AZStd::vector& AssetSelectionModel::GetResults() { return m_results; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h index 59cc9d05e2..5e9d23602a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h @@ -47,6 +47,9 @@ namespace AzToolsFramework const AZStd::vector& GetSelectedAssetIds() const; void SetSelectedAssetIds(const AZStd::vector& selectedAssetIds); void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId); + + void SetDefaultDirectory(AZStd::string_view defaultDirectory); + AZStd::string_view GetDefaultDirectory() const; AZStd::vector& GetResults(); const AssetBrowserEntry* GetResult(); @@ -72,6 +75,7 @@ namespace AzToolsFramework AZStd::vector m_selectedAssetIds; AZStd::vector m_results; + AZStd::string m_defaultDirectory; QString m_title; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp index eeee433835..6cd60b0015 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -270,7 +271,20 @@ namespace AzToolsFramework return false; } - bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entries, const uint32_t entryPathIndex) + void AssetBrowserTreeView::SelectFolder(AZStd::string_view folderPath) + { + if (folderPath.size() == 0) + { + return; + } + + AZStd::vector entries; + AZ::StringFunc::Tokenize(folderPath, entries, "/"); + + SelectEntry(QModelIndex(), entries, 0, true); + } + + bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entries, const uint32_t entryPathIndex, bool useDisplayName) { if (entries.empty()) { @@ -285,30 +299,43 @@ namespace AzToolsFramework auto rowIdx = model()->index(idx, 0, idxParent); auto rowEntry = GetEntryFromIndex(rowIdx); - // Check if this entry name matches the query - if (rowEntry && AzFramework::StringFunc::Equal(entry.c_str(), rowEntry->GetName().c_str(), true)) + if (rowEntry) { - // Final entry found - set it as the selected element - if (entryPathIndex == entries.size() - 1) - { - selectionModel()->clear(); - selectionModel()->select(rowIdx, QItemSelectionModel::Select); - setCurrentIndex(rowIdx); - return true; - } + // Check if this entry name matches the query + AZStd::string_view compareName = useDisplayName ? (const char*)(rowEntry->GetDisplayName().toUtf8()) : rowEntry->GetName().c_str(); - // If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out) - if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + if (AzFramework::StringFunc::Equal(entry.c_str(), compareName, true)) { - // Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset Browser (otherwise, early out) - if (SelectEntry(rowIdx, entries, entryPathIndex + 1)) + // Final entry found - set it as the selected element + if (entryPathIndex == entries.size() - 1) { - expand(rowIdx); + if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + { + // Expand the item itself if it is a folder + expand(rowIdx); + } + + selectionModel()->clear(); + selectionModel()->select(rowIdx, QItemSelectionModel::Select); + setCurrentIndex(rowIdx); + return true; } + + // If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out) + if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + { + // Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset + // Browser (otherwise, early out) + if (SelectEntry(rowIdx, entries, entryPathIndex + 1, useDisplayName)) + { + expand(rowIdx); + return true; + } + } + + return false; } - - return false; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h index 697396b09e..19cbd3745a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h @@ -60,6 +60,8 @@ namespace AzToolsFramework AZStd::vector GetSelectedAssets() const; + void SelectFolder(AZStd::string_view folderPath); + ////////////////////////////////////////////////////////////////////////// // AssetBrowserViewRequestBus void SelectProduct(AZ::Data::AssetId assetID) override; @@ -67,6 +69,7 @@ namespace AzToolsFramework void ClearFilter() override; void Update() override; + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -105,7 +108,7 @@ namespace AzToolsFramework QString m_name; bool SelectProduct(const QModelIndex& idxParent, AZ::Data::AssetId assetID); - bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entryPathTokens, const uint32_t entryPathIndex = 0); + bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entryPathTokens, const uint32_t entryPathIndex = 0, bool useDisplayName = false); //! Grab one entry from the source thumbnail list and update it void UpdateSCThumbnails(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp index d69eb5559f..23f8378df5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp @@ -769,6 +769,14 @@ namespace AzToolsFramework // Request the AssetBrowser Dialog and set a type filter AssetSelectionModel selection = GetAssetSelectionModel(); selection.SetSelectedAssetId(m_selectedAssetID); + + AZStd::string defaultDirectory; + if (m_defaultDirectoryCallback) + { + m_defaultDirectoryCallback->Invoke(m_editNotifyTarget, defaultDirectory); + selection.SetDefaultDirectory(defaultDirectory); + } + AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget()); if (selection.IsValid()) { @@ -1080,6 +1088,11 @@ namespace AzToolsFramework m_editNotifyCallback = editNotifyCallback; } + void PropertyAssetCtrl::SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback) + { + m_defaultDirectoryCallback = callback; + } + void PropertyAssetCtrl::SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback) { m_clearNotifyCallback = clearNotifyCallback; @@ -1214,6 +1227,11 @@ namespace AzToolsFramework GUI->SetTitle(title.c_str()); } } + else if (attrib == AZ_CRC_CE("DefaultStartingDirectoryCallback")) + { + // This is assumed to be an Asset Browser path to a specific folder to be used as a default by the asset picker if provided + GUI->SetDefaultDirectoryCallback(azdynamic_cast(attrValue->GetAttribute())); + } else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1)) { PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast(attrValue->GetAttribute()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx index e845cdf4fb..37af3d0594 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx @@ -68,6 +68,7 @@ namespace AzToolsFramework // This is meant to be used with the "EditCallback" Attribute using EditCallbackType = AZ::Edit::AttributeFunction; using ClearCallbackType = AZ::Edit::AttributeFunction; + using DefaultDirectoryCallbackType = AZ::Edit::AttributeFunction; PropertyAssetCtrl(QWidget *pParent = NULL, QString optionalValidDragDropExtensions = QString()); virtual ~PropertyAssetCtrl(); @@ -119,6 +120,7 @@ namespace AzToolsFramework EditCallbackType* m_editNotifyCallback = nullptr; ClearCallbackType* m_clearNotifyCallback = nullptr; QString m_optionalValidDragDropExtensions; + DefaultDirectoryCallbackType* m_defaultDirectoryCallback = nullptr; //! The number of characters after which the autocompleter dropdown will be shown. // Prevents showing too many options. @@ -196,6 +198,7 @@ namespace AzToolsFramework void SetEditNotifyTarget(void* editNotifyTarget); void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute + void SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback); // This is meant to be used with the "DefaultStartingDirectoryCallback" Attribute void SetEditButtonEnabled(bool enabled); void SetEditButtonVisible(bool visible); void SetEditButtonIcon(const QIcon& icon); From 2c6c639edeef06009ec9a2fd3961dc159e544994 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Tue, 25 May 2021 10:05:55 -0700 Subject: [PATCH 06/12] merging latest main --- ...ydra_AtomEditorComponents_AddedToEntity.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index 35eaa2e4ce..ff061b5e22 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -32,15 +32,20 @@ def run(): """ Summary: The below common tests are done for each of the components. - 1) Addition of component to the entity - 2) UNDO/REDO of addition of component - 3) Enter/Exit game mode - 4) Hide/Show entity containing component - 5) Deletion of component - 6) UNDO/REDO of deletion of component - Some additional tests for specific components include - 1) Assigning value to some properties of each component - 2) Verifying if the component is activated only when the required components are added + For each test step, it will generate a general.log() message that is used to verify the step was successful. + Each of the test steps for each component are listed below: + 1) Addition of component to the entity + 2) UNDO/REDO of addition of component + 3) Enter/Exit game mode + 4) Hide/Show entity containing component. + 5) Deletion of component + 6) UNDO/REDO of deletion of component + + Some additional tests for specific components include: + 1) "Display Mapper" component having its required "PostFX Layer" component attached. + 2) + 1) Assigning value to some properties of each component + 2) Verifying if the component is activated only when the required components are added Expected Result: 1) Component can be added to an entity. From bdedf419b40a0901595842bd37a45869624cc69e Mon Sep 17 00:00:00 2001 From: jromnoa Date: Tue, 25 May 2021 10:08:11 -0700 Subject: [PATCH 07/12] revert accidental docstring change --- ...ydra_AtomEditorComponents_AddedToEntity.py | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index ff061b5e22..35eaa2e4ce 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -32,20 +32,15 @@ def run(): """ Summary: The below common tests are done for each of the components. - For each test step, it will generate a general.log() message that is used to verify the step was successful. - Each of the test steps for each component are listed below: - 1) Addition of component to the entity - 2) UNDO/REDO of addition of component - 3) Enter/Exit game mode - 4) Hide/Show entity containing component. - 5) Deletion of component - 6) UNDO/REDO of deletion of component - - Some additional tests for specific components include: - 1) "Display Mapper" component having its required "PostFX Layer" component attached. - 2) - 1) Assigning value to some properties of each component - 2) Verifying if the component is activated only when the required components are added + 1) Addition of component to the entity + 2) UNDO/REDO of addition of component + 3) Enter/Exit game mode + 4) Hide/Show entity containing component + 5) Deletion of component + 6) UNDO/REDO of deletion of component + Some additional tests for specific components include + 1) Assigning value to some properties of each component + 2) Verifying if the component is activated only when the required components are added Expected Result: 1) Component can be added to an entity. From 47df212ecdcf17cb803dd24ed7441894b2f1633a Mon Sep 17 00:00:00 2001 From: jromnoa Date: Tue, 25 May 2021 10:08:51 -0700 Subject: [PATCH 08/12] Revert "revert accidental docstring change" This reverts commit bdedf419b40a0901595842bd37a45869624cc69e. --- ...ydra_AtomEditorComponents_AddedToEntity.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index 35eaa2e4ce..ff061b5e22 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -32,15 +32,20 @@ def run(): """ Summary: The below common tests are done for each of the components. - 1) Addition of component to the entity - 2) UNDO/REDO of addition of component - 3) Enter/Exit game mode - 4) Hide/Show entity containing component - 5) Deletion of component - 6) UNDO/REDO of deletion of component - Some additional tests for specific components include - 1) Assigning value to some properties of each component - 2) Verifying if the component is activated only when the required components are added + For each test step, it will generate a general.log() message that is used to verify the step was successful. + Each of the test steps for each component are listed below: + 1) Addition of component to the entity + 2) UNDO/REDO of addition of component + 3) Enter/Exit game mode + 4) Hide/Show entity containing component. + 5) Deletion of component + 6) UNDO/REDO of deletion of component + + Some additional tests for specific components include: + 1) "Display Mapper" component having its required "PostFX Layer" component attached. + 2) + 1) Assigning value to some properties of each component + 2) Verifying if the component is activated only when the required components are added Expected Result: 1) Component can be added to an entity. From 72d394dfca762aefff50d7cb852e4829998e5cad Mon Sep 17 00:00:00 2001 From: jromnoa Date: Tue, 25 May 2021 10:09:08 -0700 Subject: [PATCH 09/12] Revert "merging latest main" This reverts commit 2c6c639edeef06009ec9a2fd3961dc159e544994. --- ...ydra_AtomEditorComponents_AddedToEntity.py | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index ff061b5e22..35eaa2e4ce 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -32,20 +32,15 @@ def run(): """ Summary: The below common tests are done for each of the components. - For each test step, it will generate a general.log() message that is used to verify the step was successful. - Each of the test steps for each component are listed below: - 1) Addition of component to the entity - 2) UNDO/REDO of addition of component - 3) Enter/Exit game mode - 4) Hide/Show entity containing component. - 5) Deletion of component - 6) UNDO/REDO of deletion of component - - Some additional tests for specific components include: - 1) "Display Mapper" component having its required "PostFX Layer" component attached. - 2) - 1) Assigning value to some properties of each component - 2) Verifying if the component is activated only when the required components are added + 1) Addition of component to the entity + 2) UNDO/REDO of addition of component + 3) Enter/Exit game mode + 4) Hide/Show entity containing component + 5) Deletion of component + 6) UNDO/REDO of deletion of component + Some additional tests for specific components include + 1) Assigning value to some properties of each component + 2) Verifying if the component is activated only when the required components are added Expected Result: 1) Component can be added to an entity. From 1d50d7ed6418ba11324ddeab5031c85b14c16001 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Tue, 25 May 2021 10:16:11 -0700 Subject: [PATCH 10/12] Project Manager Projects Screen Dynamically Shows Projects Loaded from O3DE (#873) * Projects Home Screen Dynamically displays Projects from O3DE and can open Project settings editor * Seperated out CreateProjectCtrl and UpdateProjectCtrl * Moved source level statics back into class headers * Updated background image location --- .../Resources/DefaultProjectImage.png | 3 + .../Resources/ProjectManager.qrc | 3 + ...SettingsCtrl.cpp => CreateProjectCtrl.cpp} | 30 ++-- ...jectSettingsCtrl.h => CreateProjectCtrl.h} | 6 +- .../Source/FirstTimeUseScreen.cpp | 11 +- .../Source/FirstTimeUseScreen.h | 7 + .../Source/GemCatalog/GemCatalogScreen.cpp | 5 - .../Source/GemCatalog/GemCatalogScreen.h | 1 - .../Source/NewProjectSettingsScreen.cpp | 5 - .../Source/NewProjectSettingsScreen.h | 1 - .../Source/ProjectButtonWidget.cpp | 102 +++++++++++++ .../Source/ProjectButtonWidget.h | 73 +++++++++ .../Source/ProjectManagerWindow.cpp | 4 +- .../Source/ProjectSettingsScreen.cpp | 17 +++ .../Source/ProjectSettingsScreen.h | 6 + .../Source/ProjectsHomeScreen.cpp | 129 ++++++++++++++-- .../Source/ProjectsHomeScreen.h | 22 ++- .../Source/ProjectsHomeScreen.ui | 137 ----------------- .../ProjectManager/Source/PythonBindings.cpp | 3 +- Code/Tools/ProjectManager/Source/ScreenDefs.h | 3 +- .../ProjectManager/Source/ScreenFactory.cpp | 10 +- .../ProjectManager/Source/ScreenWidget.h | 5 +- .../ProjectManager/Source/ScreensCtrl.cpp | 1 + .../Tools/ProjectManager/Source/ScreensCtrl.h | 3 + .../Source/UpdateProjectCtrl.cpp | 139 ++++++++++++++++++ .../ProjectManager/Source/UpdateProjectCtrl.h | 51 +++++++ .../project_manager_files.cmake | 9 +- 27 files changed, 581 insertions(+), 205 deletions(-) create mode 100644 Code/Tools/ProjectManager/Resources/DefaultProjectImage.png rename Code/Tools/ProjectManager/Source/{ProjectSettingsCtrl.cpp => CreateProjectCtrl.cpp} (77%) rename Code/Tools/ProjectManager/Source/{ProjectSettingsCtrl.h => CreateProjectCtrl.h} (90%) create mode 100644 Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectButtonWidget.h delete mode 100644 Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui create mode 100644 Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp create mode 100644 Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h diff --git a/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png new file mode 100644 index 0000000000..cc1eda5bb8 --- /dev/null +++ b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f22df64b93d4bec91e56b60efa3d5ce2915ce388a2dc627f1ab720678e3d5 +size 334987 diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc index 1ffd7cf3e7..ac55c48a6b 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc @@ -11,6 +11,9 @@ iOS.svg Linux.svg macOS.svg + DefaultProjectImage.png + ArrowDownLine.svg + ArrowUpLine.svg Backgrounds/FirstTimeBackgroundImage.jpg diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp similarity index 77% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 95dcec3e18..03e6a34b89 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include @@ -22,7 +22,7 @@ namespace O3DE::ProjectManager { - ProjectSettingsCtrl::ProjectSettingsCtrl(QWidget* parent) + CreateProjectCtrl::CreateProjectCtrl(QWidget* parent) : ScreenWidget(parent) { QVBoxLayout* vLayout = new QVBoxLayout(); @@ -34,11 +34,11 @@ namespace O3DE::ProjectManager QDialogButtonBox* backNextButtons = new QDialogButtonBox(); vLayout->addWidget(backNextButtons); - m_backButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole); - m_nextButton = backNextButtons->addButton("Next", QDialogButtonBox::ApplyRole); + m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); - connect(m_backButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleBackButton); - connect(m_nextButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleNextButton); + connect(m_backButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleNextButton); m_screensOrder = { @@ -47,15 +47,16 @@ namespace O3DE::ProjectManager }; m_screensCtrl->BuildScreens(m_screensOrder); m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::NewProjectSettings, false); + UpdateNextButtonText(); } - ProjectManagerScreen ProjectSettingsCtrl::GetScreenEnum() + ProjectManagerScreen CreateProjectCtrl::GetScreenEnum() { - return ProjectManagerScreen::NewProjectSettingsCore; + return ProjectManagerScreen::CreateProject; } - void ProjectSettingsCtrl::HandleBackButton() + void CreateProjectCtrl::HandleBackButton() { if (!m_screensCtrl->GotoPreviousScreen()) { @@ -66,7 +67,7 @@ namespace O3DE::ProjectManager UpdateNextButtonText(); } } - void ProjectSettingsCtrl::HandleNextButton() + void CreateProjectCtrl::HandleNextButton() { ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); @@ -116,9 +117,14 @@ namespace O3DE::ProjectManager } } - void ProjectSettingsCtrl::UpdateNextButtonText() + void CreateProjectCtrl::UpdateNextButtonText() { - m_nextButton->setText(m_screensCtrl->GetCurrentScreen()->GetNextButtonText()); + QString nextButtonText = tr("Next"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Create Project"); + } + m_nextButton->setText(nextButtonText); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h similarity index 90% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.h index 42f1ce1978..213bff3bc2 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h @@ -21,12 +21,12 @@ namespace O3DE::ProjectManager { - class ProjectSettingsCtrl + class CreateProjectCtrl : public ScreenWidget { public: - explicit ProjectSettingsCtrl(QWidget* parent = nullptr); - ~ProjectSettingsCtrl() = default; + explicit CreateProjectCtrl(QWidget* parent = nullptr); + ~CreateProjectCtrl() = default; ProjectManagerScreen GetScreenEnum() override; protected slots: diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp index a1be7e8ac9..8654b221fb 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp @@ -21,13 +21,6 @@ namespace O3DE::ProjectManager { - inline constexpr static int s_contentMargins = 80; - inline constexpr static int s_buttonSpacing = 30; - inline constexpr static int s_iconSize = 24; - inline constexpr static int s_spacerSize = 20; - inline constexpr static int s_boxButtonWidth = 210; - inline constexpr static int s_boxButtonHeight = 280; - FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent) : ScreenWidget(parent) { @@ -79,8 +72,8 @@ namespace O3DE::ProjectManager void FirstTimeUseScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void FirstTimeUseScreen::HandleAddProjectButton() { diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h index b6b57dc16b..80a2310d7a 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h @@ -37,6 +37,13 @@ namespace O3DE::ProjectManager QPushButton* m_createProjectButton; QPushButton* m_addProjectButton; + + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_buttonSpacing = 30; + inline constexpr static int s_iconSize = 24; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_boxButtonWidth = 210; + inline constexpr static int s_boxButtonHeight = 280; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index bbc6099f24..7d8cee45b4 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -170,9 +170,4 @@ namespace O3DE::ProjectManager { return ProjectManagerScreen::GemCatalog; } - - QString GemCatalogScreen::GetNextButtonText() - { - return "Create Project"; - } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index bf4202499f..44e0727c7e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit GemCatalogScreen(QWidget* parent = nullptr); ~GemCatalogScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; private: QVector GenerateTestData(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index 153c0964c7..ffbf1bf6fe 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -96,11 +96,6 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::NewProjectSettings; } - QString NewProjectSettingsScreen::GetNextButtonText() - { - return tr("Next"); - } - void NewProjectSettingsScreen::HandleBrowseButton() { QString defaultPath = m_projectPathLineEdit->text(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h index dbd4388668..1cfd3c9c35 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit NewProjectSettingsScreen(QWidget* parent = nullptr); ~NewProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; ProjectInfo GetProjectInfo(); QString GetProjectTemplatePath(); diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp new file mode 100644 index 0000000000..ec1acdad61 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp @@ -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 + +#include +#include +#include +#include +#include +#include +#include +#include + +//#define SHOW_ALL_PROJECT_ACTIONS + +namespace O3DE::ProjectManager +{ + inline constexpr static int s_projectImageWidth = 210; + inline constexpr static int s_projectImageHeight = 280; + + LabelButton::LabelButton(QWidget* parent) + : QLabel(parent) + { + } + + void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event) + { + emit triggered(); + } + + ProjectButton::ProjectButton(const QString& projectName, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(":/Resources/DefaultProjectImage.png") + { + Setup(); + } + + ProjectButton::ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(projectImage) + { + Setup(); + } + + void ProjectButton::Setup() + { + QVBoxLayout* vLayout = new QVBoxLayout(); + vLayout->setSpacing(0); + vLayout->setContentsMargins(0, 0, 0, 0); + setLayout(vLayout); + + m_projectImageLabel = new LabelButton(this); + m_projectImageLabel->setFixedSize(s_projectImageWidth, s_projectImageHeight); + vLayout->addWidget(m_projectImageLabel); + + m_projectImageLabel->setPixmap(QPixmap(m_projectImagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding)); + + QMenu* newProjectMenu = new QMenu(this); + m_editProjectAction = newProjectMenu->addAction(tr("Edit Project Settings...")); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems...")); + newProjectMenu->addSeparator(); + m_copyProjectAction = newProjectMenu->addAction(tr("Duplicate")); + newProjectMenu->addSeparator(); + m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE")); + m_deleteProjectAction = newProjectMenu->addAction(tr("Delete the Project")); +#endif + + m_projectSettingsMenuButton = new QPushButton(this); + m_projectSettingsMenuButton->setText(m_projectName); + m_projectSettingsMenuButton->setMenu(newProjectMenu); + m_projectSettingsMenuButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); + m_projectSettingsMenuButton->setStyleSheet("font-size: 14px; text-align:left;"); + vLayout->addWidget(m_projectSettingsMenuButton); + + setFixedSize(s_projectImageWidth, s_projectImageHeight + m_projectSettingsMenuButton->height()); + + connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); }); + connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); }); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectName); }); + connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectName); }); + connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectName); }); + connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectName); }); +#endif + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h new file mode 100644 index 0000000000..c1aee8e63e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h @@ -0,0 +1,73 @@ +/* + * 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 +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QPixmap) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QAction) + +namespace O3DE::ProjectManager +{ + class LabelButton + : public QLabel + { + Q_OBJECT // AUTOMOC + + public: + explicit LabelButton(QWidget* parent = nullptr); + ~LabelButton() = default; + + signals: + void triggered(); + + public slots: + void mousePressEvent(QMouseEvent* event) override; + }; + + class ProjectButton + : public QFrame + { + Q_OBJECT // AUTOMOC + + public: + explicit ProjectButton(const QString& projectName, QWidget* parent = nullptr); + explicit ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent = nullptr); + ~ProjectButton() = default; + + signals: + void OpenProject(const QString& projectName); + void EditProject(const QString& projectName); + void EditProjectGems(const QString& projectName); + void CopyProject(const QString& projectName); + void RemoveProject(const QString& projectName); + void DeleteProject(const QString& projectName); + + private: + void Setup(); + + QString m_projectName; + QString m_projectImagePath; + LabelButton* m_projectImageLabel; + QPushButton* m_projectSettingsMenuButton; + QAction* m_editProjectAction; + QAction* m_editProjectGemsAction; + QAction* m_copyProjectAction; + QAction* m_removeProjectAction; + QAction* m_deleteProjectAction; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp index 4136b9eb8c..eb79f2da1e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp @@ -50,9 +50,9 @@ namespace O3DE::ProjectManager QVector screenEnums = { ProjectManagerScreen::FirstTimeUse, - ProjectManagerScreen::NewProjectSettingsCore, + ProjectManagerScreen::CreateProject, ProjectManagerScreen::ProjectsHome, - ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::UpdateProject, ProjectManagerScreen::EngineSettings }; m_screensCtrl->BuildScreens(screenEnums); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp index 52fca439b4..76aa1d2897 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp @@ -30,6 +30,23 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::ProjectSettings; } + ProjectInfo ProjectSettingsScreen::GetProjectInfo() + { + // Impl pending next PR + return ProjectInfo(); + } + + void ProjectSettingsScreen::SetProjectInfo() + { + // Impl pending next PR + } + + bool ProjectSettingsScreen::Validate() + { + // Impl pending next PR + return true; + } + void ProjectSettingsScreen::HandleGemsButton() { emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h index 1ec1b46f44..a4cafcd93a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h @@ -13,6 +13,7 @@ #if !defined(Q_MOC_RUN) #include +#include #endif namespace Ui @@ -30,6 +31,11 @@ namespace O3DE::ProjectManager ~ProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; + ProjectInfo GetProjectInfo(); + void SetProjectInfo(); + + bool Validate(); + protected slots: void HandleGemsButton(); diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp index 539f79b017..411b46c55d 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp @@ -12,21 +12,103 @@ #include -#include - +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace O3DE::ProjectManager { ProjectsHomeScreen::ProjectsHomeScreen(QWidget* parent) : ScreenWidget(parent) - , m_ui(new Ui::ProjectsHomeClass()) { - m_ui->setupUi(this); + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins); - connect(m_ui->newProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleNewProjectButton); - connect(m_ui->addProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleAddProjectButton); - connect(m_ui->editProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleEditProjectButton); + QHBoxLayout* topLayout = new QHBoxLayout(); + + QLabel* titleLabel = new QLabel(this); + titleLabel->setText("My Projects"); + titleLabel->setStyleSheet("font-size: 24px"); + topLayout->addWidget(titleLabel); + + QSpacerItem* topSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum); + topLayout->addItem(topSpacer); + + QMenu* newProjectMenu = new QMenu(this); + m_createNewProjectAction = newProjectMenu->addAction("Create New Project"); + m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project"); + + QPushButton* newProjectMenuButton = new QPushButton(this); + newProjectMenuButton->setText("New Project..."); + newProjectMenuButton->setMenu(newProjectMenu); + newProjectMenuButton->setFixedWidth(s_newProjectButtonWidth); + newProjectMenuButton->setStyleSheet("font-size: 14px;"); + topLayout->addWidget(newProjectMenuButton); + + vLayout->addLayout(topLayout); + + // Get all projects and create a horizontal scrolling list of them + auto projectsResult = PythonBindingsInterface::Get()->GetProjects(); + if (projectsResult.IsSuccess() && !projectsResult.GetValue().isEmpty()) + { + QScrollArea* projectsScrollArea = new QScrollArea(this); + QWidget* scrollWidget = new QWidget(); + QGridLayout* projectGridLayout = new QGridLayout(); + scrollWidget->setLayout(projectGridLayout); + projectsScrollArea->setWidget(scrollWidget); + projectsScrollArea->setWidgetResizable(true); + + int gridIndex = 0; + for (auto project : projectsResult.GetValue()) + { + ProjectButton* projectButton; + QString projectPreviewPath = project.m_path + m_projectPreviewImagePath; + QFileInfo doesPreviewExist(projectPreviewPath); + if (doesPreviewExist.exists() && doesPreviewExist.isFile()) + { + projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this); + } + else + { + projectButton = new ProjectButton(project.m_projectName, this); + } + + // Create rows of projects buttons s_projectButtonRowCount buttons wide + projectGridLayout->addWidget(projectButton, gridIndex / s_projectButtonRowCount, gridIndex % s_projectButtonRowCount); + + connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsHomeScreen::HandleOpenProject); + connect(projectButton, &ProjectButton::EditProject, this, &ProjectsHomeScreen::HandleEditProject); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsHomeScreen::HandleEditProjectGems); + connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsHomeScreen::HandleCopyProject); + connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsHomeScreen::HandleRemoveProject); + connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsHomeScreen::HandleDeleteProject); +#endif + ++gridIndex; + } + + vLayout->addWidget(projectsScrollArea); + } + + // Using border-image allows for scaling options background-image does not support + setStyleSheet("O3DE--ProjectManager--ScreenWidget { border-image: url(:/Backgrounds/FirstTimeBackgroundImage.jpg) repeat repeat; }"); + + connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleNewProjectButton); + connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleAddProjectButton); } ProjectManagerScreen ProjectsHomeScreen::GetScreenEnum() @@ -36,16 +118,41 @@ namespace O3DE::ProjectManager void ProjectsHomeScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void ProjectsHomeScreen::HandleAddProjectButton() { // Do nothing for now } - void ProjectsHomeScreen::HandleEditProjectButton() + void ProjectsHomeScreen::HandleOpenProject(const QString& projectPath) { - emit ChangeScreenRequest(ProjectManagerScreen::ProjectSettings); + // Open the editor with this project open + emit NotifyCurrentProject(projectPath); + } + void ProjectsHomeScreen::HandleEditProject(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ResetScreenRequest(ProjectManagerScreen::UpdateProject); + emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject); + } + void ProjectsHomeScreen::HandleEditProjectGems(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); + } + void ProjectsHomeScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath) + { + // Open file dialog and choose location for copied project then register copy with O3DE + } + void ProjectsHomeScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath) + { + // Unregister Project from O3DE + } + void ProjectsHomeScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath) + { + // Remove project from 03DE and delete from disk + ProjectsHomeScreen::HandleRemoveProject(projectPath); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h index 9fd5919d2d..e8d1ac4fb5 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h @@ -15,11 +15,6 @@ #include #endif -namespace Ui -{ - class ProjectsHomeClass; -} - namespace O3DE::ProjectManager { class ProjectsHomeScreen @@ -34,10 +29,23 @@ namespace O3DE::ProjectManager protected slots: void HandleNewProjectButton(); void HandleAddProjectButton(); - void HandleEditProjectButton(); + void HandleOpenProject(const QString& projectPath); + void HandleEditProject(const QString& projectPath); + void HandleEditProjectGems(const QString& projectPath); + void HandleCopyProject(const QString& projectPath); + void HandleRemoveProject(const QString& projectPath); + void HandleDeleteProject(const QString& projectPath); private: - QScopedPointer m_ui; + QAction* m_createNewProjectAction; + QAction* m_addExistingProjectAction; + + const QString m_projectPreviewImagePath = "/preview.png"; + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_projectButtonRowCount = 4; + inline constexpr static int s_newProjectButtonWidth = 156; + }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui deleted file mode 100644 index 2ba93ccf90..0000000000 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui +++ /dev/null @@ -1,137 +0,0 @@ - - - ProjectsHomeClass - - - - 0 - 0 - 826 - 585 - - - - Form - - - - - - My Projects - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - :/Add.svg:/Add.svg - - - - - - - - 0 - 0 - - - - - - - - :/Select_Folder.svg:/Select_Folder.svg - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - Edit Project - - - - - - - Open a Project - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 9a5e82dafb..8c79a153c8 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -540,7 +540,8 @@ namespace O3DE::ProjectManager ProjectInfo PythonBindings::ProjectInfoFromPath(pybind11::handle path) { ProjectInfo projectInfo; - projectInfo.m_path = Py_To_String(path); + projectInfo.m_path = Py_To_String(path); + projectInfo.m_isNew = false; auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path); if (pybind11::isinstance(projectData)) diff --git a/Code/Tools/ProjectManager/Source/ScreenDefs.h b/Code/Tools/ProjectManager/Source/ScreenDefs.h index 658b8d88fd..13289e2481 100644 --- a/Code/Tools/ProjectManager/Source/ScreenDefs.h +++ b/Code/Tools/ProjectManager/Source/ScreenDefs.h @@ -18,10 +18,11 @@ namespace O3DE::ProjectManager Invalid = -1, Empty, FirstTimeUse, - NewProjectSettingsCore, + CreateProject, NewProjectSettings, GemCatalog, ProjectsHome, + UpdateProject, ProjectSettings, EngineSettings }; diff --git a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp index 1089f8ee94..d37ccdb59f 100644 --- a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp +++ b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include #include #include @@ -30,8 +31,8 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::FirstTimeUse): newScreen = new FirstTimeUseScreen(parent); break; - case (ProjectManagerScreen::NewProjectSettingsCore): - newScreen = new ProjectSettingsCtrl(parent); + case (ProjectManagerScreen::CreateProject): + newScreen = new CreateProjectCtrl(parent); break; case (ProjectManagerScreen::NewProjectSettings): newScreen = new NewProjectSettingsScreen(parent); @@ -42,6 +43,9 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::ProjectsHome): newScreen = new ProjectsHomeScreen(parent); break; + case (ProjectManagerScreen::UpdateProject): + newScreen = new UpdateProjectCtrl(parent); + break; case (ProjectManagerScreen::ProjectSettings): newScreen = new ProjectSettingsScreen(parent); break; diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index 483066e031..e80747d67b 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -41,15 +41,12 @@ namespace O3DE::ProjectManager { return true; } - virtual QString GetNextButtonText() - { - return "Next"; - } signals: void ChangeScreenRequest(ProjectManagerScreen screen); void GotoPreviousScreenRequest(); void ResetScreenRequest(ProjectManagerScreen screen); + void NotifyCurrentProject(const QString& projectPath); }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp index b8a38ed155..a77c434026 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp @@ -117,6 +117,7 @@ namespace O3DE::ProjectManager connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen); connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen); connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen); + connect(newScreen, &ScreenWidget::NotifyCurrentProject, this, &ScreensCtrl::NotifyCurrentProject); } void ScreensCtrl::ResetAllScreens() diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h index 7912a314e3..a9d1023b4b 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h @@ -35,6 +35,9 @@ namespace O3DE::ProjectManager ScreenWidget* FindScreen(ProjectManagerScreen screen); ScreenWidget* GetCurrentScreen(); + signals: + void NotifyCurrentProject(const QString& projectPath); + public slots: bool ChangeToScreen(ProjectManagerScreen screen); bool ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit = true); diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp new file mode 100644 index 0000000000..84e3d8359d --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -0,0 +1,139 @@ +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + UpdateProjectCtrl::UpdateProjectCtrl(QWidget* parent) + : ScreenWidget(parent) + { + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + + m_screensCtrl = new ScreensCtrl(); + vLayout->addWidget(m_screensCtrl); + + QDialogButtonBox* backNextButtons = new QDialogButtonBox(); + vLayout->addWidget(backNextButtons); + + m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); + + connect(m_backButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleNextButton); + connect(reinterpret_cast(parent), &ScreensCtrl::NotifyCurrentProject, this, &UpdateProjectCtrl::UpdateCurrentProject); + + m_screensOrder = + { + ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::GemCatalog + }; + m_screensCtrl->BuildScreens(m_screensOrder); + m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::ProjectSettings, false); + + UpdateNextButtonText(); + + } + + ProjectManagerScreen UpdateProjectCtrl::GetScreenEnum() + { + return ProjectManagerScreen::UpdateProject; + } + + void UpdateProjectCtrl::HandleBackButton() + { + if (!m_screensCtrl->GotoPreviousScreen()) + { + emit GotoPreviousScreenRequest(); + } + else + { + UpdateNextButtonText(); + } + } + void UpdateProjectCtrl::HandleNextButton() + { + ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); + ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); + auto screenOrderIter = m_screensOrder.begin(); + for (; screenOrderIter != m_screensOrder.end(); ++screenOrderIter) + { + if (*screenOrderIter == screenEnum) + { + ++screenOrderIter; + break; + } + } + + if (screenEnum == ProjectManagerScreen::ProjectSettings) + { + auto projectScreen = reinterpret_cast(currentScreen); + if (projectScreen) + { + if (!projectScreen->Validate()) + { + QMessageBox::critical(this, tr("Invalid project settings"), tr("Invalid project settings")); + return; + } + + m_projectInfo = projectScreen->GetProjectInfo(); + } + } + + if (screenOrderIter != m_screensOrder.end()) + { + m_screensCtrl->ChangeToScreen(*screenOrderIter); + UpdateNextButtonText(); + } + else + { + auto result = PythonBindingsInterface::Get()->UpdateProject(m_projectInfo); + if (result) + { + emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome); + } + else + { + QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project.")); + } + } + } + + void UpdateProjectCtrl::UpdateCurrentProject(const QString& projectPath) + { + auto projectResult = PythonBindingsInterface::Get()->GetProject(projectPath); + if (projectResult.IsSuccess()) + { + m_projectInfo = projectResult.GetValue(); + } + } + + void UpdateProjectCtrl::UpdateNextButtonText() + { + QString nextButtonText = tr("Continue"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Update Project"); + } + m_nextButton->setText(nextButtonText); + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h new file mode 100644 index 0000000000..ee871e7bb2 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h @@ -0,0 +1,51 @@ +/* + * 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 "ProjectInfo.h" +#include +#include +#include +#endif + + +namespace O3DE::ProjectManager +{ + class UpdateProjectCtrl + : public ScreenWidget + { + public: + explicit UpdateProjectCtrl(QWidget* parent = nullptr); + ~UpdateProjectCtrl() = default; + ProjectManagerScreen GetScreenEnum() override; + + + protected slots: + void HandleBackButton(); + void HandleNextButton(); + void UpdateCurrentProject(const QString& projectPath); + + private: + void UpdateNextButtonText(); + + ScreensCtrl* m_screensCtrl; + QPushButton* m_backButton; + QPushButton* m_nextButton; + QVector m_screensOrder; + + ProjectInfo m_projectInfo; + + ProjectManagerScreen m_screenEnum; + }; + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 16bc8cf965..5fd2b4a9d8 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -41,16 +41,19 @@ set(FILES Source/ProjectInfo.cpp Source/NewProjectSettingsScreen.h Source/NewProjectSettingsScreen.cpp - Source/ProjectSettingsCtrl.h - Source/ProjectSettingsCtrl.cpp + Source/CreateProjectCtrl.h + Source/CreateProjectCtrl.cpp + Source/UpdateProjectCtrl.h + Source/UpdateProjectCtrl.cpp Source/ProjectsHomeScreen.h Source/ProjectsHomeScreen.cpp - Source/ProjectsHomeScreen.ui Source/ProjectSettingsScreen.h Source/ProjectSettingsScreen.cpp Source/ProjectSettingsScreen.ui Source/EngineSettingsScreen.h Source/EngineSettingsScreen.cpp + Source/ProjectButtonWidget.h + Source/ProjectButtonWidget.cpp Source/LinkWidget.h Source/LinkWidget.cpp Source/TagWidget.h From 0be75732cc1e3c82e9bd3f70c5a759102948c03f Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 25 May 2021 12:44:34 -0500 Subject: [PATCH 11/12] Added initial support for nested slices to slice-prefab converter (#881) Nested slices are now detected, converted into prefabs, and the top-level prefab will get linked to the nested prefabs with the proper number of instances. However, the nested prefabs won't retain any of the slice override values or parent entity hierarchy. That will (hopefully) be added in a separate PR. This also adds support for better relative source paths for nested prefabs. To support this, the tool now needs to connect/disconnect with the AssetProcessor to be able to turn a slice asset ID into a relative source path, so that nested templates can be looked up and converted correctly. --- .../SerializeContextTools/Application.cpp | 5 + .../Tools/SerializeContextTools/Application.h | 1 + .../SerializeContextTools/SliceConverter.cpp | 420 ++++++++++++++---- .../SerializeContextTools/SliceConverter.h | 17 +- .../EditorSurfaceDataSystemComponent.cpp | 2 + .../gem_autoload.serializecontexttools.setreg | 12 + 6 files changed, 357 insertions(+), 100 deletions(-) diff --git a/Code/Tools/SerializeContextTools/Application.cpp b/Code/Tools/SerializeContextTools/Application.cpp index da0cca5ca6..81cc314deb 100644 --- a/Code/Tools/SerializeContextTools/Application.cpp +++ b/Code/Tools/SerializeContextTools/Application.cpp @@ -97,6 +97,11 @@ namespace AZ return m_configFilePath.c_str(); } + void Application::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const + { + appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Tool; + } + void Application::SetSettingsRegistrySpecializations(AZ::SettingsRegistryInterface::Specializations& specializations) { AZ::ComponentApplication::SetSettingsRegistrySpecializations(specializations); diff --git a/Code/Tools/SerializeContextTools/Application.h b/Code/Tools/SerializeContextTools/Application.h index b1b818e27d..b4c02b87c2 100644 --- a/Code/Tools/SerializeContextTools/Application.h +++ b/Code/Tools/SerializeContextTools/Application.h @@ -28,6 +28,7 @@ namespace AZ const char* GetConfigFilePath() const; AZ::ComponentTypeList GetRequiredSystemComponents() const override; + void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; protected: void SetSettingsRegistrySpecializations(AZ::SettingsRegistryInterface::Specializations& specializations) override; diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp index a18a6ff3a3..3fbf7cb25c 100644 --- a/Code/Tools/SerializeContextTools/SliceConverter.cpp +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -25,8 +25,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -36,7 +39,6 @@ // SliceConverter reads in a slice file (saved in an ObjectStream format), instantiates it, creates a prefab out of the data, // and saves the prefab in a JSON format. This can be used for one-time migrations of slices or slice-based levels to prefabs. -// This converter is still in an early state. It can convert trivial slices, but it cannot handle nested slices yet. // // If the slice contains legacy data, it will print out warnings / errors about the data that couldn't be serialized. // The prefab will be generated without that data. @@ -70,6 +72,20 @@ namespace AZ AZ_Error("Convert-Slice", false, "No json registration context found."); return false; } + + // Connect to the Asset Processor so that we can get the correct source path to any nested slice references. + if (!ConnectToAssetProcessor()) + { + AZ_Error("Convert-Slice", false, " Failed to connect to the Asset Processor.\n"); + return false; + } + + // Load the asset catalog so that we can find any nested assets successfully. We also need to tick the tick bus + // so that the OnCatalogLoaded event gets processed now, instead of during application shutdown. + AZ::Data::AssetCatalogRequestBus::Broadcast( + &AZ::Data::AssetCatalogRequestBus::Events::LoadCatalog, "@assets@/assetcatalog.xml"); + application.Tick(); + AZStd::string logggingScratchBuffer; SetupLogging(logggingScratchBuffer, convertSettings.m_reporting, *commandLine); @@ -80,83 +96,90 @@ namespace AZ verifySettings.m_serializeContext = application.GetSerializeContext(); SetupLogging(logggingScratchBuffer, verifySettings.m_reporting, *commandLine); - auto archiveInterface = AZ::Interface::Get(); - - // Find the Prefab System Component for use in creating and saving the prefab - AZ::Entity* systemEntity = application.FindEntity(AZ::SystemEntityId); - AZ_Assert(systemEntity != nullptr, "System entity doesn't exist."); - auto prefabSystemComponent = systemEntity->FindComponent(); - AZ_Assert(prefabSystemComponent != nullptr, "Prefab System component doesn't exist"); - bool result = true; rapidjson::StringBuffer scratchBuffer; + // Loop through the list of requested files and convert them. AZStd::vector fileList = Utilities::ReadFileListFromCommandLine(application, "files"); for (AZStd::string& filePath : fileList) { - bool packOpened = false; - - AZ::IO::Path outputPath = filePath; - outputPath.ReplaceExtension("prefab"); - - AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); - AZ_Printf("Convert-Slice", "Converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); - - AZ::IO::Path inputPath = filePath; - auto fileExtension = inputPath.Extension(); - if (fileExtension == ".ly") - { - // Special case: for level files, we need to open the .ly zip file and convert the levelentities.editor_xml file - // inside of it. All the other files can be ignored as they are deprecated legacy system files that are no longer - // loaded with prefab-based levels. - packOpened = archiveInterface->OpenPack(filePath); - inputPath.ReplaceFilename("levelentities.editor_xml"); - AZ_Warning("Convert-Slice", packOpened, " '%s' could not be opened as a pack file.\n", filePath.c_str()); - } - else - { - AZ_Warning( - "Convert-Slice", (fileExtension == ".slice"), - " Warning: Only .ly and .slice files are supported, conversion of '%.*s' may not work.\n", - AZ_STRING_ARG(fileExtension.Native())); - } - - auto callback = [prefabSystemComponent, &outputPath, isDryRun] - (void* classPtr, const Uuid& classId, [[maybe_unused]] SerializeContext* context) - { - if (classId != azrtti_typeid()) - { - AZ_Printf("Convert-Slice", " File not converted: Slice root is not an entity.\n"); - return false; - } - - AZ::Entity* rootEntity = reinterpret_cast(classPtr); - return ConvertSliceFile(prefabSystemComponent, outputPath, isDryRun, rootEntity); - }; - - if (!Utilities::InspectSerializedFile(inputPath.c_str(), convertSettings.m_serializeContext, callback)) - { - AZ_Warning("Convert-Slice", false, "Failed to load '%s'. File may not contain an object stream.", inputPath.c_str()); - result = false; - } - - if (packOpened) - { - [[maybe_unused]] bool closeResult = archiveInterface->ClosePack(filePath); - AZ_Warning("Convert-Slice", closeResult, "Failed to close '%s'.", filePath.c_str()); - } - - AZ_Printf("Convert-Slice", "Finished converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); - AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + bool convertResult = ConvertSliceFile(convertSettings.m_serializeContext, filePath, isDryRun); + result = result && convertResult; } + DisconnectFromAssetProcessor(); return result; } bool SliceConverter::ConvertSliceFile( - AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, AZ::IO::PathView outputPath, bool isDryRun, - AZ::Entity* rootEntity) + AZ::SerializeContext* serializeContext, const AZStd::string& slicePath, bool isDryRun) { + bool result = true; + bool packOpened = false; + + auto archiveInterface = AZ::Interface::Get(); + + AZ::IO::Path outputPath = slicePath; + outputPath.ReplaceExtension("prefab"); + + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + AZ_Printf("Convert-Slice", "Converting '%s' to '%s'\n", slicePath.c_str(), outputPath.c_str()); + + AZ::IO::Path inputPath = slicePath; + auto fileExtension = inputPath.Extension(); + if (fileExtension == ".ly") + { + // Special case: for level files, we need to open the .ly zip file and convert the levelentities.editor_xml file + // inside of it. All the other files can be ignored as they are deprecated legacy system files that are no longer + // loaded with prefab-based levels. + packOpened = archiveInterface->OpenPack(slicePath); + inputPath.ReplaceFilename("levelentities.editor_xml"); + AZ_Warning("Convert-Slice", packOpened, " '%s' could not be opened as a pack file.\n", slicePath.c_str()); + } + else + { + AZ_Warning( + "Convert-Slice", (fileExtension == ".slice"), + " Warning: Only .ly and .slice files are supported, conversion of '%.*s' may not work.\n", + AZ_STRING_ARG(fileExtension.Native())); + } + + auto callback = [&outputPath, isDryRun](void* classPtr, const Uuid& classId, SerializeContext* context) + { + if (classId != azrtti_typeid()) + { + AZ_Printf("Convert-Slice", " File not converted: Slice root is not an entity.\n"); + return false; + } + + AZ::Entity* rootEntity = reinterpret_cast(classPtr); + return ConvertSliceToPrefab(context, outputPath, isDryRun, rootEntity); + }; + + // Read in the slice file and call the callback on completion to convert the read-in slice to a prefab. + if (!Utilities::InspectSerializedFile(inputPath.c_str(), serializeContext, callback)) + { + AZ_Warning("Convert-Slice", false, "Failed to load '%s'. File may not contain an object stream.", inputPath.c_str()); + result = false; + } + + if (packOpened) + { + [[maybe_unused]] bool closeResult = archiveInterface->ClosePack(slicePath); + AZ_Warning("Convert-Slice", closeResult, "Failed to close '%s'.", slicePath.c_str()); + } + + AZ_Printf("Convert-Slice", "Finished converting '%s' to '%s'\n", slicePath.c_str(), outputPath.c_str()); + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + + return result; + } + + bool SliceConverter::ConvertSliceToPrefab( + AZ::SerializeContext* serializeContext, AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity) + { + auto prefabSystemComponentInterface = AZ::Interface::Get(); + // Find the slice from the root entity. SliceComponent* sliceComponent = AZ::EntityUtils::FindFirstDerivedComponent(rootEntity); if (sliceComponent == nullptr) @@ -167,44 +190,21 @@ namespace AZ // Get all of the entities from the slice. SliceComponent::EntityList sliceEntities = sliceComponent->GetNewEntities(); - if (sliceEntities.empty()) - { - AZ_Printf("Convert-Slice", " File not converted: Slice entities could not be retrieved.\n"); - return false; - } - - AZ_Warning("Convert-Slice", sliceComponent->GetSlices().empty(), " Slice depends on other slices, this conversion will lose data.\n"); + AZ_Printf("Convert-Slice", " Slice contains %zu entities.\n", sliceEntities.size()); // Create the Prefab with the entities from the slice AZStd::unique_ptr sourceInstance( - prefabSystemComponent->CreatePrefab(sliceEntities, {}, outputPath)); + prefabSystemComponentInterface->CreatePrefab(sliceEntities, {}, outputPath)); // Dispatch events here, because prefab creation might trigger asset loads in rare circumstances. AZ::Data::AssetManager::Instance().DispatchEvents(); - // Set up the Prefab container entity to be a proper Editor entity. (This logic is normally triggered - // via an EditorRequests EBus in CreatePrefab, but the subsystem that listens for it isn't present in this tool.) + // Fix up the container entity to have the proper components and fix up the slice entities to have the proper hierarchy + // with the container as the top-most parent. AzToolsFramework::Prefab::EntityOptionalReference container = sourceInstance->GetContainerEntity(); - AzToolsFramework::EditorEntityContextRequestBus::Broadcast( - &AzToolsFramework::EditorEntityContextRequestBus::Events::AddRequiredComponents, container->get()); - container->get().AddComponent(aznew AzToolsFramework::Prefab::EditorPrefabComponent()); - - // Reparent any root-level slice entities to the container entity. - for (auto entity : sliceEntities) - { - AzToolsFramework::Components::TransformComponent* transformComponent = - entity->FindComponent(); - if (transformComponent) - { - if (!transformComponent->GetParentId().IsValid()) - { - transformComponent->SetParent(container->get().GetId()); - } - } - } + FixPrefabEntities(container->get(), sliceEntities); auto templateId = sourceInstance->GetTemplateId(); - if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) { AZ_Printf("Convert-Slice", " Path error. Path could be invalid, or the prefab may not be loaded in this level.\n"); @@ -219,14 +219,27 @@ namespace AZ AZ_Printf("Convert-Slice", " Failed to convert prefab instance data to a PrefabDom.\n"); return false; } - prefabSystemComponent->UpdatePrefabTemplate(templateId, prefabDom); + prefabSystemComponentInterface->UpdatePrefabTemplate(templateId, prefabDom); // Dispatch events here, because prefab serialization might trigger asset loads in rare circumstances. AZ::Data::AssetManager::Instance().DispatchEvents(); + // If this slice has nested slices, we need to loop through those, convert them to prefabs as well, and + // set up the new nesting relationships correctly. + const SliceComponent::SliceList& sliceList = sliceComponent->GetSlices(); + AZ_Printf("Convert-Slice", " Slice contains %zu nested slices.\n", sliceList.size()); + if (!sliceList.empty()) + { + bool nestedSliceResult = ConvertNestedSlices(sliceComponent, sourceInstance.get(), serializeContext, isDryRun); + if (!nestedSliceResult) + { + return false; + } + } + if (isDryRun) { - PrintPrefab(prefabDom, sourceInstance->GetTemplateSourcePath()); + PrintPrefab(templateId); return true; } else @@ -235,8 +248,187 @@ namespace AZ } } - void SliceConverter::PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath) + void SliceConverter::FixPrefabEntities(AZ::Entity& containerEntity, SliceComponent::EntityList& sliceEntities) { + // Set up the Prefab container entity to be a proper Editor entity. (This logic is normally triggered + // via an EditorRequests EBus in CreatePrefab, but the subsystem that listens for it isn't present in this tool.) + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequestBus::Events::AddRequiredComponents, containerEntity); + containerEntity.AddComponent(aznew AzToolsFramework::Prefab::EditorPrefabComponent()); + + // Reparent any root-level slice entities to the container entity. + for (auto entity : sliceEntities) + { + AzToolsFramework::Components::TransformComponent* transformComponent = + entity->FindComponent(); + if (transformComponent) + { + if (!transformComponent->GetParentId().IsValid()) + { + transformComponent->SetParent(containerEntity.GetId()); + transformComponent->UpdateCachedWorldTransform(); + } + } + } + } + + bool SliceConverter::ConvertNestedSlices( + SliceComponent* sliceComponent, AzToolsFramework::Prefab::Instance* sourceInstance, + AZ::SerializeContext* serializeContext, bool isDryRun) + { + const SliceComponent::SliceList& sliceList = sliceComponent->GetSlices(); + auto prefabSystemComponentInterface = AZ::Interface::Get(); + + for (auto& slice : sliceList) + { + // Get the nested slice asset + auto sliceAsset = slice.GetSliceAsset(); + sliceAsset.QueueLoad(); + sliceAsset.BlockUntilLoadComplete(); + + // The slice list gives us asset IDs, and we need to get to the source path. So first we get the asset path from the ID, + // then we get the source path from the asset path. + + AZStd::string processedAssetPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + processedAssetPath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, sliceAsset.GetId()); + + AZStd::string assetPath; + AzToolsFramework::AssetSystemRequestBus::Broadcast( + &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, + processedAssetPath, assetPath); + if (assetPath.empty()) + { + AZ_Warning("Convert-Slice", false, + " Source path for nested slice '%s' could not be found, slice not converted.", processedAssetPath.c_str()); + return false; + } + + // Now, convert the nested slice to a prefab. + bool nestedSliceResult = ConvertSliceFile(serializeContext, assetPath, isDryRun); + if (!nestedSliceResult) + { + AZ_Warning("Convert-Slice", nestedSliceResult, " Nested slice '%s' could not be converted.", assetPath.c_str()); + return false; + } + + // Load the prefab template for the newly-created nested prefab. + // To get the template, we need to take our absolute slice path and turn it into a project-relative prefab path. + AZ::IO::Path nestedPrefabPath = assetPath; + nestedPrefabPath.ReplaceExtension("prefab"); + + auto prefabLoaderInterface = AZ::Interface::Get(); + nestedPrefabPath = prefabLoaderInterface->GetRelativePathToProject(nestedPrefabPath); + + AzToolsFramework::Prefab::TemplateId nestedTemplateId = + prefabSystemComponentInterface->GetTemplateIdFromFilePath(nestedPrefabPath); + AzToolsFramework::Prefab::TemplateReference nestedTemplate = + prefabSystemComponentInterface->FindTemplate(nestedTemplateId); + + // For each slice instance of the nested slice, convert it to a nested prefab instance instead. + + auto instances = slice.GetInstances(); + AZ_Printf( + "Convert-Slice", " Attaching %zu instances of nested slice '%s'.\n", instances.size(), + nestedPrefabPath.Native().c_str()); + + for (auto& instance : instances) + { + bool instanceConvertResult = ConvertSliceInstance(instance, sliceAsset, nestedTemplate, sourceInstance); + if (!instanceConvertResult) + { + return false; + } + } + } + + return true; + } + + bool SliceConverter::ConvertSliceInstance( + [[maybe_unused]] AZ::SliceComponent::SliceInstance& instance, + [[maybe_unused]] AZ::Data::Asset& sliceAsset, + AzToolsFramework::Prefab::TemplateReference nestedTemplate, + AzToolsFramework::Prefab::Instance* topLevelInstance) + { + auto instanceToTemplateInterface = AZ::Interface::Get(); + auto prefabSystemComponentInterface = AZ::Interface::Get(); + + // Create a new unmodified prefab Instance for the nested slice instance. + auto nestedInstance = AZStd::make_unique(); + AzToolsFramework::Prefab::Instance::EntityList newEntities; + if (!AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom( + *nestedInstance, newEntities, nestedTemplate->get().GetPrefabDom())) + { + AZ_Error( + "Convert-Slice", false, " Failed to load and instantiate nested Prefab Template '%s'.", + nestedTemplate->get().GetFilePath().c_str()); + return false; + } + + // Get the DOM for the unmodified nested instance. This will be used later below for generating the correct patch + // to the top-level template DOM. + AzToolsFramework::Prefab::PrefabDom unmodifiedNestedInstanceDom; + instanceToTemplateInterface->GenerateDomForInstance(unmodifiedNestedInstanceDom, *(nestedInstance.get())); + + // Currently, DataPatch conversions for nested slices aren't implemented, so all nested slice overrides will + // be lost. + AZ_Warning( + "Convert-Slice", false, " Nested slice instances will lose all of their override data during conversion.", + nestedTemplate->get().GetFilePath().c_str()); + + // Set the container entity of the nested prefab to have the top-level prefab as the parent. + // Once DataPatch conversions are supported, this will need to change to nest the prefab under the appropriate entity + // within the level. + auto containerEntity = nestedInstance->GetContainerEntity(); + AzToolsFramework::Components::TransformComponent* transformComponent = + containerEntity->get().FindComponent(); + if (transformComponent) + { + transformComponent->SetParent(topLevelInstance->GetContainerEntityId()); + transformComponent->UpdateCachedWorldTransform(); + } + + // Add the nested instance itself to the top-level prefab. To do this, we need to add it to our top-level instance, + // create a patch out of it, and patch the top-level prefab template. + + AzToolsFramework::Prefab::PrefabDom topLevelInstanceDomBefore; + instanceToTemplateInterface->GenerateDomForInstance(topLevelInstanceDomBefore, *topLevelInstance); + + AzToolsFramework::Prefab::Instance& addedInstance = topLevelInstance->AddInstance(AZStd::move(nestedInstance)); + + AzToolsFramework::Prefab::PrefabDom topLevelInstanceDomAfter; + instanceToTemplateInterface->GenerateDomForInstance(topLevelInstanceDomAfter, *topLevelInstance); + + AzToolsFramework::Prefab::PrefabDom addedInstancePatch; + instanceToTemplateInterface->GeneratePatch(addedInstancePatch, topLevelInstanceDomBefore, topLevelInstanceDomAfter); + instanceToTemplateInterface->PatchTemplate(addedInstancePatch, topLevelInstance->GetTemplateId()); + + // Get the DOM for the modified nested instance. Now that the data has been fixed up, and the instance has been added + // to the top-level instance, we've got all the changes we need to generate the correct patch. + + AzToolsFramework::Prefab::PrefabDom modifiedNestedInstanceDom; + instanceToTemplateInterface->GenerateDomForInstance(modifiedNestedInstanceDom, addedInstance); + + AzToolsFramework::Prefab::PrefabDom linkPatch; + instanceToTemplateInterface->GeneratePatch(linkPatch, unmodifiedNestedInstanceDom, modifiedNestedInstanceDom); + + prefabSystemComponentInterface->CreateLink( + topLevelInstance->GetTemplateId(), addedInstance.GetTemplateId(), addedInstance.GetInstanceAlias(), linkPatch, + AzToolsFramework::Prefab::InvalidLinkId); + prefabSystemComponentInterface->PropagateTemplateChanges(topLevelInstance->GetTemplateId()); + + return true; + } + + void SliceConverter::PrintPrefab(AzToolsFramework::Prefab::TemplateId templateId) + { + auto prefabSystemComponentInterface = AZ::Interface::Get(); + + auto prefabTemplate = prefabSystemComponentInterface->FindTemplate(templateId); + auto& prefabDom = prefabTemplate->get().GetPrefabDom(); + const AZ::IO::Path& templatePath = prefabTemplate->get().GetFilePath(); + rapidjson::StringBuffer prefabBuffer; rapidjson::PrettyWriter writer(prefabBuffer); prefabDom.Accept(writer); @@ -260,5 +452,41 @@ namespace AZ return true; } + bool SliceConverter::ConnectToAssetProcessor() + { + AzFramework::AssetSystem::ConnectionSettings connectionSettings; + AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); + + connectionSettings.m_launchAssetProcessorOnFailedConnection = true; + connectionSettings.m_connectionDirection = + AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; + connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Editor; + connectionSettings.m_loggingCallback = [](AZStd::string_view logData) + { + AZ_Printf("Convert-Slice", "%.*s\n", AZ_STRING_ARG(logData)); + }; + + bool connectedToAssetProcessor = false; + + AzFramework::AssetSystemRequestBus::BroadcastResult( + connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, + connectionSettings); + + return connectedToAssetProcessor; + } + + void SliceConverter::DisconnectFromAssetProcessor() + { + AzFramework::AssetSystemRequestBus::Broadcast( + &AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); + + // Wait for the disconnect to finish. + bool disconnected = false; + AzFramework::AssetSystemRequestBus::BroadcastResult(disconnected, + &AzFramework::AssetSystem::AssetSystemRequests::WaitUntilAssetProcessorDisconnected, AZStd::chrono::seconds(30)); + + AZ_Error("Convert-Slice", disconnected, "Asset Processor failed to disconnect successfully."); + } + } // namespace SerializeContextTools } // namespace AZ diff --git a/Code/Tools/SerializeContextTools/SliceConverter.h b/Code/Tools/SerializeContextTools/SliceConverter.h index 90dfa0d50a..8dba6a0e55 100644 --- a/Code/Tools/SerializeContextTools/SliceConverter.h +++ b/Code/Tools/SerializeContextTools/SliceConverter.h @@ -42,11 +42,20 @@ namespace AZ static bool ConvertSliceFiles(Application& application); private: + static bool ConnectToAssetProcessor(); + static void DisconnectFromAssetProcessor(); - static bool ConvertSliceFile(AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, - AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity); - - static void PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath); + static bool ConvertSliceFile(AZ::SerializeContext* serializeContext, const AZStd::string& slicePath, bool isDryRun); + static bool ConvertSliceToPrefab( + AZ::SerializeContext* serializeContext, AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity); + static void FixPrefabEntities(AZ::Entity& containerEntity, SliceComponent::EntityList& sliceEntities); + static bool ConvertNestedSlices( + SliceComponent* sliceComponent, AzToolsFramework::Prefab::Instance* sourceInstance, + AZ::SerializeContext* serializeContext, bool isDryRun); + static bool SliceConverter::ConvertSliceInstance( + AZ::SliceComponent::SliceInstance& instance, AZ::Data::Asset& sliceAsset, + AzToolsFramework::Prefab::TemplateReference nestedTemplate, AzToolsFramework::Prefab::Instance* topLevelInstance); + static void PrintPrefab(AzToolsFramework::Prefab::TemplateId templateId); static bool SavePrefab(AzToolsFramework::Prefab::TemplateId templateId); }; } // namespace SerializeContextTools diff --git a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataSystemComponent.cpp b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataSystemComponent.cpp index 4dcc969434..4703977ab4 100644 --- a/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataSystemComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Editor/EditorSurfaceDataSystemComponent.cpp @@ -118,6 +118,8 @@ namespace SurfaceData void EditorSurfaceDataSystemComponent::Deactivate() { + m_surfaceTagNameAssets.clear(); + AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); AzToolsFramework::Components::EditorComponentBase::Deactivate(); SurfaceDataTagProviderRequestBus::Handler::BusDisconnect(); diff --git a/Registry/gem_autoload.serializecontexttools.setreg b/Registry/gem_autoload.serializecontexttools.setreg index 1f4a8931c5..e7e88dd6a6 100644 --- a/Registry/gem_autoload.serializecontexttools.setreg +++ b/Registry/gem_autoload.serializecontexttools.setreg @@ -9,6 +9,18 @@ }, "PythonAssetBuilder.Editor": { "AutoLoad": false + }, + "AWSCore.Editor": { + "AutoLoad": false + }, + "AWSClientAuth": { + "AutoLoad": false + }, + "AWSClientAuth.Editor": { + "AutoLoad": false + }, + "AWSMetrics": { + "AutoLoad": false } } } From 3aa6969d199cc4ece38cfe9698f8fda4e591839b Mon Sep 17 00:00:00 2001 From: sharmajs-amzn <82233357+sharmajs-amzn@users.noreply.github.com> Date: Tue, 25 May 2021 11:13:29 -0700 Subject: [PATCH 12/12] disabling rccontrollertest (#874) --- .../native/tests/resourcecompiler/RCControllerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCControllerTest.cpp b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCControllerTest.cpp index b08fbc28d5..1da4703f3d 100644 --- a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCControllerTest.cpp +++ b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCControllerTest.cpp @@ -224,7 +224,7 @@ void RCcontrollerTest_Simple::SubmitJob() // This is a regresssion test to ensure the rccontroller can handle multiple jobs for the same file being completed before // the APM has a chance to send OnFinishedProcesssingJob events -TEST_F(RCcontrollerTest_Simple, SameJobIsCompletedMultipleTimes_CompletesWithoutError) +TEST_F(RCcontrollerTest_Simple, DISABLED_SameJobIsCompletedMultipleTimes_CompletesWithoutError) { using namespace AssetProcessor;