/* * 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 <AzCore/Serialization/SerializeContext.h> #include <AzFramework/Components/TransformComponent.h> #include <AzFramework/Entity/EntityContext.h> #include <AzTest/AzTest.h> #include <AzToolsFramework/Application/ToolsApplication.h> #include <AzToolsFramework/API/EntityCompositionRequestBus.h> #include <AzToolsFramework/ComponentMode/ComponentModeCollection.h> #include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h> #include <AzToolsFramework/ToolsComponents/EditorLockComponent.h> #include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h> #include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h> #include <AzToolsFramework/ToolsComponents/TransformComponent.h> #include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx> #include <AzToolsFramework/Viewport/ActionBus.h> #include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h> #include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h> #include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h> #include <AzCore/UnitTest/TestTypes.h> #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h> #include <AzToolsFramework/UnitTest/ComponentModeTestDoubles.h> #include <AzToolsFramework/UnitTest/ComponentModeTestFixture.h> #include <QtTest/QtTest> #include <QApplication> namespace UnitTest { using namespace AzToolsFramework; using namespace AzToolsFramework::ComponentModeFramework; TEST_F(ComponentModeTestFixture, BeginEndComponentMode) { using ::testing::Eq; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); QWidget rootWidget; ActionOverrideRequestBus::Event( GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, &rootWidget); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::BeginComponentMode, AZStd::vector<EntityAndComponentModeBuilders>{}); bool inComponentMode = false; ComponentModeSystemRequestBus::BroadcastResult( inComponentMode, &ComponentModeSystemRequests::InComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then EXPECT_TRUE(inComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::EndComponentMode); ComponentModeSystemRequestBus::BroadcastResult( inComponentMode, &ComponentModeSystemRequests::InComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then EXPECT_FALSE(inComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// ActionOverrideRequestBus::Event( GetEntityContextId(), &ActionOverrideRequests::TeardownActionOverrideHandler); } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeBothBegin) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); const AZ::Component* placeholder2 = entity->CreateComponent<PlaceholderEditorComponent>(); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool firstComponentModeInstantiated = false; ComponentModeSystemRequestBus::BroadcastResult( firstComponentModeInstantiated, &ComponentModeSystemRequests::ComponentModeInstantiated, AZ::EntityComponentIdPair(entityId, placeholder1->GetId())); bool secondComponentModeInstantiated = false; ComponentModeSystemRequestBus::BroadcastResult( secondComponentModeInstantiated, &ComponentModeSystemRequests::ComponentModeInstantiated, AZ::EntityComponentIdPair(entityId, placeholder2->GetId())); EXPECT_TRUE(firstComponentModeInstantiated && secondComponentModeInstantiated); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, OneComponentModeBeginsWithTwoComponentsOnSingleEntityEachWithDifferentComponentModes) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); const AZ::Component* placeholder2 = entity->CreateComponent<AnotherPlaceholderEditorComponent>(); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool firstComponentModeInstantiated = false; ComponentModeSystemRequestBus::BroadcastResult( firstComponentModeInstantiated, &ComponentModeSystemRequests::ComponentModeInstantiated, AZ::EntityComponentIdPair(entityId, placeholder1->GetId())); bool secondComponentModeInstantiated = true; ComponentModeSystemRequestBus::BroadcastResult( secondComponentModeInstantiated, &ComponentModeSystemRequests::ComponentModeInstantiated, AZ::EntityComponentIdPair(entityId, placeholder2->GetId())); EXPECT_TRUE(firstComponentModeInstantiated && !secondComponentModeInstantiated); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeDoNotCycle) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); AZ_UNUSED(placeholder1); const AZ::Component* placeholder2 = entity->CreateComponent<PlaceholderEditorComponent>(); AZ_UNUSED(placeholder2); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid()); bool nextModeCycled = true; ComponentModeSystemRequestBus::BroadcastResult( nextModeCycled, &ComponentModeSystemRequests::SelectNextActiveComponentMode); bool previousModeCycled = true; ComponentModeSystemRequestBus::BroadcastResult( previousModeCycled, &ComponentModeSystemRequests::SelectPreviousActiveComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then EXPECT_TRUE(!nextModeCycled && !previousModeCycled); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeHasOnlyOneType) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); AZ_UNUSED(placeholder1); const AZ::Component* placeholder2 = entity->CreateComponent<PlaceholderEditorComponent>(); AZ_UNUSED(placeholder2); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = true; ComponentModeSystemRequestBus::BroadcastResult( multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); EXPECT_FALSE(multipleComponentModeTypes); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithDifferentComponentModeHasOnlyOneType) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); AZ_UNUSED(placeholder1); const AZ::Component* placeholder2 = entity->CreateComponent<AnotherPlaceholderEditorComponent>(); AZ_UNUSED(placeholder2); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<AnotherPlaceholderEditorComponent>::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = true; ComponentModeSystemRequestBus::BroadcastResult( multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); EXPECT_FALSE(multipleComponentModeTypes); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithDependentComponentModesHasTwoTypes) { using testing::Eq; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // setup default editor interaction model EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<AnotherPlaceholderEditorComponent>(); AZ_UNUSED(placeholder1); // DependentPlaceholderEditorComponent has a Component Mode dependent on AnotherPlaceholderEditorComponent const AZ::Component* placeholder2 = entity->CreateComponent<DependentPlaceholderEditorComponent>(); AZ_UNUSED(placeholder2); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<DependentPlaceholderEditorComponent>::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = false; ComponentModeSystemRequestBus::BroadcastResult( multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); bool secondComponentModeInstantiated = false; ComponentModeSystemRequestBus::BroadcastResult( secondComponentModeInstantiated, &ComponentModeSystemRequests::ComponentModeInstantiated, AZ::EntityComponentIdPair(entityId, placeholder2->GetId())); AZ::Uuid activeComponentType = AZ::Uuid::CreateNull(); ComponentModeSystemRequestBus::BroadcastResult( activeComponentType, &ComponentModeSystemRequests::ActiveComponentMode); EXPECT_TRUE(multipleComponentModeTypes); EXPECT_TRUE(secondComponentModeInstantiated); EXPECT_THAT(activeComponentType, Eq(AZ::AzTypeInfo<DependentPlaceholderEditorComponent>::Uuid())); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeBothTriggerSameAction) { using testing::Eq; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given const auto viewportHandlerBuilder = [this](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache) { // create the default viewport (handles ComponentMode) AZStd::unique_ptr<EditorDefaultSelection> defaultSelection = AZStd::make_unique<EditorDefaultSelection>(entityDataCache); // override the phantom widget so we can use out custom test widget defaultSelection->SetOverridePhantomWidget(&m_editorActions.m_testWidget); return defaultSelection; }; // setup default editor interaction model with the phantom widget overridden EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetHandler, viewportHandlerBuilder); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // add two placeholder Components (each with their own Component Mode) const AZ::Component* placeholder1 = entity->CreateComponent<PlaceholderEditorComponent>(); const AZ::Component* placeholder2 = entity->CreateComponent<PlaceholderEditorComponent>(); entity->Activate(); // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; ToolsApplicationRequestBus::Broadcast( &ToolsApplicationRequests::SetSelectedEntities, entityIds); // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid()); // Component Modes are now instantiated // create a simple signal checker type which implements the ComponentModeActionSignalNotificationBus const int checkerBusId = 1234; ComponentModeActionSignalNotificationChecker checker(checkerBusId); // when a shortcut action happens, we want to send a message to the checker bus // internally PlaceHolderComponentMode sets up an action to send an event to // ComponentModeActionSignalNotifications::OnActionTriggered - we make sure each // Component Mode is will sent the notification to the correct address. ComponentModeActionSignalRequestBus::Event( AZ::EntityComponentIdPair(entityId, placeholder1->GetId()), &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId); ComponentModeActionSignalRequestBus::Event( AZ::EntityComponentIdPair(entityId, placeholder2->GetId()), &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // trigger the shortcut for this Component Mode QTest::keyPress(&m_editorActions.m_testWidget, Qt::Key_Space); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then // ensure the checker count is what we expect (both Component Modes will notify the // ComponentModeActionSignalNotificationChecker connected at the address specified) EXPECT_THAT(checker.GetCount(), Eq(2)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, ShouldIgnoreMouseEventWhenOverridenByComponentMode) { using OverrideMouseInteractionComponent = TestComponentModeComponent<OverrideMouseInteractionComponentMode>; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given // Setup default editor interaction model. EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // Add placeholder component which implements component mode. const AZ::Component* placeholder1 = entity->CreateComponent<OverrideMouseInteractionComponent>(); entity->Activate(); // Mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) SelectEntities({ entityId }); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // Move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) EnterComponentMode<OverrideMouseInteractionComponent>(); ViewportInteraction::MouseInteractionEvent interactionEvent; interactionEvent.m_mouseEvent = ViewportInteraction::MouseEvent::Move; // Simulate a mouse event using MouseInteractionResult = AzToolsFramework::ViewportInteraction::MouseInteractionResult; MouseInteractionResult handled = MouseInteractionResult::None; EditorInteractionSystemViewportSelectionRequestBus::BroadcastResult( handled, &EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleAllMouseInteractions, interactionEvent); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then // Check it was handled by the component mode. EXPECT_EQ(handled, MouseInteractionResult::Viewport); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } // Test version of EntityPropertyEditor to detect/ensure certain functions were called class TestEntityPropertyEditor : public AzToolsFramework::EntityPropertyEditor { public: void InvalidatePropertyDisplay(PropertyModificationRefreshLevel level) override; bool m_invalidatePropertyDisplayCalled = false; }; void TestEntityPropertyEditor::InvalidatePropertyDisplay(PropertyModificationRefreshLevel level) { m_invalidatePropertyDisplayCalled = true; } // Simple fixture to encapsulate a TestEntityPropertyEditor class ComponentModePinnedSelectionFixture : public ToolsApplicationFixture { public: void SetUpEditorFixtureImpl() override { EditorInteractionSystemViewportSelectionRequestBus::Event( GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler); m_testEntityPropertyEditor = AZStd::make_unique<TestEntityPropertyEditor>(); } AZStd::unique_ptr<TestEntityPropertyEditor> m_testEntityPropertyEditor; }; TEST_F(ComponentModePinnedSelectionFixture, CannotEnterComponentModeWhenEntityIsPinnedButNotSelected) { using PlaceHolderComponent = TestComponentModeComponent<PlaceHolderComponentMode>; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); // Add placeholder component which implements component mode. entity->CreateComponent<PlaceHolderComponent>(); entity->Activate(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // select entity const auto selectedEntities = AzToolsFramework::EntityIdList { entityId }; SelectEntities(selectedEntities); // pin entity AzToolsFramework::EntityIdSet selectedSet(selectedEntities.begin(), selectedEntities.end()); m_testEntityPropertyEditor->SetOverrideEntityIds(selectedSet); // deselect entity SelectEntities(AzToolsFramework::EntityIdList{}); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then EXPECT_TRUE(m_testEntityPropertyEditor->IsLockedToSpecificEntities()); EXPECT_TRUE(m_testEntityPropertyEditor->m_invalidatePropertyDisplayCalled); bool couldBeginComponentMode = AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId); EXPECT_FALSE(couldBeginComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } TEST_F(ComponentModeTestFixture, CannotEnterComponentModeWhenThereArePendingComponents) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given AZ::Entity* entity = nullptr; AZ::EntityId entityId = CreateDefaultEditorEntity("ComponentModeEntity", &entity); entity->Deactivate(); AzToolsFramework::EntityCompositionRequestBus::Broadcast( &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{entityId}, AZ::ComponentTypeList{ AZ::AzTypeInfo<AnotherPlaceholderEditorComponent>::Uuid() }); AzToolsFramework::EntityCompositionRequestBus::Broadcast( &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{entityId}, AZ::ComponentTypeList{AZ::AzTypeInfo<IncompatiblePlaceholderEditorComponent>::Uuid()}); entity->Activate(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When SelectEntities(AzToolsFramework::EntityIdList{entityId}); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then AZ::Entity::ComponentArrayType pendingComponents; AzToolsFramework::EditorPendingCompositionRequestBus::Event( entityId, &AzToolsFramework::EditorPendingCompositionRequestBus::Events::GetPendingComponents, pendingComponents); // ensure we do have pending components EXPECT_EQ(pendingComponents.size(), 1); // cannot enter Component Mode with pending components EXPECT_FALSE(AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } } // namespace UnitTest