You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeDelegate.h

144 lines
7.1 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/ToolsComponents/EditorLockComponentBus.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
namespace AzToolsFramework
{
namespace ComponentModeFramework
{
/// Utility factory function to create a ComponentModeBuilder for a specific EditorComponent
template<typename EditorComponentType, typename EditorComponentModeType>
ComponentModeBuilder CreateComponentModeBuilder(const AZ::EntityComponentIdPair& entityComponentIdPair)
{
const auto componentModeBuilderFunc = [entityComponentIdPair]()
{
return AZStd::make_unique<EditorComponentModeType>(
entityComponentIdPair, AZ::AzTypeInfo<EditorComponentType>::Uuid());
};
return ComponentModeBuilder(
entityComponentIdPair.GetComponentId(), AZ::AzTypeInfo<EditorComponentType>::Uuid(), componentModeBuilderFunc);
}
/// Helper to provide ComponentMode button in the Entity Inspector and double click
/// handling in the viewport for entering/exiting ComponentMode.
class ComponentModeDelegate
: private ComponentModeDelegateRequestBus::Handler
, private EntitySelectionEvents::Bus::Handler
, private EditorEntityVisibilityNotificationBus::Handler
, private EditorEntityLockComponentNotificationBus::Handler
{
public:
/// @cond
AZ_CLASS_ALLOCATOR(ComponentModeDelegate, AZ::SystemAllocator, 0);
AZ_RTTI(ComponentModeDelegate, "{635B28F0-601A-43D2-A42A-02C4A88CD9C2}");
static void Reflect(AZ::ReflectContext* context);
/// @endcond
/// Connect the ComponentModeDelegate to listen for Editor selection events.
/// Editor Component must call Connect (or variant of Connect), usually in Component::Activate, and
/// Disconnect, most likely in Component::Deactivate.
template<typename EditorComponentType>
void Connect(
const AZ::EntityComponentIdPair& entityComponentIdPair, EditorComponentSelectionRequestsBus::Handler* handler)
{
ConnectInternal(entityComponentIdPair, AZ::AzTypeInfo<EditorComponentType>::Uuid(), handler);
}
/// Connect the ComponentModeDelegate to listen for Editor selection events and
/// simultaneously add a single concrete ComponentMode (common case utility).
template<typename EditorComponentType, typename EditorComponentModeType>
void ConnectWithSingleComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, EditorComponentSelectionRequestsBus::Handler* handler)
{
Connect<EditorComponentType>(entityComponentIdPair, handler);
IndividualComponentMode<EditorComponentType, EditorComponentModeType>();
}
/// Disconnect the ComponentModeDelegate to stop listening for Editor selection events.
void Disconnect();
/// Has this specific ComponentModeDelegate (for a specific Entity and Component)
/// been added to ComponentMode.
bool AddedToComponentMode();
/// The function to call when this ComponentModeDelegate detects an event to enter ComponentMode.
void SetAddComponentModeCallback(
const AZStd::function<void(const AZ::EntityComponentIdPair&)>& addComponentModeCallback);
private:
void ConnectInternal(
const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType,
EditorComponentSelectionRequestsBus::Handler* handler);
/// Utility function for the common case of creating a single ComponentMode for a Component.
template<typename EditorComponentType, typename EditorComponentModeType>
void IndividualComponentMode()
{
SetAddComponentModeCallback([](const AZ::EntityComponentIdPair& entityComponentIdPair)
{
const auto componentModeBuilder =
CreateComponentModeBuilder<EditorComponentType, EditorComponentModeType>(entityComponentIdPair);
const auto entityAndComponentModeBuilder =
EntityAndComponentModeBuilders(entityComponentIdPair.GetEntityId(), componentModeBuilder);
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddComponentModes, entityAndComponentModeBuilder);
});
}
void AddComponentMode();
// EntitySelectionEvents
void OnSelected() override;
void OnDeselected() override;
// ComponentModeDelegateRequestBus
bool DetectEnterComponentModeInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool DetectLeaveComponentModeInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
void AddComponentModeOfType(AZ::Uuid componentType) override;
// EditorEntityVisibilityNotificationBus
void OnEntityVisibilityChanged(bool visibility) override;
// EditorEntityLockComponentNotificationBus
void OnEntityLockChanged(bool locked) override;
/// Is the ComponentMode button active/operational.
/// It will not be if the entity with this component is either locked or hidden.
/// It will also not be active if the Entity is pinned but not selected.
bool ComponentModeButtonInactive() const;
AZ::Uuid m_componentType; ///< The type of component entering ComponentMode.
AZ::EntityComponentIdPair m_entityComponentIdPair; ///< The Entity and Component Id this ComponentMode is bound to.
EditorComponentSelectionRequestsBus::Handler* m_handler = nullptr; /**< Selection handler (used for double clicking
* on a component to enter ComponentMode). */
AZStd::function<void(const AZ::EntityComponentIdPair&)> m_addComponentMode; ///< Callback to add ComponentMode for this component.
/// ComponentMode Button
void OnComponentModeEnterButtonPressed();
void OnComponentModeLeaveButtonPressed();
};
/// If this Entity had a Component supporting a ComponentMode, would
/// it be possible for it to enter it given the current Editor state.
bool CouldBeginComponentModeWithEntity(AZ::EntityId entityId);
} // namespace ComponentModeFramework
} // namespace AzToolsFramework