// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Math/Color.h" #include "UObject/ObjectKey.h" #include "UObject/NameTypes.h" #include "Templates/PimplPtr.h" #include "Templates/SharedPointer.h" #include "Containers/ArrayView.h" #include "Curves/KeyHandle.h" #include "MovieSceneCommonHelpers.h" #include "Channels/MovieSceneChannelHandle.h" struct FCurveModelID; struct FRichCurve; struct FKeyDrawParams; struct FMovieSceneChannel; struct FMovieSceneChannelProxy; struct FSequencerChannelPaintArgs; struct FSequencerPasteEnvironment; struct ISequencerChannelInterface; struct FMovieSceneChannelMetaData; struct FMovieSceneClipboardEnvironment; struct FGeometry; class SWidget; class ISequencer; class FCurveModel; class FStructOnScope; class ISequencerSection; class UMovieSceneSection; class FMovieSceneClipboardBuilder; class FMovieSceneClipboardKeyTrack; class FSequencerSectionPainter; /** * Interface that should be implemented for the UI portion of a key area within a section */ class SEQUENCER_API IKeyArea : public TSharedFromThis { public: /** Serial number of the node tree from the last time this key area was seen */ uint32 TreeSerialNumber; /** * Constructor * * @param InSection The section that owns the channel that this key area represents * @param InChannel Handle to the channel this key area represents */ IKeyArea(TWeakPtr InSection, FMovieSceneChannelHandle InChannel, const FCurveModelID& InCurveId); /** * Reinitialize this key area with a new channel * * @param InSection The section that owns the channel that this key area represents * @param InChannel Handle to the channel this key area represents */ void Reinitialize(TWeakPtr InSection, FMovieSceneChannelHandle InChannel); public: /** * Locate the sequencer channel interface for this key area's channel * @note: Channel interfaces are registered via ISequencerModule::RegisterChannelInterface * * @return The channel interface, or nullptr if one was not found */ ISequencerChannelInterface* FindChannelEditorInterface() const; /** * Access the channel type identifier for the channel that this key area wraps * * @return The name of the channel type */ FName GetChannelTypeName() const { return ChannelHandle.GetChannelTypeName(); } /** * Access the channel handle that this key area represents * * @return The (potentially invalid) channel handle */ const FMovieSceneChannelHandle& GetChannel() const { return ChannelHandle; } /** * Resolve this key area's channel handle * * @return A (potentially invalid) interface to this key area's channel */ FMovieSceneChannel* ResolveChannel() const; /** * Get this key area's name * * @return This key area's name */ FName GetName() const; /** * Set this key area's name * * @param InName This key area's name */ void SetName(FName InName); /** * Get the color of this channel that should be drawn underneath its keys * * @return (Optional) This channel's color */ TOptional GetColor() const { return Color; } /** * Access section that owns the channel this key area represents * * @return The owning section, or nullptr if it has been destroyed */ UMovieSceneSection* GetOwningSection() const; /** * Access object that owns the channel this key area represents. * @note: this may return the same as GetOwningSection (the common case) * * @return The owning object, or nullptr if it has been destroyed */ UObject* GetOwningObject() const; /** * Access section editor interface * * @return The owning section interface, or nullptr if it has been destroyed */ TSharedPtr GetSectionInterface() const; /** * Check whether we should show this key area's curve on its channel UI or not * * @return True to show the curve, false otherwise */ bool ShouldShowCurve() const; public: /** * Add a key at the specified time with the current value of the channel, updating an existing key if possible * * @param Time The time at which a key should be added (or updated) * @param ObjectBindingID The object binding ID this key area's track is bound to * @param InSequencer The currently active sequencer * @return A handle to the key that was added or updated */ FKeyHandle AddOrUpdateKey(FFrameNumber Time, const FGuid& ObjectBindingID, ISequencer& InSequencer); /** * Delete the specified keys. If all keys are removed, the current value at that time will be set as the default value for the channel * * @param Channel The channel to remove the keys from * @param InHandles The key handles to delete * @param InTime The time at which to evaluate for the default value if there are no keys remaining */ void DeleteKeys(TArrayView InHandles, FFrameNumber InTime); /** * Duplicate the key represented by the specified handle * * @param InKeyHandle A handle to the key to duplicate * @return A handle to the new duplicated key */ FKeyHandle DuplicateKey(FKeyHandle InKeyHandle) const; /** * Get the time of the key represented by the specified handle * * @param InKeyHandle A handle to the key to query for * @return The key's time, or TNumericLimits::Lowest() if the handle was not valid */ FORCEINLINE FFrameNumber GetKeyTime(FKeyHandle InKeyHandle) const { FFrameNumber Time = TNumericLimits::Lowest(); GetKeyTimes(TArrayView(&InKeyHandle, 1), TArrayView(&Time, 1)); return Time; } /** * Get the times of every key represented by the specified handles * * @param InKeyHandles A handle to the key to query for * @param OutTimes A pre-sized array view to populate with key times */ void GetKeyTimes(TArrayView InKeyHandles, TArrayView OutTimes) const; /** * Get all key handles that exist within the given time range * * @param OutHandles An array to populate with key handles, any key handles will be appended to this array * @param WithinRange (Optional) A predicate range to search within */ FORCEINLINE void GetKeyHandles(TArray& OutHandles, const TRange& WithinRange = TRange::All()) const { GetKeyInfo(&OutHandles, nullptr, WithinRange); } /** * Get all key times that exist within the given time range * * @param OutTimes An array to populate with key times, any key times will be appended to this array * @param WithinRange (Optional) A predicate range to search within */ FORCEINLINE void GetKeyTimes(TArray& OutTimes, const TRange& WithinRange = TRange::All()) const { GetKeyInfo(nullptr, &OutTimes, WithinRange); } /** * Populate the specified handle and/or time arrays with information pertaining to keys that exist within the given range * * @param OutHandles (Optional) An array to populate with key handles, any key handles will be appended to this array * @param OutTimes (Optional) An array to populate with key times, any key times will be appended to this array * @param WithinRange (Optional) A predicate range to search within */ void GetKeyInfo(TArray* OutHandles, TArray* OutTimes, const TRange& WithinRange = TRange::All()) const; /** * Set the time of the key with the specified handle * * @param InKeyHandle The key handle to set * @param InKeyTime The time to set the key to */ void SetKeyTime(FKeyHandle InKeyHandle, FFrameNumber InKeyTime) const { SetKeyTimes(TArrayView(&InKeyHandle, 1), TArrayView(&InKeyTime, 1)); } /** * Set the times of the each key with the specified handles * * @param InKeyHandles An array of handles that should have their time set to times in the corresponding InKeyTimes array * @param InKeyTimes Array of times to set to, one per key handle. Must match the size of InKeyHandles */ void SetKeyTimes(TArrayView InKeyHandles, TArrayView InKeyTimes) const; public: /** * Gather key drawing information for the specified key handles * * @param InKeyHandles An array of handles to draw * @param OutKeyDrawParams Pre-sized array view of parameters to populate with each key */ void DrawKeys(TArrayView InKeyHandles, TArrayView OutKeyDrawParams); /** * Copy all the keys specified in KeyMask to the specified clipboard * * @param ClipboardBuilder The structure responsible for building clipboard information for each key * @param KeyMask A specific set of keys to copy */ void CopyKeys(FMovieSceneClipboardBuilder& ClipboardBuilder, TArrayView KeyMask) const; /** * Draw additional content in addition to keys for a particular IKeyArea * * @param PaintArgs Paint arguments containing the draw element list, time-to-pixel converter and other structures * @param LayerId The slate layer to paint onto * @return The new slate layer ID for subsequent elements to paint onto */ int32 DrawExtra(const FSequencerChannelPaintArgs& PaintArgs, int32 LayerId) const; /** * Paste the specified key track into this key area * * @param KeyTrack The source clipboard data to paste * @param SrcEnvironment The environment the source data was copied from * @param DstEnvironment The environment we're pasting into */ TArray PasteKeys(const FMovieSceneClipboardKeyTrack& KeyTrack, const FMovieSceneClipboardEnvironment& SrcEnvironment, const FSequencerPasteEnvironment& DstEnvironment); /** * Create a new model for this key area that can be used on the curve editor interface * * @return (Optional) A new model to be added to a curve editor */ TUniquePtr CreateCurveEditorModel(TSharedRef InSequencer) const; public: FRichCurve* GetRichCurve() const { return nullptr; } /** * Get a key structure for editing a value on this channel * * @return The key structure for this channel, or nullptr */ TSharedPtr GetKeyStruct(FKeyHandle KeyHandle) const; /** * Check whether this key area can create an editor on the sequencer node tree */ bool CanCreateKeyEditor() const; /** * Create an editor on the sequencer node tree * * @param Sequencer The currently active sequencer * @param ObjectBindingID The ID of the object this key area's track is bound to * @return The editor widget to display on the key area's node */ TSharedRef CreateKeyEditor(TWeakPtr Sequencer, const FGuid& ObjectBindingID); private: /** A weak pointer back to the originating section interface that owns this channel */ TWeakPtr WeakSection; /** Handle to the channel itself */ FMovieSceneChannelHandle ChannelHandle; /** Optional property bindings class where the section resides inside a UMovieScenePropertyTrack */ TOptional PropertyBindings; /** The color of this channel that should be drawn underneath its keys */ TOptional Color; /** The name of this channel. */ FName ChannelName; /** The display text of this channel. */ FText DisplayText; /** Consistent ID that is reused and injected into the curve model every time it is created. Pimpl to avoid public build.cs dependency. */ const TPimplPtr CurveModelID; };