2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "PersonaPrivatePCH.h"
# include "SAnimCurvePanel.h"
# include "ScopedTransaction.h"
2014-11-13 17:30:49 -05:00
# include "SAnimCurveEd.h"
2014-03-14 14:13:41 -04:00
# include "Editor/KismetWidgets/Public/SScrubWidget.h"
# include "AssetRegistryModule.h"
2014-07-28 13:20:13 -04:00
# include "Kismet2NameValidators.h"
2014-10-14 22:50:06 -04:00
# include "SExpandableArea.h"
# include "STextEntryPopup.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "AnimCurvePanel"
//////////////////////////////////////////////////////////////////////////
// FAnimCurveInterface interface
/** Interface you implement if you want the CurveEditor to be able to edit curves on you */
class FAnimCurveBaseInterface : public FCurveOwnerInterface
{
public :
TWeakObjectPtr < UAnimSequenceBase > BaseSequence ;
2015-01-30 17:41:04 -05:00
USkeleton : : AnimCurveUID CurveUID ;
2014-03-14 14:13:41 -04:00
FAnimCurveBase * CurveData ;
public :
2015-01-30 17:41:04 -05:00
FAnimCurveBaseInterface ( UAnimSequenceBase * BaseSeq , USkeleton : : AnimCurveUID InCurveUID )
2014-03-14 14:13:41 -04:00
: BaseSequence ( BaseSeq )
2015-01-30 17:41:04 -05:00
, CurveUID ( InCurveUID )
2014-03-14 14:13:41 -04:00
{
2015-01-30 17:41:04 -05:00
CurveData = BaseSequence . Get ( ) - > RawCurveData . GetCurveData ( CurveUID ) ;
2014-03-14 14:13:41 -04:00
// they should be valid
check ( BaseSequence . IsValid ( ) ) ;
check ( CurveData ) ;
}
/** Returns set of curves to edit. Must not release the curves while being edited. */
2015-04-01 07:20:55 -04:00
virtual TArray < FRichCurveEditInfoConst > GetCurves ( ) const override
2014-03-14 14:13:41 -04:00
{
TArray < FRichCurveEditInfoConst > Curves ;
FFloatCurve * FloatCurveData = ( FFloatCurve * ) ( CurveData ) ;
Curves . Add ( & FloatCurveData - > FloatCurve ) ;
return Curves ;
}
/** Returns set of curves to query. Must not release the curves while being edited. */
2015-04-01 07:20:55 -04:00
virtual TArray < FRichCurveEditInfo > GetCurves ( ) override
2014-03-14 14:13:41 -04:00
{
TArray < FRichCurveEditInfo > Curves ;
FFloatCurve * FloatCurveData = ( FFloatCurve * ) ( CurveData ) ;
Curves . Add ( & FloatCurveData - > FloatCurve ) ;
return Curves ;
}
/** Called to modify the owner of the curve */
2015-04-01 07:20:55 -04:00
virtual void ModifyOwner ( ) override
2014-03-14 14:13:41 -04:00
{
if ( BaseSequence . IsValid ( ) )
{
BaseSequence . Get ( ) - > Modify ( true ) ;
}
}
/** Called to make curve owner transactional */
2015-04-01 07:20:55 -04:00
virtual void MakeTransactional ( ) override
2014-03-14 14:13:41 -04:00
{
if ( BaseSequence . IsValid ( ) )
{
BaseSequence . Get ( ) - > SetFlags ( BaseSequence . Get ( ) - > GetFlags ( ) | RF_Transactional ) ;
}
}
2014-08-05 13:03:42 -04:00
/** Called to get the name of a curve back from the animation skeleton */
virtual FText GetCurveName ( USkeleton : : AnimCurveUID Uid ) const
{
if ( BaseSequence . IsValid ( ) )
{
FSmartNameMapping * NameMapping = BaseSequence . Get ( ) - > GetSkeleton ( ) - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
if ( NameMapping )
{
FName CurveName ;
if ( NameMapping - > GetName ( Uid , CurveName ) )
{
return FText : : FromName ( CurveName ) ;
}
}
}
return FText : : GetEmpty ( ) ;
}
2014-08-19 15:57:46 -04:00
2015-02-16 11:59:08 -05:00
virtual void OnCurveChanged ( const TArray < FRichCurveEditInfo > & ChangedCurveEditInfos ) override
2014-08-19 15:57:46 -04:00
{
}
2015-01-30 17:41:04 -05:00
virtual bool IsValidCurve ( FRichCurveEditInfo CurveInfo ) override
{
// Get the curve with the ID directly from the sequence and compare it since undo/redo can cause previously
// used curves to become invalid.
FAnimCurveBase * CurrentCurveData = BaseSequence . Get ( ) - > RawCurveData . GetCurveData ( CurveUID ) ;
return CurrentCurveData ! = nullptr & &
CurveInfo . CurveToEdit = = & ( ( FFloatCurve * ) CurrentCurveData ) - > FloatCurve ;
}
2014-03-14 14:13:41 -04:00
} ;
//////////////////////////////////////////////////////////////////////////
// SCurveEd Track : each track for curve editing
/** Widget for editing a single track of animation curve - this includes CurveEditor */
class SCurveEdTrack : public SCompoundWidget
{
private :
/** Pointer to notify panel for drawing*/
TSharedPtr < class SCurveEditor > CurveEditor ;
/** Name of curve it's editing - CurveName should be unique within this tracks**/
FAnimCurveBaseInterface * CurveInterface ;
/** Curve Panel Ptr **/
TWeakPtr < SAnimCurvePanel > PanelPtr ;
/** is using expanded editor **/
bool bUseExpandEditor ;
public :
SLATE_BEGIN_ARGS ( SCurveEdTrack )
: _AnimCurvePanel ( )
, _Sequence ( )
2014-08-05 13:03:42 -04:00
, _CurveUid ( )
2014-03-14 14:13:41 -04:00
, _WidgetWidth ( )
, _ViewInputMin ( )
, _ViewInputMax ( )
, _OnSetInputViewRange ( )
, _OnGetScrubValue ( )
{ }
SLATE_ARGUMENT ( TSharedPtr < SAnimCurvePanel > , AnimCurvePanel )
// editing related variables
SLATE_ARGUMENT ( class UAnimSequenceBase * , Sequence )
2014-08-05 13:03:42 -04:00
SLATE_ARGUMENT ( USkeleton : : AnimCurveUID , CurveUid )
2014-03-14 14:13:41 -04:00
// widget viewing related variables
SLATE_ARGUMENT ( float , WidgetWidth ) // @todo do I need this?
SLATE_ATTRIBUTE ( float , ViewInputMin )
SLATE_ATTRIBUTE ( float , ViewInputMax )
SLATE_EVENT ( FOnSetInputViewRange , OnSetInputViewRange )
SLATE_EVENT ( FOnGetScrubValue , OnGetScrubValue )
SLATE_END_ARGS ( )
void Construct ( const FArguments & InArgs ) ;
virtual ~ SCurveEdTrack ( ) ;
// input handling for curve name
void NewCurveNameEntered ( const FText & NewText , ETextCommit : : Type CommitInfo ) ;
2014-07-28 11:54:52 -04:00
// Duplicate the current track
void DuplicateTrack ( ) ;
2014-03-14 14:13:41 -04:00
// Delete current track
void DeleteTrack ( ) ;
// Sets the current mode for this curve
2014-12-10 14:24:09 -05:00
void ToggleCurveMode ( ECheckBoxState NewState , EAnimCurveFlags ModeToSet ) ;
2014-03-14 14:13:41 -04:00
// Returns whether this curve is of the specificed mode type
2014-12-10 14:24:09 -05:00
ECheckBoxState IsCurveOfMode ( EAnimCurveFlags ModeToTest ) const ;
2014-03-14 14:13:41 -04:00
/**
* Build and display curve track context menu .
*
*/
FReply OnContextMenu ( ) ;
// expand editor mode
2014-12-10 14:24:09 -05:00
ECheckBoxState IsEditorExpanded ( ) const ;
void ToggleExpandEditor ( ECheckBoxState NewType ) ;
2014-03-14 14:13:41 -04:00
const FSlateBrush * GetExpandContent ( ) const ;
FVector2D GetDesiredSize ( ) const ;
2014-08-05 13:03:42 -04:00
// Bound to attribute for curve name, uses curve interface to request from skeleton
FText GetCurveName ( USkeleton : : AnimCurveUID Uid ) const ;
2014-03-14 14:13:41 -04:00
} ;
//////////////////////////////////////////////////////////////////////////
// SCurveEdTrack
void SCurveEdTrack : : Construct ( const FArguments & InArgs )
{
TSharedRef < SAnimCurvePanel > PanelRef = InArgs . _AnimCurvePanel . ToSharedRef ( ) ;
PanelPtr = InArgs . _AnimCurvePanel ;
bUseExpandEditor = false ;
// now create CurveInterface,
// find which curve this belongs to
UAnimSequenceBase * Sequence = InArgs . _Sequence ;
check ( Sequence ) ;
// get the curve data
2014-08-05 13:03:42 -04:00
FAnimCurveBase * Curve = Sequence - > RawCurveData . GetCurveData ( InArgs . _CurveUid ) ;
2014-03-14 14:13:41 -04:00
check ( Curve ) ;
2015-01-30 17:41:04 -05:00
CurveInterface = new FAnimCurveBaseInterface ( Sequence , InArgs . _CurveUid ) ;
2014-03-14 14:13:41 -04:00
int32 NumberOfKeys = Sequence - > GetNumberOfFrames ( ) ;
//////////////////////////////
2014-08-05 13:03:42 -04:00
TSharedPtr < SBorder > CurveBorder = nullptr ;
TSharedPtr < SHorizontalBox > InnerBox = nullptr ;
SAssignNew ( CurveBorder , SBorder )
. Padding ( FMargin ( 2.0f , 2.0f ) )
2014-03-14 14:13:41 -04:00
[
2014-08-05 13:03:42 -04:00
SAssignNew ( InnerBox , SHorizontalBox )
] ;
2014-11-13 17:30:49 -05:00
bool bIsMetadata = Curve - > GetCurveTypeFlag ( ACF_Metadata ) ;
2014-08-05 13:03:42 -04:00
if ( ! bIsMetadata )
{
InnerBox - > AddSlot ( )
. FillWidth ( 1 )
2014-03-14 14:13:41 -04:00
[
2014-08-05 13:03:42 -04:00
// Notification editor panel
SAssignNew ( CurveEditor , SAnimCurveEd )
. ViewMinInput ( InArgs . _ViewInputMin )
. ViewMaxInput ( InArgs . _ViewInputMax )
. DataMinInput ( 0.f )
. DataMaxInput ( Sequence - > SequenceLength )
// @fixme fix this to delegate
. TimelineLength ( Sequence - > SequenceLength )
. NumberOfKeys ( NumberOfKeys )
. DesiredSize ( this , & SCurveEdTrack : : GetDesiredSize )
. OnSetInputViewRange ( InArgs . _OnSetInputViewRange )
. OnGetScrubValue ( InArgs . _OnGetScrubValue )
] ;
//Inform track widget about the curve and whether it is editable or not.
CurveEditor - > SetCurveOwner ( CurveInterface , true ) ;
}
TSharedPtr < SHorizontalBox > NameBox = nullptr ;
SHorizontalBox : : FSlot & CurveSlot = InnerBox - > AddSlot ( )
[
SNew ( SBox )
. WidthOverride ( InArgs . _WidgetWidth )
. VAlign ( VAlign_Center )
[
SAssignNew ( NameBox , SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. HAlign ( HAlign_Center )
. Padding ( FMargin ( 0.0f , 5.0f , 0.0f , 5.0f ) )
2014-03-14 14:13:41 -04:00
[
2014-08-05 13:03:42 -04:00
// Name of track
SNew ( SEditableText )
. MinDesiredWidth ( 64.0f )
. IsEnabled ( true )
. Font ( FEditorStyle : : GetFontStyle ( " CurveEd.InfoFont " ) )
. SelectAllTextWhenFocused ( true )
. Text ( this , & SCurveEdTrack : : GetCurveName , Curve - > CurveUid )
. OnTextCommitted ( this , & SCurveEdTrack : : NewCurveNameEntered )
2014-03-14 14:13:41 -04:00
]
]
] ;
2014-08-05 13:03:42 -04:00
// Need to autowidth non-metadata names to maximise curve editor area and
// add the expansion checkbox (unnecessary for metadata)
if ( ! bIsMetadata )
{
CurveSlot . AutoWidth ( ) ;
NameBox - > AddSlot ( )
. AutoWidth ( )
[
// Name of track
SNew ( SCheckBox )
. IsChecked ( this , & SCurveEdTrack : : IsEditorExpanded )
. OnCheckStateChanged ( this , & SCurveEdTrack : : ToggleExpandEditor )
. ToolTipText ( LOCTEXT ( " Expand window " , " Expand window " ) )
. IsEnabled ( true )
[
SNew ( SImage )
. Image ( this , & SCurveEdTrack : : GetExpandContent )
]
] ;
}
// Add track options combo button
NameBox - > AddSlot ( )
. Padding ( FMargin ( 0.0f , 5.0f , 0.0f , 5.0f ) )
. AutoWidth ( )
[
SNew ( SButton )
. ToolTipText ( LOCTEXT ( " DisplayTrackOptionsMenuTooltip " , " Display track options menu " ) )
. OnClicked ( this , & SCurveEdTrack : : OnContextMenu )
. Content ( )
[
SNew ( SImage )
. Image ( FEditorStyle : : GetBrush ( " ComboButton.Arrow " ) )
. ColorAndOpacity ( FSlateColor : : UseForeground ( ) )
]
] ;
this - > ChildSlot
[
CurveBorder - > AsShared ( )
] ;
2014-03-14 14:13:41 -04:00
}
/** return a widget */
const FSlateBrush * SCurveEdTrack : : GetExpandContent ( ) const
{
if ( bUseExpandEditor )
{
return FEditorStyle : : GetBrush ( " Kismet.VariableList.HideForInstance " ) ;
}
else
{
return FEditorStyle : : GetBrush ( " Kismet.VariableList.ExposeForInstance " ) ;
}
}
void SCurveEdTrack : : NewCurveNameEntered ( const FText & NewText , ETextCommit : : Type CommitInfo )
{
2014-08-05 13:03:42 -04:00
if ( CommitInfo = = ETextCommit : : OnEnter | | CommitInfo = = ETextCommit : : OnUserMovedFocus )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
if ( USkeleton * Skeleton = CurveInterface - > BaseSequence - > GetSkeleton ( ) )
{
// Check that the name doesn't already exist
FName RequestedName = FName ( * NewText . ToString ( ) ) ;
FSmartNameMapping * NameMapping = Skeleton - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
if ( ! NameMapping - > Exists ( RequestedName ) )
{
FScopedTransaction Transaction ( LOCTEXT ( " CurveEditor_RenameCurve " , " Rename Curve " ) ) ;
Skeleton - > RenameSmartnameAndModify ( USkeleton : : AnimCurveMappingName , CurveInterface - > CurveData - > CurveUid , FName ( * NewText . ToString ( ) ) ) ;
}
}
2014-03-14 14:13:41 -04:00
}
}
SCurveEdTrack : : ~ SCurveEdTrack ( )
{
// @fixme - check -is this okay way of doing it?
delete CurveInterface ;
}
2014-07-28 11:54:52 -04:00
void SCurveEdTrack : : DuplicateTrack ( )
{
TSharedPtr < SAnimCurvePanel > SharedPanel = PanelPtr . Pin ( ) ;
if ( SharedPanel . IsValid ( ) )
{
2014-08-05 13:03:42 -04:00
SharedPanel - > DuplicateTrack ( CurveInterface - > CurveData - > CurveUid ) ;
2014-07-28 11:54:52 -04:00
}
}
2014-03-14 14:13:41 -04:00
void SCurveEdTrack : : DeleteTrack ( )
{
2014-08-05 13:03:42 -04:00
TSharedPtr < SAnimCurvePanel > SharedPanel = PanelPtr . Pin ( ) ;
if ( SharedPanel . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
SharedPanel - > DeleteTrack ( CurveInterface - > CurveData - > CurveUid ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-12-10 14:24:09 -05:00
void SCurveEdTrack : : ToggleCurveMode ( ECheckBoxState NewState , EAnimCurveFlags ModeToSet )
2014-03-14 14:13:41 -04:00
{
const int32 AllModes = ( ACF_DrivesMorphTarget | ACF_DrivesMaterial ) ;
check ( ( ModeToSet & AllModes ) ! = 0 ) ; //unexpected value for ModeToSet
FFloatCurve * CurveData = ( FFloatCurve * ) ( CurveInterface - > CurveData ) ;
FText UndoLabel ;
bool bIsSwitchingFlagOn = ! CurveData - > GetCurveTypeFlag ( ModeToSet ) ;
2014-12-10 14:24:09 -05:00
check ( bIsSwitchingFlagOn = = ( NewState = = ECheckBoxState : : Checked ) ) ;
2014-03-14 14:13:41 -04:00
if ( bIsSwitchingFlagOn )
{
if ( ModeToSet = = ACF_DrivesMorphTarget )
{
UndoLabel = LOCTEXT ( " AnimCurve_TurnOnMorphMode " , " Enable driving of morph targets " ) ;
}
else if ( ModeToSet = = ACF_DrivesMaterial )
{
UndoLabel = LOCTEXT ( " AnimCurve_TurnOnMaterialMode " , " Enable driving of materials " ) ;
}
}
else
{
if ( ModeToSet = = ACF_DrivesMorphTarget )
{
UndoLabel = LOCTEXT ( " AnimCurve_TurnOffMorphMode " , " Disable driving of morph targets " ) ;
}
else if ( ModeToSet = = ACF_DrivesMaterial )
{
UndoLabel = LOCTEXT ( " AnimCurve_TurnOffMaterialMode " , " Disable driving of materials " ) ;
}
}
const FScopedTransaction Transaction ( UndoLabel ) ;
CurveInterface - > MakeTransactional ( ) ;
CurveInterface - > ModifyOwner ( ) ;
CurveData - > SetCurveTypeFlag ( ModeToSet , bIsSwitchingFlagOn ) ;
}
2014-12-10 14:24:09 -05:00
ECheckBoxState SCurveEdTrack : : IsCurveOfMode ( EAnimCurveFlags ModeToTest ) const
2014-03-14 14:13:41 -04:00
{
FFloatCurve * CurveData = ( FFloatCurve * ) ( CurveInterface - > CurveData ) ;
2014-12-10 14:24:09 -05:00
return CurveData - > GetCurveTypeFlag ( ModeToTest ) ? ECheckBoxState : : Checked : ECheckBoxState : : Unchecked ;
2014-03-14 14:13:41 -04:00
}
FReply SCurveEdTrack : : OnContextMenu ( )
{
2014-08-05 13:03:42 -04:00
TSharedPtr < SAnimCurvePanel > PanelShared = PanelPtr . Pin ( ) ;
if ( PanelShared . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
FFloatCurve * Curve = ( FFloatCurve * ) ( CurveInterface - > CurveData ) ;
FSlateApplication : : Get ( ) . PushMenu ( SharedThis ( this ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-08-05 13:03:42 -04:00
PanelShared - > CreateCurveContextMenu ( Curve ) ,
FSlateApplication : : Get ( ) . GetCursorPos ( ) ,
FPopupTransitionEffect ( FPopupTransitionEffect : : TypeInPopup ) ) ;
2014-03-14 14:13:41 -04:00
}
return FReply : : Handled ( ) ;
}
2014-12-10 14:24:09 -05:00
ECheckBoxState SCurveEdTrack : : IsEditorExpanded ( ) const
2014-03-14 14:13:41 -04:00
{
2014-12-10 14:24:09 -05:00
return ( bUseExpandEditor ) ? ECheckBoxState : : Checked : ECheckBoxState : : Unchecked ;
2014-03-14 14:13:41 -04:00
}
2014-12-10 14:24:09 -05:00
void SCurveEdTrack : : ToggleExpandEditor ( ECheckBoxState NewType )
2014-03-14 14:13:41 -04:00
{
2014-12-10 14:24:09 -05:00
bUseExpandEditor = ( NewType = = ECheckBoxState : : Checked ) ;
2014-03-14 14:13:41 -04:00
}
FVector2D SCurveEdTrack : : GetDesiredSize ( ) const
{
if ( bUseExpandEditor )
{
return FVector2D ( 128.f , 128.f ) ;
}
else
{
return FVector2D ( 128.f , 32.f ) ;
}
}
2014-08-05 13:03:42 -04:00
FText SCurveEdTrack : : GetCurveName ( USkeleton : : AnimCurveUID Uid ) const
{
return CurveInterface - > GetCurveName ( Uid ) ;
}
2014-03-14 14:13:41 -04:00
//////////////////////////////////////////////////////////////////////////
// SAnimCurvePanel
2014-07-28 13:20:13 -04:00
/**
* Name validator for anim curves
*/
class FCurveNameValidator : public FStringSetNameValidator
{
public :
2014-08-05 13:03:42 -04:00
FCurveNameValidator ( FRawCurveTracks & Tracks , FSmartNameMapping * NameMapping , const FString & ExistingName )
2014-07-28 13:20:13 -04:00
: FStringSetNameValidator ( ExistingName )
{
2014-08-05 13:03:42 -04:00
FName CurveName ;
2014-07-28 13:20:13 -04:00
for ( FFloatCurve & Curve : Tracks . FloatCurves )
{
2014-08-05 13:03:42 -04:00
if ( NameMapping - > GetName ( Curve . CurveUid , CurveName ) )
{
Names . Add ( CurveName . ToString ( ) ) ;
}
2014-07-28 13:20:13 -04:00
}
}
} ;
2014-03-14 14:13:41 -04:00
void SAnimCurvePanel : : Construct ( const FArguments & InArgs )
{
SAnimTrackPanel : : Construct ( SAnimTrackPanel : : FArguments ( )
. WidgetWidth ( InArgs . _WidgetWidth )
. ViewInputMin ( InArgs . _ViewInputMin )
. ViewInputMax ( InArgs . _ViewInputMax )
. InputMin ( InArgs . _InputMin )
. InputMax ( InArgs . _InputMax )
. OnSetInputViewRange ( InArgs . _OnSetInputViewRange ) ) ;
2014-08-05 13:03:42 -04:00
WeakPersona = InArgs . _Persona ;
2014-03-14 14:13:41 -04:00
Sequence = InArgs . _Sequence ;
WidgetWidth = InArgs . _WidgetWidth ;
OnGetScrubValue = InArgs . _OnGetScrubValue ;
this - > ChildSlot
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. FillHeight ( 1 )
[
SNew ( SExpandableArea )
. AreaTitle ( LOCTEXT ( " Curves " , " Curves " ) )
. BodyContent ( )
[
SNew ( SVerticalBox )
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
[
// Name of track
SNew ( SButton )
2014-08-05 13:03:42 -04:00
. Text ( LOCTEXT ( " AddFloatTrack " , " Add... " ) )
2014-03-14 14:13:41 -04:00
. ToolTipText ( LOCTEXT ( " AddTrackTooltip " , " Add float track above here " ) )
2014-08-05 13:03:42 -04:00
. OnClicked ( this , & SAnimCurvePanel : : AddButtonClicked )
2014-09-12 15:56:59 -04:00
. AddMetaData < FTagMetaData > ( TEXT ( " AnimCurve.AddFloat " ) )
2014-03-14 14:13:41 -04:00
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
[
SNew ( SComboButton )
. ContentPadding ( FMargin ( 2.0f ) )
. OnGetMenuContent ( this , & SAnimCurvePanel : : GenerateCurveList )
]
2015-02-13 15:40:33 -05:00
+ SHorizontalBox : : Slot ( )
. HAlign ( HAlign_Center )
. VAlign ( VAlign_Center )
. Padding ( 5 , 0 )
. AutoWidth ( )
[
SNew ( STextBlock )
. Font ( FEditorStyle : : GetFontStyle ( " CurveEd.InfoFont " ) )
. Text ( FText : : FromString ( FString : : Printf ( TEXT ( " Total Number : %d " ) , Sequence - > RawCurveData . FloatCurves . Num ( ) ) ) )
]
2014-03-14 14:13:41 -04:00
+ SHorizontalBox : : Slot ( )
. HAlign ( HAlign_Right )
. Padding ( 2.0f , 0.0f )
[
// Name of track
SNew ( SButton )
. ToolTipText ( LOCTEXT ( " DisplayTrackOptionsMenuForAllTracksTooltip " , " Display track options menu for all tracks " ) )
. OnClicked ( this , & SAnimCurvePanel : : OnContextMenu )
. Visibility ( TAttribute < EVisibility > ( this , & SAnimCurvePanel : : IsSetAllTracksButtonVisible ) )
. Content ( )
[
SNew ( SImage )
. Image ( FEditorStyle : : GetBrush ( " ComboButton.Arrow " ) )
. ColorAndOpacity ( FSlateColor : : UseForeground ( ) )
]
]
]
+ SVerticalBox : : Slot ( )
2014-08-05 13:03:42 -04:00
. Padding ( FMargin ( 0.0f , 5.0f , 0.0f , 0.0f ) )
2014-03-14 14:13:41 -04:00
. AutoHeight ( )
[
2014-08-05 13:03:42 -04:00
SAssignNew ( PanelSlot , SSplitter )
2014-03-14 14:13:41 -04:00
. Orientation ( Orient_Vertical )
]
]
]
] ;
UpdatePanel ( ) ;
}
2014-08-05 13:03:42 -04:00
FReply SAnimCurvePanel : : AddButtonClicked ( )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
USkeleton * CurrentSkeleton = Sequence - > GetSkeleton ( ) ;
check ( CurrentSkeleton ) ;
FMenuBuilder MenuBuilder ( true , NULL ) ;
MenuBuilder . BeginSection ( " ConstantCurves " , LOCTEXT ( " ConstantCurveHeading " , " Constant Curve " ) ) ;
{
MenuBuilder . AddSubMenu (
LOCTEXT ( " NewMetadataSubMenu " , " Add Metadata... " ) ,
LOCTEXT ( " NewMetadataSubMenuToolTip " , " Add a new metadata entry to the sequence " ) ,
FNewMenuDelegate : : CreateRaw ( this , & SAnimCurvePanel : : FillMetadataEntryMenu ) ) ;
}
MenuBuilder . EndSection ( ) ;
MenuBuilder . BeginSection ( " Curves " , LOCTEXT ( " CurveHeading " , " Curve " ) ) ;
{
MenuBuilder . AddSubMenu (
LOCTEXT ( " NewVariableCurveSubMenu " , " Add Variable Curve... " ) ,
LOCTEXT ( " NewVariableCurveSubMenuToolTip " , " Add a new variable curve to the sequence " ) ,
FNewMenuDelegate : : CreateRaw ( this , & SAnimCurvePanel : : FillVariableCurveMenu ) ) ;
}
MenuBuilder . EndSection ( ) ;
2014-03-14 14:13:41 -04:00
// Show dialog to enter new track name
FSlateApplication : : Get ( ) . PushMenu (
SharedThis ( this ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-08-05 13:03:42 -04:00
MenuBuilder . MakeWidget ( ) ,
2014-03-14 14:13:41 -04:00
FSlateApplication : : Get ( ) . GetCursorPos ( ) ,
FPopupTransitionEffect ( FPopupTransitionEffect : : TypeInPopup )
) ;
return FReply : : Handled ( ) ;
}
2014-08-05 13:03:42 -04:00
void SAnimCurvePanel : : CreateTrack ( const FText & ComittedText , ETextCommit : : Type CommitInfo )
2014-03-14 14:13:41 -04:00
{
if ( CommitInfo = = ETextCommit : : OnEnter )
{
2014-08-05 13:03:42 -04:00
USkeleton * Skeleton = Sequence - > GetSkeleton ( ) ;
if ( Skeleton & & ! ComittedText . IsEmpty ( ) )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
const FScopedTransaction Transaction ( LOCTEXT ( " AnimCurve_AddTrack " , " Add New Curve " ) ) ;
USkeleton : : AnimCurveUID CurveUid ;
if ( Skeleton - > AddSmartnameAndModify ( USkeleton : : AnimCurveMappingName , FName ( * ComittedText . ToString ( ) ) , CurveUid ) )
{
AddVariableCurve ( CurveUid ) ;
}
2014-03-14 14:13:41 -04:00
}
FSlateApplication : : Get ( ) . DismissAllMenus ( ) ;
}
}
2014-08-05 13:03:42 -04:00
FReply SAnimCurvePanel : : DuplicateTrack ( USkeleton : : AnimCurveUID Uid )
2014-07-28 11:54:52 -04:00
{
const FScopedTransaction Transaction ( LOCTEXT ( " AnimCurve_DuplicateTrack " , " Duplicate Curve " ) ) ;
2014-08-05 13:03:42 -04:00
FSmartNameMapping * NameMapping = Sequence - > GetSkeleton ( ) - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
FName CurveNameToCopy ;
USkeleton : : AnimCurveUID NewUid ;
2014-07-28 13:20:13 -04:00
2014-08-05 13:03:42 -04:00
// Must have a curve that exists to duplicate
if ( NameMapping - > Exists ( Uid ) )
2014-07-28 11:54:52 -04:00
{
2014-08-05 13:03:42 -04:00
NameMapping - > GetName ( Uid , CurveNameToCopy ) ;
TSharedPtr < INameValidatorInterface > Validator = MakeShareable ( new FCurveNameValidator ( Sequence - > RawCurveData , NameMapping , FString ( TEXT ( " " ) ) ) ) ;
2014-07-28 11:54:52 -04:00
2014-08-05 13:03:42 -04:00
// Use the validator to pick a reasonable name for the duplicated curve.
FString NewCurveName = CurveNameToCopy . ToString ( ) ;
Validator - > FindValidString ( NewCurveName ) ;
2014-11-13 17:30:49 -05:00
if ( NameMapping - > AddOrFindName ( * NewCurveName , NewUid ) )
2014-08-05 13:03:42 -04:00
{
if ( Sequence - > RawCurveData . DuplicateCurveData ( Uid , NewUid ) )
{
Sequence - > Modify ( ) ;
UpdatePanel ( ) ;
return FReply : : Handled ( ) ;
}
}
2014-07-28 11:54:52 -04:00
}
return FReply : : Unhandled ( ) ;
}
2014-08-05 13:03:42 -04:00
void SAnimCurvePanel : : DeleteTrack ( USkeleton : : AnimCurveUID Uid )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
const FScopedTransaction Transaction ( LOCTEXT ( " AnimCurve_DeleteTrack " , " Delete Curve " ) ) ;
if ( Sequence - > RawCurveData . GetCurveData ( Uid ) )
2014-03-14 14:13:41 -04:00
{
Sequence - > Modify ( true ) ;
2014-08-05 13:03:42 -04:00
Sequence - > RawCurveData . DeleteCurveData ( Uid ) ;
2014-07-30 11:05:52 -04:00
UpdatePanel ( ) ;
2014-03-14 14:13:41 -04:00
}
}
FReply SAnimCurvePanel : : OnContextMenu ( )
{
FMenuBuilder MenuBuilder ( true , NULL ) ;
MenuBuilder . BeginSection ( " AnimCurvePanelCurveTypes " , LOCTEXT ( " AllCurveTypesHeading " , " All Curve Types " ) ) ;
{
MenuBuilder . AddWidget (
SNew ( SCheckBox )
. IsChecked ( this , & SAnimCurvePanel : : AreAllCurvesOfMode , ACF_DrivesMorphTarget )
. OnCheckStateChanged ( this , & SAnimCurvePanel : : ToggleAllCurveModes , ACF_DrivesMorphTarget )
2014-04-23 18:06:41 -04:00
. ToolTipText ( LOCTEXT ( " MorphCurveModeTooltip " , " This curve drives a morph target " ) )
2014-03-14 14:13:41 -04:00
[
SNew ( STextBlock )
2014-04-23 18:06:41 -04:00
. Text ( LOCTEXT ( " MorphCurveMode " , " Morph Curve " ) )
2014-03-14 14:13:41 -04:00
] ,
FText ( )
) ;
MenuBuilder . AddWidget (
SNew ( SCheckBox )
. IsChecked ( this , & SAnimCurvePanel : : AreAllCurvesOfMode , ACF_DrivesMaterial )
. OnCheckStateChanged ( this , & SAnimCurvePanel : : ToggleAllCurveModes , ACF_DrivesMaterial )
2014-04-23 18:06:41 -04:00
. ToolTipText ( LOCTEXT ( " MaterialCurveModeTooltip " , " This curve drives a material " ) )
2014-03-14 14:13:41 -04:00
. HAlign ( HAlign_Left )
[
SNew ( STextBlock )
2014-04-23 18:06:41 -04:00
. Text ( LOCTEXT ( " MaterialCurveMode " , " Material Curve " ) )
2014-03-14 14:13:41 -04:00
] ,
FText ( )
) ;
FSlateApplication : : Get ( ) . PushMenu ( SharedThis ( this ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-03-14 14:13:41 -04:00
MenuBuilder . MakeWidget ( ) ,
FSlateApplication : : Get ( ) . GetCursorPos ( ) ,
FPopupTransitionEffect ( FPopupTransitionEffect : : TypeInPopup ) ) ;
}
MenuBuilder . EndSection ( ) ;
return FReply : : Handled ( ) ;
}
EVisibility SAnimCurvePanel : : IsSetAllTracksButtonVisible ( ) const
{
return ( Tracks . Num ( ) > 1 ) ? EVisibility : : Visible : EVisibility : : Hidden ;
}
2014-12-10 14:24:09 -05:00
void SAnimCurvePanel : : ToggleAllCurveModes ( ECheckBoxState NewState , EAnimCurveFlags ModeToSet )
2014-03-14 14:13:41 -04:00
{
2014-12-10 14:24:09 -05:00
const ECheckBoxState CurrentAllState = AreAllCurvesOfMode ( ModeToSet ) ;
2014-08-05 13:03:42 -04:00
for ( TWeakPtr < SCurveEdTrack > TrackWeak : Tracks )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
TSharedPtr < SCurveEdTrack > TrackWidget = TrackWeak . Pin ( ) ;
2014-03-14 14:13:41 -04:00
if ( TrackWidget . IsValid ( ) )
{
2014-12-10 14:24:09 -05:00
const ECheckBoxState CurrentTrackState = TrackWidget - > IsCurveOfMode ( ModeToSet ) ;
if ( ( CurrentAllState = = CurrentTrackState ) | | ( ( CurrentAllState = = ECheckBoxState : : Undetermined ) & & ( CurrentTrackState = = ECheckBoxState : : Unchecked ) ) )
2014-03-14 14:13:41 -04:00
{
TrackWidget - > ToggleCurveMode ( NewState , ModeToSet ) ;
}
}
}
}
2014-12-10 14:24:09 -05:00
ECheckBoxState SAnimCurvePanel : : AreAllCurvesOfMode ( EAnimCurveFlags ModeToSet ) const
2014-03-14 14:13:41 -04:00
{
int32 NumChecked = 0 ;
2014-08-05 13:03:42 -04:00
for ( const TWeakPtr < SCurveEdTrack > TrackWeak : Tracks )
2014-03-14 14:13:41 -04:00
{
2014-08-05 13:03:42 -04:00
const TSharedPtr < SCurveEdTrack > TrackWidget = TrackWeak . Pin ( ) ;
2014-03-14 14:13:41 -04:00
if ( TrackWidget . IsValid ( ) )
{
2014-12-10 14:24:09 -05:00
if ( TrackWidget - > IsCurveOfMode ( ModeToSet ) = = ECheckBoxState : : Checked )
2014-03-14 14:13:41 -04:00
{
NumChecked + + ;
}
}
}
if ( NumChecked = = Tracks . Num ( ) )
{
2014-12-10 14:24:09 -05:00
return ECheckBoxState : : Checked ;
2014-03-14 14:13:41 -04:00
}
else if ( NumChecked = = 0 )
{
2014-12-10 14:24:09 -05:00
return ECheckBoxState : : Unchecked ;
2014-03-14 14:13:41 -04:00
}
2014-12-10 14:24:09 -05:00
return ECheckBoxState : : Undetermined ;
2014-03-14 14:13:41 -04:00
}
2014-07-30 11:05:52 -04:00
void SAnimCurvePanel : : UpdatePanel ( )
2014-03-14 14:13:41 -04:00
{
if ( Sequence ! = NULL )
{
2014-08-05 13:03:42 -04:00
USkeleton * CurrentSkeleton = Sequence - > GetSkeleton ( ) ;
FSmartNameMapping * MetadataNameMap = CurrentSkeleton - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
// Sort the raw curves before setting up display
Sequence - > RawCurveData . FloatCurves . Sort ( [ MetadataNameMap ] ( const FFloatCurve & A , const FFloatCurve & B )
{
bool bAMeta = A . GetCurveTypeFlag ( ACF_Metadata ) ;
bool bBMeta = B . GetCurveTypeFlag ( ACF_Metadata ) ;
if ( bAMeta ! = bBMeta )
{
return ! bAMeta ;
}
2014-03-14 14:13:41 -04:00
2014-08-05 13:03:42 -04:00
FName AName ;
FName BName ;
MetadataNameMap - > GetName ( A . CurveUid , AName ) ;
MetadataNameMap - > GetName ( B . CurveUid , BName ) ;
return AName < BName ;
} ) ;
// see if we need to clear or not
FChildren * VariableChildren = PanelSlot - > GetChildren ( ) ;
for ( int32 Id = VariableChildren - > Num ( ) - 1 ; Id > = 0 ; - - Id )
2014-03-14 14:13:41 -04:00
{
2014-07-30 11:05:52 -04:00
PanelSlot - > RemoveAt ( Id ) ;
2014-03-14 14:13:41 -04:00
}
2014-08-05 13:03:42 -04:00
2014-07-30 11:05:52 -04:00
// Clear all tracks as we're re-adding them all anyway.
Tracks . Empty ( ) ;
2014-03-14 14:13:41 -04:00
// Updating new tracks
2014-08-05 13:03:42 -04:00
FSmartNameMapping * NameMapping = CurrentSkeleton - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
2014-07-30 11:05:52 -04:00
int32 TotalCurve = Sequence - > RawCurveData . FloatCurves . Num ( ) ;
for ( int32 CurrentIt = 0 ; CurrentIt < TotalCurve ; + + CurrentIt )
2014-03-14 14:13:41 -04:00
{
FFloatCurve & Curve = Sequence - > RawCurveData . FloatCurves [ CurrentIt ] ;
2014-08-05 13:03:42 -04:00
const bool bEditable = Curve . GetCurveTypeFlag ( ACF_Editable ) ;
const bool bConstant = Curve . GetCurveTypeFlag ( ACF_Metadata ) ;
FName CurveName ;
2014-03-14 14:13:41 -04:00
// if editable, add to the list
2014-08-05 13:03:42 -04:00
if ( bEditable & & NameMapping - > GetName ( Curve . CurveUid , CurveName ) )
2014-03-14 14:13:41 -04:00
{
TSharedPtr < SCurveEdTrack > CurrentTrack ;
PanelSlot - > AddSlot ( )
. SizeRule ( SSplitter : : SizeToContent )
[
SNew ( SVerticalBox )
2014-08-05 13:03:42 -04:00
+ SVerticalBox : : Slot ( )
2014-03-14 14:13:41 -04:00
. AutoHeight ( )
. VAlign ( VAlign_Center )
[
SAssignNew ( CurrentTrack , SCurveEdTrack )
. Sequence ( Sequence )
2014-08-05 13:03:42 -04:00
. CurveUid ( Curve . CurveUid )
2014-03-14 14:13:41 -04:00
. AnimCurvePanel ( SharedThis ( this ) )
. WidgetWidth ( WidgetWidth )
. ViewInputMin ( ViewInputMin )
. ViewInputMax ( ViewInputMax )
. OnGetScrubValue ( OnGetScrubValue )
. OnSetInputViewRange ( OnSetInputViewRange )
]
] ;
2014-08-05 13:03:42 -04:00
Tracks . Add ( CurrentTrack ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-08-05 13:03:42 -04:00
TSharedPtr < FPersona > SharedPersona = WeakPersona . Pin ( ) ;
if ( SharedPersona . IsValid ( ) )
{
SharedPersona - > OnCurvesChanged . Broadcast ( ) ;
}
2014-03-14 14:13:41 -04:00
}
}
void SAnimCurvePanel : : SetSequence ( class UAnimSequenceBase * InSequence )
{
if ( InSequence ! = Sequence )
{
Sequence = InSequence ;
2014-07-30 11:05:52 -04:00
UpdatePanel ( ) ;
2014-03-14 14:13:41 -04:00
}
}
TSharedRef < SWidget > SAnimCurvePanel : : GenerateCurveList ( )
{
TSharedPtr < SVerticalBox > MainBox , ListBox ;
TSharedRef < SWidget > NewWidget = SAssignNew ( MainBox , SVerticalBox ) ;
if ( Sequence & & Sequence - > RawCurveData . FloatCurves . Num ( ) > 0 )
{
MainBox - > AddSlot ( )
. AutoHeight ( )
. MaxHeight ( 300 )
[
SNew ( SScrollBox )
+ SScrollBox : : Slot ( )
[
SAssignNew ( ListBox , SVerticalBox )
]
] ;
2014-08-05 13:03:42 -04:00
// Mapping to retrieve curve names
FSmartNameMapping * NameMapping = Sequence - > GetSkeleton ( ) - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
check ( NameMapping ) ;
2014-03-14 14:13:41 -04:00
for ( auto Iter = Sequence - > RawCurveData . FloatCurves . CreateConstIterator ( ) ; Iter ; + + Iter )
{
const FFloatCurve & Curve = * Iter ;
2014-08-05 13:03:42 -04:00
FName CurveName ;
NameMapping - > GetName ( Curve . CurveUid , CurveName ) ;
2014-03-14 14:13:41 -04:00
ListBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 2.0f )
[
SNew ( SCheckBox )
2014-08-05 13:03:42 -04:00
. IsChecked ( this , & SAnimCurvePanel : : IsCurveEditable , Curve . CurveUid )
. OnCheckStateChanged ( this , & SAnimCurvePanel : : ToggleEditability , Curve . CurveUid )
2014-03-14 14:13:41 -04:00
. ToolTipText ( LOCTEXT ( " Show Curves " , " Show or Hide Curves " ) )
. IsEnabled ( true )
[
SNew ( STextBlock )
2014-08-05 13:03:42 -04:00
. Text ( FText : : FromName ( CurveName ) )
2014-03-14 14:13:41 -04:00
]
] ;
}
MainBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 2.0f )
[
SNew ( SButton )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
. OnClicked ( this , & SAnimCurvePanel : : RefreshPanel )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " RefreshCurve " , " Refresh " ) )
]
] ;
MainBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 2.0f )
[
SNew ( SButton )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
. OnClicked ( this , & SAnimCurvePanel : : ShowAll , true )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " ShowAll " , " Show All " ) )
]
] ;
MainBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 2.0f )
[
SNew ( SButton )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
. OnClicked ( this , & SAnimCurvePanel : : ShowAll , false )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " HideAll " , " Hide All " ) )
]
] ;
}
else
{
MainBox - > AddSlot ( )
. AutoHeight ( )
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 2.0f )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " Not Available " , " No curve exists " ) )
] ;
}
return NewWidget ;
}
2014-12-10 14:24:09 -05:00
ECheckBoxState SAnimCurvePanel : : IsCurveEditable ( USkeleton : : AnimCurveUID Uid ) const
2014-03-14 14:13:41 -04:00
{
if ( Sequence )
{
2014-11-13 17:30:49 -05:00
const FFloatCurve * Curve = static_cast < const FFloatCurve * > ( Sequence - > RawCurveData . GetCurveData ( Uid , FRawCurveTracks : : FloatType ) ) ;
2014-03-14 14:13:41 -04:00
if ( Curve )
{
2014-12-10 14:24:09 -05:00
return Curve - > GetCurveTypeFlag ( ACF_Editable ) ? ECheckBoxState : : Checked : ECheckBoxState : : Unchecked ;
2014-03-14 14:13:41 -04:00
}
}
2014-12-10 14:24:09 -05:00
return ECheckBoxState : : Undetermined ;
2014-03-14 14:13:41 -04:00
}
2014-12-10 14:24:09 -05:00
void SAnimCurvePanel : : ToggleEditability ( ECheckBoxState NewType , USkeleton : : AnimCurveUID Uid )
2014-03-14 14:13:41 -04:00
{
2014-12-10 14:24:09 -05:00
bool bEdit = ( NewType = = ECheckBoxState : : Checked ) ;
2014-03-14 14:13:41 -04:00
if ( Sequence )
{
2014-11-13 17:30:49 -05:00
FFloatCurve * Curve = static_cast < FFloatCurve * > ( Sequence - > RawCurveData . GetCurveData ( Uid , FRawCurveTracks : : FloatType ) ) ;
2014-03-14 14:13:41 -04:00
if ( Curve )
{
Curve - > SetCurveTypeFlag ( ACF_Editable , bEdit ) ;
}
}
}
FReply SAnimCurvePanel : : RefreshPanel ( )
{
2014-07-30 11:05:52 -04:00
UpdatePanel ( ) ;
2014-03-14 14:13:41 -04:00
return FReply : : Handled ( ) ;
}
FReply SAnimCurvePanel : : ShowAll ( bool bShow )
{
if ( Sequence )
{
for ( auto Iter = Sequence - > RawCurveData . FloatCurves . CreateIterator ( ) ; Iter ; + + Iter )
{
FFloatCurve & Curve = * Iter ;
Curve . SetCurveTypeFlag ( ACF_Editable , bShow ) ;
}
2014-07-30 11:05:52 -04:00
UpdatePanel ( ) ;
2014-03-14 14:13:41 -04:00
}
return FReply : : Handled ( ) ;
}
2014-08-05 13:03:42 -04:00
void SAnimCurvePanel : : FillMetadataEntryMenu ( FMenuBuilder & Builder )
{
USkeleton * CurrentSkeleton = Sequence - > GetSkeleton ( ) ;
check ( CurrentSkeleton ) ;
FSmartNameMapping * Mapping = CurrentSkeleton - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
TArray < USkeleton : : AnimCurveUID > CurveUids ;
Mapping - > FillUidArray ( CurveUids ) ;
Builder . BeginSection ( NAME_None , LOCTEXT ( " MetadataMenu_ListHeading " , " Available Names " ) ) ;
{
2015-06-16 15:59:06 -04:00
TArray < FSmartNameSortItem > SmartNameList ;
for ( USkeleton : : AnimCurveUID Id : CurveUids )
2014-08-05 13:03:42 -04:00
{
2015-06-16 15:59:06 -04:00
if ( ! Sequence - > RawCurveData . GetCurveData ( Id ) )
{
FName CurveName ;
if ( Mapping - > GetName ( Id , CurveName ) )
{
SmartNameList . Add ( FSmartNameSortItem ( CurveName , Id ) ) ;
}
}
}
{
SmartNameList . Sort ( FSmartNameSortItemSortOp ( ) ) ;
for ( FSmartNameSortItem SmartNameItem : SmartNameList )
2014-08-05 13:03:42 -04:00
{
const FText Description = LOCTEXT ( " NewMetadataSubMenu_ToolTip " , " Add an existing metadata curve " ) ;
2015-06-16 15:59:06 -04:00
const FText Label = FText : : FromName ( SmartNameItem . SmartName ) ;
2014-08-05 13:03:42 -04:00
FUIAction UIAction ;
UIAction . ExecuteAction . BindRaw (
this , & SAnimCurvePanel : : AddMetadataEntry ,
2015-06-16 15:59:06 -04:00
SmartNameItem . ID ) ;
2014-08-05 13:03:42 -04:00
Builder . AddMenuEntry ( Label , Description , FSlateIcon ( ) , UIAction ) ;
}
}
}
Builder . EndSection ( ) ;
Builder . AddMenuSeparator ( ) ;
const FText Description = LOCTEXT ( " NewMetadataCreateNew_ToolTip " , " Create a new metadata entry " ) ;
const FText Label = LOCTEXT ( " NewMetadataCreateNew_Label " , " Create New " ) ;
FUIAction UIAction ;
UIAction . ExecuteAction . BindRaw ( this , & SAnimCurvePanel : : CreateNewMetadataEntryClicked ) ;
Builder . AddMenuEntry ( Label , Description , FSlateIcon ( ) , UIAction ) ;
}
void SAnimCurvePanel : : FillVariableCurveMenu ( FMenuBuilder & Builder )
{
USkeleton * CurrentSkeleton = Sequence - > GetSkeleton ( ) ;
check ( CurrentSkeleton ) ;
FSmartNameMapping * Mapping = CurrentSkeleton - > SmartNames . GetContainer ( USkeleton : : AnimCurveMappingName ) ;
TArray < USkeleton : : AnimCurveUID > CurveUids ;
Mapping - > FillUidArray ( CurveUids ) ;
Builder . BeginSection ( NAME_None , LOCTEXT ( " VariableMenu_ListHeading " , " Available Names " ) ) ;
{
2015-06-16 15:59:06 -04:00
TArray < FSmartNameSortItem > SmartNameList ;
for ( USkeleton : : AnimCurveUID Id : CurveUids )
2014-08-05 13:03:42 -04:00
{
2015-06-16 15:59:06 -04:00
if ( ! Sequence - > RawCurveData . GetCurveData ( Id ) )
{
FName CurveName ;
if ( Mapping - > GetName ( Id , CurveName ) )
{
SmartNameList . Add ( FSmartNameSortItem ( CurveName , Id ) ) ;
}
}
}
{
SmartNameList . Sort ( FSmartNameSortItemSortOp ( ) ) ;
for ( FSmartNameSortItem SmartNameItem : SmartNameList )
2014-08-05 13:03:42 -04:00
{
const FText Description = LOCTEXT ( " NewVariableSubMenu_ToolTip " , " Add an existing variable curve " ) ;
2015-06-16 15:59:06 -04:00
const FText Label = FText : : FromName ( SmartNameItem . SmartName ) ;
2014-08-05 13:03:42 -04:00
FUIAction UIAction ;
UIAction . ExecuteAction . BindRaw (
this , & SAnimCurvePanel : : AddVariableCurve ,
2015-06-16 15:59:06 -04:00
SmartNameItem . ID ) ;
2014-08-05 13:03:42 -04:00
Builder . AddMenuEntry ( Label , Description , FSlateIcon ( ) , UIAction ) ;
}
}
}
Builder . EndSection ( ) ;
Builder . AddMenuSeparator ( ) ;
const FText Description = LOCTEXT ( " NewVariableCurveCreateNew_ToolTip " , " Create a new variable curve " ) ;
const FText Label = LOCTEXT ( " NewVariableCurveCreateNew_Label " , " Create Curve " ) ;
FUIAction UIAction ;
UIAction . ExecuteAction . BindRaw ( this , & SAnimCurvePanel : : CreateNewCurveClicked ) ;
Builder . AddMenuEntry ( Label , Description , FSlateIcon ( ) , UIAction ) ;
}
void SAnimCurvePanel : : AddMetadataEntry ( USkeleton : : AnimCurveUID Uid )
{
if ( Sequence - > RawCurveData . AddCurveData ( Uid ) )
{
Sequence - > Modify ( true ) ;
2014-11-13 17:30:49 -05:00
FFloatCurve * Curve = static_cast < FFloatCurve * > ( Sequence - > RawCurveData . GetCurveData ( Uid , FRawCurveTracks : : FloatType ) ) ;
2014-08-05 13:03:42 -04:00
Curve - > FloatCurve . AddKey ( 0.0f , 1.0f ) ;
Curve - > SetCurveTypeFlag ( ACF_Metadata , true ) ;
RefreshPanel ( ) ;
}
}
void SAnimCurvePanel : : CreateNewMetadataEntryClicked ( )
{
TSharedRef < STextEntryPopup > TextEntry =
SNew ( STextEntryPopup )
. Label ( LOCTEXT ( " NewMetadataCurveEntryLabal " , " Metadata Name " ) )
. OnTextCommitted ( this , & SAnimCurvePanel : : CreateNewMetadataEntry ) ;
FSlateApplication & SlateApp = FSlateApplication : : Get ( ) ;
SlateApp . PushMenu (
AsShared ( ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-08-05 13:03:42 -04:00
TextEntry ,
SlateApp . GetCursorPos ( ) ,
FPopupTransitionEffect : : TypeInPopup
) ;
}
void SAnimCurvePanel : : CreateNewMetadataEntry ( const FText & CommittedText , ETextCommit : : Type CommitType )
{
FSlateApplication : : Get ( ) . DismissAllMenus ( ) ;
if ( CommitType = = ETextCommit : : OnEnter )
{
// Add the name to the skeleton and then add the new curve to the sequence
USkeleton * Skeleton = Sequence - > GetSkeleton ( ) ;
if ( Skeleton & & ! CommittedText . IsEmpty ( ) )
{
USkeleton : : AnimCurveUID CurveUid ;
if ( Skeleton - > AddSmartnameAndModify ( USkeleton : : AnimCurveMappingName , FName ( * CommittedText . ToString ( ) ) , CurveUid ) )
{
AddMetadataEntry ( CurveUid ) ;
}
}
}
}
void SAnimCurvePanel : : CreateNewCurveClicked ( )
{
TSharedRef < STextEntryPopup > TextEntry =
SNew ( STextEntryPopup )
. Label ( LOCTEXT ( " NewCurveEntryLabal " , " Curve Name " ) )
. OnTextCommitted ( this , & SAnimCurvePanel : : CreateTrack ) ;
FSlateApplication & SlateApp = FSlateApplication : : Get ( ) ;
SlateApp . PushMenu (
AsShared ( ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-08-05 13:03:42 -04:00
TextEntry ,
SlateApp . GetCursorPos ( ) ,
FPopupTransitionEffect : : TypeInPopup
) ;
}
TSharedRef < SWidget > SAnimCurvePanel : : CreateCurveContextMenu ( FFloatCurve * Curve ) const
{
FMenuBuilder MenuBuilder ( true , NULL ) ;
MenuBuilder . BeginSection ( " AnimCurvePanelCurveTypes " , LOCTEXT ( " CurveTypesHeading " , " Curve Types " ) ) ;
{
MenuBuilder . AddWidget (
SNew ( SCheckBox )
. IsChecked ( this , & SAnimCurvePanel : : GetCurveFlagAsCheckboxState , Curve , ACF_DrivesMorphTarget )
. OnCheckStateChanged ( this , & SAnimCurvePanel : : SetCurveFlagFromCheckboxState , Curve , ACF_DrivesMorphTarget )
. ToolTipText ( LOCTEXT ( " MorphCurveModeTooltip " , " This curve drives a morph target " ) )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " MorphCurveMode " , " Morph Curve " ) )
] ,
FText ( )
) ;
MenuBuilder . AddWidget (
SNew ( SCheckBox )
. IsChecked ( this , & SAnimCurvePanel : : GetCurveFlagAsCheckboxState , Curve , ACF_DrivesMaterial )
. OnCheckStateChanged ( this , & SAnimCurvePanel : : SetCurveFlagFromCheckboxState , Curve , ACF_DrivesMaterial )
. ToolTipText ( LOCTEXT ( " MaterialCurveModeTooltip " , " This curve drives a material " ) )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " MaterialCurveMode " , " Material Curve " ) )
] ,
FText ( )
) ;
}
MenuBuilder . EndSection ( ) ;
MenuBuilder . BeginSection ( " AnimCurvePanelTrackOptions " , LOCTEXT ( " TrackOptionsHeading " , " Track Options " ) ) ;
{
FText TypeToggleLabel = LOCTEXT ( " TypeToggleToMetadataLabel " , " Convert to Metadata " ) ;
FText TypeToggleToolTip = LOCTEXT ( " TypeToggleToMetadataToolTip " , " Turns this curve into a Metadata entry. This is a destructive operation and will remove the keys in this curve " ) ;
bool bIsConstantCurve = Curve - > GetCurveTypeFlag ( ACF_Metadata ) ;
FUIAction NewAction ;
if ( bIsConstantCurve )
{
TypeToggleLabel = LOCTEXT ( " TypeToggleToVariableLabel " , " Convert to Variable Curve " ) ;
TypeToggleToolTip = LOCTEXT ( " TypeToggleToVariableToolTip " , " Turns this curve into a variable curve. " ) ;
}
NewAction . ExecuteAction . BindSP ( this , & SAnimCurvePanel : : ToggleCurveTypeMenuCallback , Curve ) ;
MenuBuilder . AddMenuEntry (
TypeToggleLabel ,
TypeToggleToolTip ,
FSlateIcon ( ) ,
NewAction ) ;
NewAction . ExecuteAction . BindSP ( this , & SAnimCurvePanel : : DeleteTrack , Curve - > CurveUid ) ;
MenuBuilder . AddMenuEntry (
LOCTEXT ( " RemoveTrack " , " Remove Track " ) ,
LOCTEXT ( " RemoveTrackTooltip " , " Remove this track " ) ,
FSlateIcon ( ) ,
NewAction ) ;
}
MenuBuilder . EndSection ( ) ;
return MenuBuilder . MakeWidget ( ) ;
}
2014-12-10 14:24:09 -05:00
ECheckBoxState SAnimCurvePanel : : GetCurveFlagAsCheckboxState ( FFloatCurve * Curve , EAnimCurveFlags InFlag ) const
2014-08-05 13:03:42 -04:00
{
2014-12-10 14:24:09 -05:00
return Curve - > GetCurveTypeFlag ( InFlag ) ? ECheckBoxState : : Checked : ECheckBoxState : : Unchecked ;
2014-08-05 13:03:42 -04:00
}
2014-12-10 14:24:09 -05:00
void SAnimCurvePanel : : SetCurveFlagFromCheckboxState ( ECheckBoxState CheckState , FFloatCurve * Curve , EAnimCurveFlags InFlag )
2014-08-05 13:03:42 -04:00
{
2014-12-10 14:24:09 -05:00
bool Enabled = CheckState = = ECheckBoxState : : Checked ;
2014-08-05 13:03:42 -04:00
Curve - > SetCurveTypeFlag ( InFlag , Enabled ) ;
}
void SAnimCurvePanel : : ToggleCurveTypeMenuCallback ( FFloatCurve * Curve )
{
check ( Curve ) ;
FScopedTransaction Transaction ( LOCTEXT ( " CurvePanel_ToggleCurveType " , " Toggle curve type " ) ) ;
Sequence - > Modify ( true ) ;
bool bIsSet = Curve - > GetCurveTypeFlag ( ACF_Metadata ) ;
Curve - > SetCurveTypeFlag ( ACF_Metadata , ! bIsSet ) ;
if ( ! bIsSet )
{
// We're moving to a metadata curve, we need to clear out the keys.
Curve - > FloatCurve . Reset ( ) ;
Curve - > FloatCurve . AddKey ( 0.0f , 1.0f ) ;
}
UpdatePanel ( ) ;
}
void SAnimCurvePanel : : AddVariableCurve ( USkeleton : : AnimCurveUID CurveUid )
{
Sequence - > Modify ( true ) ;
Sequence - > RawCurveData . AddCurveData ( CurveUid ) ;
UpdatePanel ( ) ;
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE