Call sites for activating/deactivating viewport editor modes. (#4265)

* Provisional impl and testing of central state tracker.

Signed-off-by: John <jonawals@amazon.com>

* Add missing namespace comment.

Signed-off-by: John <jonawals@amazon.com>

* ViewportEditorModeState -> ViewportEditorModes

Signed-off-by: John <jonawals@amazon.com>

* ViewportEditorModesTracker -> ViewportEditorModeTracker

Signed-off-by: John <jonawals@amazon.com>

* GetEditorModeState ->GetViewportEditorModes

Signed-off-by: John <jonawals@amazon.com>

* GetNumTrackedViewports -> GetTrackedViewportCount

Signed-off-by: John <jonawals@amazon.com>

* IsViewportStateBeingTracked -> IsViewportModeTracked

Signed-off-by: John <jonawals@amazon.com>

* Fix API comments.

Signed-off-by: John <jonawals@amazon.com>

* Delete hangover file.

Signed-off-by: John <jonawals@amazon.com>

* Delete more hangover files.

Signed-off-by: John <jonawals@amazon.com>

* Minor member name refactor.

Signed-off-by: John <jonawals@amazon.com>

* Refactor nonclemanture.

Signed-off-by: John <jonawals@amazon.com>

* Rename Enter/ExitMode to Register/UnregisterMode.

Signed-off-by: John <jonawals@amazon.com>

* Error and warning msgs now return AZ::Outcomes.

Signed-off-by: John <jonawals@amazon.com>

* Change all nomenclature to Activate/Deactivate for consistency.

Signed-off-by: John <jonawals@amazon.com>

* Change tense of notification bus methods.

Signed-off-by: John <jonawals@amazon.com>

* Fix malformed string format.

Signed-off-by: John <jonawals@amazon.com>

* Fix malformed string format (again).

Signed-off-by: John <jonawals@amazon.com>

* Fix Linux warning.

Signed-off-by: John <jonawals@amazon.com>

* Call sites for editor mode activate/deactivate.

Signed-off-by: John <jonawals@amazon.com>

* Move Component editor mode logic to ComponentModeCollection.

Signed-off-by: John <jonawals@amazon.com>

* Delete non-source data.

Signed-off-by: John <jonawals@amazon.com>

* Remove line breaks and forward declare class.

Signed-off-by: John <jonawals@amazon.com>

* Remove constructors without ViewportEditorModeTrackerInterface ptr.

Signed-off-by: John <jonawals@amazon.com>

* Add integration tests for viewport editor modes.

Signed-off-by: John <jonawals@amazon.com>

* Address PR comments.

Signed-off-by: John <jonawals@amazon.com>
This commit is contained in:
jonawals
2021-09-30 15:36:42 +01:00
committed by GitHub
parent 08e020f2b1
commit fa47b35580
15 changed files with 182 additions and 74 deletions
@@ -8,8 +8,9 @@
#include "ComponentModeCollection.h"
#include <AzToolsFramework/Commands/ComponentModeCommand.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/Commands/ComponentModeCommand.h>
namespace AzToolsFramework
{
@@ -17,7 +18,7 @@ namespace AzToolsFramework
{
AZ_CLASS_ALLOCATOR_IMPL(ComponentModeCollection, AZ::SystemAllocator, 0)
static const char* const s_nextActiveComponentModeTitle = "Edit Next";
static const char* const s_nextActiveComponentModeTitle = "Edit Next";
static const char* const s_previousActiveComponentModeTitle = "Edit Previous";
static const char* const s_nextActiveComponentModeDesc = "Move to the next component";
static const char* const s_prevActiveComponentModeDesc = "Move to the previous component";
@@ -119,6 +120,11 @@ namespace AzToolsFramework
}
};
ComponentModeCollection::ComponentModeCollection(ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
: m_viewportEditorModeTracker(viewportEditorModeTracker)
{
}
void ComponentModeCollection::AddComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid componentType,
const ComponentModeFactoryFunction& componentModeBuilder)
@@ -209,6 +215,11 @@ namespace AzToolsFramework
GetEntityContextId(), &EditorComponentModeNotifications::EnteredComponentMode,
m_activeComponentTypes);
// this call to activate the component mode editor state should eventually replace the bus call in
// ComponentModeCollection::BeginComponentMode() to EditorComponentModeNotifications::EnteredComponentMode
// such that all of the notifications for activating/deactivating the different editor modes are in a central location
m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Component);
// enable actions for the first/primary ComponentMode
// note: if multiple ComponentModes are activated at the same time, actions
// are not available together, the 'active' mode will bind its actions one at a time
@@ -282,6 +293,10 @@ namespace AzToolsFramework
&EditorComponentModeNotifications::LeftComponentMode,
m_activeComponentTypes);
// this call to deactivate the component mode editor state should eventually replace the bus call in
// ComponentModeCollection::EndComponentMode() to EditorComponentModeNotifications::LeftComponentMode
// such that all of the notifications for activating/deactivating the different editor modes are in a central location
m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Component);
// clear stored modes and builders for this ComponentMode
// TLDR: avoid 'use after free' error
@@ -15,6 +15,7 @@
namespace AzToolsFramework
{
class EditorMetricsEventsBusTraits;
class ViewportEditorModeTrackerInterface;
namespace ComponentModeFramework
{
@@ -25,7 +26,7 @@ namespace AzToolsFramework
AZ_CLASS_ALLOCATOR_DECL
/// @cond
ComponentModeCollection() = default;
explicit ComponentModeCollection(ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
~ComponentModeCollection() = default;
ComponentModeCollection(const ComponentModeCollection&) = delete;
ComponentModeCollection& operator=(const ComponentModeCollection&) = delete;
@@ -101,6 +102,7 @@ namespace AzToolsFramework
size_t m_selectedComponentModeIndex = 0; ///< Index into the array of active ComponentModes, current index is 'selected' ComponentMode.
bool m_adding = false; ///< Are we currently adding individual ComponentModes to the Editor wide ComponentMode.
bool m_componentMode = false; ///< Editor (global) ComponentMode flag - is ComponentMode active or not.
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; //!< Tracker for activating/deactivating viewport editor modes.
};
} // namespace ComponentModeFramework
} // namespace AzToolsFramework
@@ -119,11 +119,12 @@ namespace AzToolsFramework
// replace the default input handler with one specific for dealing with
// entity selection in the viewport
EditorInteractionSystemViewportSelectionRequestBus::Event(
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetHandler,
[](const EditorVisibleEntityDataCache* entityDataCache)
[](const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
{
return AZStd::make_unique<EditorPickEntitySelection>(entityDataCache);
return AZStd::make_unique<EditorPickEntitySelection>(entityDataCache, viewportEditorModeTracker);
});
if (!pickModeEntityContextId.IsNull())
@@ -22,6 +22,7 @@
#include <AZTestShared/Math/MathTestHelpers.h>
#include <AZTestShared/Utils/Utils.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/Entity/EditorEntityTransformBus.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
@@ -166,11 +167,12 @@ namespace UnitTest
m_editorActions.Connect();
const auto viewportHandlerBuilder =
[this](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache)
[this](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
{
// create the default viewport (handles ComponentMode)
AZStd::unique_ptr<AzToolsFramework::EditorDefaultSelection> defaultSelection =
AZStd::make_unique<AzToolsFramework::EditorDefaultSelection>(entityDataCache);
AZStd::make_unique<AzToolsFramework::EditorDefaultSelection>(entityDataCache, viewportEditorModeTracker);
// override the phantom widget so we can use out custom test widget
defaultSelection->SetOverridePhantomWidget(&m_editorActions.m_componentModeWidget);
@@ -9,6 +9,7 @@
#include "EditorDefaultSelection.h"
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
@@ -19,21 +20,26 @@ namespace AzToolsFramework
{
AZ_CLASS_ALLOCATOR_IMPL(EditorDefaultSelection, AZ::SystemAllocator, 0)
EditorDefaultSelection::EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache)
EditorDefaultSelection::EditorDefaultSelection(
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
: m_phantomWidget(nullptr)
, m_entityDataCache(entityDataCache)
, m_viewportEditorModeTracker(viewportEditorModeTracker)
, m_componentModeCollection(viewportEditorModeTracker)
{
ActionOverrideRequestBus::Handler::BusConnect(GetEntityContextId());
ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusConnect();
m_manipulatorManager = AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
m_transformComponentSelection = AZStd::make_unique<EditorTransformComponentSelection>(entityDataCache);
m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Default);
}
EditorDefaultSelection::~EditorDefaultSelection()
{
ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusDisconnect();
ActionOverrideRequestBus::Handler::BusDisconnect();
m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Default);
}
void EditorDefaultSelection::SetOverridePhantomWidget(QWidget* phantomOverrideWidget)
@@ -15,6 +15,8 @@
namespace AzToolsFramework
{
class ViewportEditorModeTrackerInterface;
//! The default selection/input handler for the editor (includes handling ComponentMode).
class EditorDefaultSelection
: public ViewportInteraction::InternalViewportSelectionRequests
@@ -25,7 +27,7 @@ namespace AzToolsFramework
AZ_CLASS_ALLOCATOR_DECL
//! @cond
explicit EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache);
EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
EditorDefaultSelection(const EditorDefaultSelection&) = delete;
EditorDefaultSelection& operator=(const EditorDefaultSelection&) = delete;
virtual ~EditorDefaultSelection();
@@ -110,5 +112,7 @@ namespace AzToolsFramework
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager; //!< The default manipulator manager.
ViewportInteraction::MouseInteraction m_currentInteraction; //!< Current mouse interaction to be used for drawing manipulators.
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; //!< Tracker for activating/deactivating viewport editor modes.
};
} // namespace AzToolsFramework
@@ -10,9 +10,24 @@
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
#include <AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h>
namespace AzToolsFramework
{
EditorInteractionSystemComponent::EditorInteractionSystemComponent()
: m_viewportEditorMode(AZStd::make_unique<ViewportEditorModeTracker>())
{
AZ_Assert(AZ::Interface<ViewportEditorModeTrackerInterface>::Get() == nullptr, "Unexpected registration of viewport editor mode tracker.")
AZ::Interface<ViewportEditorModeTrackerInterface>::Register(m_viewportEditorMode.get());
}
EditorInteractionSystemComponent::~EditorInteractionSystemComponent()
{
m_interactionRequests.reset();
AZ_Assert(AZ::Interface<ViewportEditorModeTrackerInterface>::Get() != nullptr, "Unexpected unregistration of viewport editor mode tracker.")
AZ::Interface<ViewportEditorModeTrackerInterface>::Unregister(m_viewportEditorMode.get());
}
void EditorInteractionSystemComponent::Activate()
{
EditorInteractionSystemViewportSelectionRequestBus::Handler::BusConnect(GetEntityContextId());
@@ -41,7 +56,8 @@ namespace AzToolsFramework
return m_interactionRequests->InternalHandleMouseManipulatorInteraction(mouseInteraction);
}
void EditorInteractionSystemComponent::SetHandler(const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder)
void EditorInteractionSystemComponent::SetHandler(
const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder)
{
// when setting a handler, make sure we're connected to the ViewportDebugDisplayEventBus so we
// can forward calls to the specific type implementing ViewportSelectionRequests
@@ -59,7 +75,7 @@ namespace AzToolsFramework
m_entityDataCache = AZStd::make_unique<EditorVisibleEntityDataCache>();
m_interactionRequests.reset(); // BusConnect/Disconnect in constructor/destructor,
// so have to reset before assigning the new one
m_interactionRequests = interactionRequestsBuilder(m_entityDataCache.get());
m_interactionRequests = interactionRequestsBuilder(m_entityDataCache.get(), m_viewportEditorMode.get());
}
EditorInteractionSystemViewportSelectionRequestBus::Handler::BusConnect(GetEntityContextId());
@@ -68,9 +84,9 @@ namespace AzToolsFramework
void EditorInteractionSystemComponent::SetDefaultHandler()
{
SetHandler(
[](const EditorVisibleEntityDataCache* entityDataCache)
[](const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
{
return AZStd::make_unique<EditorDefaultSelection>(entityDataCache);
return AZStd::make_unique<EditorDefaultSelection>(entityDataCache, viewportEditorModeTracker);
});
}
@@ -14,6 +14,8 @@
namespace AzToolsFramework
{
class ViewportEditorModeTracker;
//! System Component to wrap active input handler.
//! EditorInteractionSystemComponent is notified of viewport mouse events from RenderViewport
//! and forwards them to a concrete implementation of ViewportSelectionRequests.
@@ -26,6 +28,9 @@ namespace AzToolsFramework
public:
AZ_COMPONENT(EditorInteractionSystemComponent, "{146D0317-AF42-45AB-A953-F54198525DD5}")
EditorInteractionSystemComponent();
~EditorInteractionSystemComponent();
static void Reflect(AZ::ReflectContext* context);
// EditorInteractionSystemViewportSelectionRequestBus
@@ -54,5 +59,7 @@ namespace AzToolsFramework
AZStd::unique_ptr<InternalViewportSelectionRequests> m_interactionRequests; //!< Hold a concrete implementation of
//!< ViewportSelectionRequests to handle viewport
//!< input and drawing for the Editor.
AZStd::unique_ptr<ViewportEditorModeTracker> m_viewportEditorMode; //!< Editor mode tracker for each viewport.
};
} // namespace AzToolsFramework
@@ -17,6 +17,7 @@
namespace AzToolsFramework
{
class EditorVisibleEntityDataCache;
class ViewportEditorModeTrackerInterface;
//! Bus to handle all mouse events originating from the viewport.
//! Coordinated by the EditorInteractionSystemComponent
@@ -32,8 +33,8 @@ namespace AzToolsFramework
};
//! Alias for factory function to create a new type implementing the ViewportSelectionRequests interface.
using ViewportSelectionRequestsBuilderFn =
AZStd::function<AZStd::unique_ptr<ViewportInteraction::InternalViewportSelectionRequests>(const EditorVisibleEntityDataCache*)>;
using ViewportSelectionRequestsBuilderFn = AZStd::function<AZStd::unique_ptr<ViewportInteraction::InternalViewportSelectionRequests>(
const EditorVisibleEntityDataCache*, ViewportEditorModeTrackerInterface*)>;
//! Interface for system component implementing the ViewportSelectionRequests interface.
//! This interface also includes a setter to set a custom handler also implementing
@@ -8,6 +8,7 @@
#include "EditorPickEntitySelection.h"
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <QApplication>
@@ -15,9 +16,12 @@ namespace AzToolsFramework
{
AZ_CLASS_ALLOCATOR_IMPL(EditorPickEntitySelection, AZ::SystemAllocator, 0)
EditorPickEntitySelection::EditorPickEntitySelection(const EditorVisibleEntityDataCache* entityDataCache)
EditorPickEntitySelection::EditorPickEntitySelection(
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
: m_editorHelpers(AZStd::make_unique<EditorHelpers>(entityDataCache))
, m_viewportEditorModeTracker(viewportEditorModeTracker)
{
m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Pick);
}
EditorPickEntitySelection::~EditorPickEntitySelection()
@@ -26,6 +30,8 @@ namespace AzToolsFramework
{
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false);
}
m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Pick);
}
// note: entityIdUnderCursor is the authoritative entityId we get each frame by querying
@@ -13,6 +13,8 @@
namespace AzToolsFramework
{
class ViewportEditorModeTrackerInterface;
//! Viewport interaction that will handle assigning an entity in the viewport to
//! an entity field in the entity inspector.
class EditorPickEntitySelection : public ViewportInteraction::InternalViewportSelectionRequests
@@ -20,7 +22,8 @@ namespace AzToolsFramework
public:
AZ_CLASS_ALLOCATOR_DECL
EditorPickEntitySelection(const EditorVisibleEntityDataCache* entityDataCache);
EditorPickEntitySelection(
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
~EditorPickEntitySelection();
private:
@@ -32,5 +35,6 @@ namespace AzToolsFramework
AZStd::unique_ptr<EditorHelpers> m_editorHelpers; //!< Editor visualization of entities (icons, shapes, debug visuals etc).
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; //!< Tracker for activating/deactivating viewport editor modes.
};
} // namespace AzToolsFramework
@@ -45,22 +45,6 @@ namespace AzToolsFramework
return m_editorModes[static_cast<AZ::u32>(mode)];
}
void ViewportEditorModeTracker::RegisterInterface()
{
if (AZ::Interface<ViewportEditorModeTrackerInterface>::Get() == nullptr)
{
AZ::Interface<ViewportEditorModeTrackerInterface>::Register(this);
}
}
void ViewportEditorModeTracker::UnregisterInterface()
{
if (AZ::Interface<ViewportEditorModeTrackerInterface>::Get() != nullptr)
{
AZ::Interface<ViewportEditorModeTrackerInterface>::Unregister(this);
}
}
AZ::Outcome<void, AZStd::string> ViewportEditorModeTracker::ActivateMode(
const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode)
{
@@ -41,12 +41,6 @@ namespace AzToolsFramework
: public ViewportEditorModeTrackerInterface
{
public:
//! Registers this object with the AZ::Interface.
void RegisterInterface();
//! Unregisters this object with the AZ::Interface.
void UnregisterInterface();
// ViewportEditorModeTrackerInterface overrides ...
AZ::Outcome<void, AZStd::string> ActivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;
AZ::Outcome<void, AZStd::string> DeactivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;