Files
UnrealEngineUWP/Engine/Source/Editor/Sequencer/Private/SAnimationOutlinerTreeNode.cpp
Max Chen 4cde9c20a0 Copying //UE4/Dev-Sequencer to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================

Change 2875025 on 2016/02/20 by Andrew.Rodham

	Sequencer: Cinematic viewport improvements
	  - Added optional letterbox overlay (defaults to 2.35:1)
	  - Added ability to change safe frame colors
	  - Added selected tracks' keys to the transport range
	  - Added buttons for jumping between selected tracks' keyframes on the transport controls
	  - Removed black padding around the viewport where possible
	  - Added ability to specify whether a combo button/menu anchor should close when its parent receives focus
	  - Separated logic of FGroupedKeyArea into FSequencerKeyCollection, so it can be used independently
	  - Added playback range to the viewport frame numbers
	  - All frame numbers are now spin boxes

	#jira UE-26429

Change 2875026 on 2016/02/20 by Thomas.Sarkanen

	Added console commands for recording sequences

	Changed plugin to a developer plugin so we can load it when the editor is in -game mode.
	Added Exec commands.
	Added some more logging to help diagnose problems when using commands.
	Added loading/saving of config for recorder settings (stored in Editor.ini).
	Also disabled controls in recorder window when recording.
	Added auto-saving of assets when in non-editor modes.
	Moved animation settings from UnrealEd to Engine module.

Change 2875036 on 2016/02/20 by Max.Chen

	Sequencer: Call RedrawAllViewports instead of RedrawLevelEditingViewports. In particular, this fixes some update issues when editing values in the key editors.

	#jira UE-26960

Change 2875046 on 2016/02/20 by Max.Preussner

	Sequencer: Fix so that clicking on UMG Animations doesn't dirty the scene.

	#jira UE-26249

Change 2875047 on 2016/02/20 by Max.Chen

	Sequencer: Add option to toggle display of channel colors/lines. View->Channel Colors

Change 2877138 on 2016/02/23 by Max.Chen

	Sequencer: Select corresponding track node when selecting key or section. Removed active/inactive selection since it was only being used in deletion and the rules for deletion are now dependent upon what is selected - delete keys and sections before deleting outliner nodes.

Change 2877143 on 2016/02/23 by Thomas.Sarkanen

	Added new math function: WindRelativeAnglesDegrees

	Given two angles in degrees, 'wind' the angle in Angle1 so that it avoids >180 degree flips.
	Good for winding rotations previously expressed as quaternions into a euler-angle representation.

Change 2877147 on 2016/02/23 by Thomas.Sarkanen

	Added the ability to import sequencer transforms from the root node of an animation sequence

	Intended for use after re-importing animations from DCC tools.
	Available in the right-click menu for transform tracks.
	Also added FindTrackBinding to UMovieScene so track bindings can be recovered from tracks.

Change 2877163 on 2016/02/23 by Max.Chen

	Sequencer: Add option to create keyframe sections as infinite. Sequencer defaults to true, UMG defaults to false.

Change 2877165 on 2016/02/23 by Max.Preussner

	Sequencer: Drawing vertical position lines when dragging keys

Change 2878748 on 2016/02/23 by Max.Chen

	Curve Editor: Switch curve type to user when flatting or straightening tangents.

	#jira UE-27277

Change 2878799 on 2016/02/23 by Frank.Fella

	Sequencer - Add folders support to the outliner.

Change 2880769 on 2016/02/24 by Andrew.Rodham

	Sequencer: Added ability to override runtime spawnable ownership in sequencer
	  - This is exposed as an option on spawnables "Keep Alive Outside Playback Range (In Sequencer)"
	  - Enabling this will stop spawnables from being destroyed when scrubbing outside of the playback range

	#jira UE-27205

Change 2880770 on 2016/02/24 by Thomas.Sarkanen

	Sequencer: Added countdown and recording indicator display when recording

	Also fixed extra popups added post-PIE when animation recordings auto shutdown.

Change 2880782 on 2016/02/24 by Max.Chen

	Sequencer: Snapping now also uses the current time as a possible snap time.

	#jira UE-26306

Change 2880793 on 2016/02/24 by Max.Chen

	Sequencer: Add +Animation to Animation track so that it's consistent with all other tracks that have a + button.

Change 2880812 on 2016/02/24 by Max.Chen

	Sequencer: Fix adjusting the leading edge of a shot section so that it cuts into the shot rather than adjusts the start time.

	#jira UE-26306

Change 2881624 on 2016/02/25 by Andrew.Rodham

	Changing shader version GUID to fix corrupt shaders in ddc

Change 2882408 on 2016/02/25 by Thomas.Sarkanen

	Asset/actors stored in TLazyObjectPtrs can now reference game content from engine

	This is a legitimate use case as lazy object ptrs are designed to reference assets/actors cross-domain.

Change 2882409 on 2016/02/25 by Thomas.Sarkanen

[CL 2899785 by Max Chen in Main branch]
2016-03-08 16:55:04 -05:00

388 lines
9.6 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "SequencerPrivatePCH.h"
#include "SAnimationOutlinerTreeNode.h"
#include "ScopedTransaction.h"
#include "Sequencer.h"
#include "MovieScene.h"
#include "MovieSceneSection.h"
#include "MovieSceneCommonHelpers.h"
#include "Engine/Selection.h"
#include "IKeyArea.h"
#include "SEditableLabel.h"
#include "SSequencerTreeView.h"
#include "SColorPicker.h"
#include "SequencerSectionPainter.h"
#define LOCTEXT_NAMESPACE "AnimationOutliner"
class STrackColorPicker : public SCompoundWidget
{
public:
static void OnOpen()
{
if (!Transaction.IsValid())
{
Transaction.Reset(new FScopedTransaction(LOCTEXT("ChangeTrackColor", "Change Track Color")));
}
}
static void OnClose()
{
if (!Transaction.IsValid())
{
return;
}
if (!bMadeChanges)
{
Transaction->Cancel();
}
Transaction.Reset();
}
SLATE_BEGIN_ARGS(STrackColorPicker){}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs, UMovieSceneTrack* InTrack)
{
bMadeChanges = false;
Track = InTrack;
ChildSlot
[
SNew(SColorPicker)
.DisplayInlineVersion(true)
.TargetColorAttribute(this, &STrackColorPicker::GetTrackColor)
.OnColorCommitted(this, &STrackColorPicker::SetTrackColor)
];
}
FLinearColor GetTrackColor() const
{
return Track->GetColorTint().ReinterpretAsLinear();
}
void SetTrackColor(FLinearColor NewColor)
{
bMadeChanges = true;
Track->Modify();
Track->SetColorTint(NewColor.ToFColor(false));
}
private:
UMovieSceneTrack* Track;
static TUniquePtr<FScopedTransaction> Transaction;
static bool bMadeChanges;
};
TUniquePtr<FScopedTransaction> STrackColorPicker::Transaction;
bool STrackColorPicker::bMadeChanges = false;
SAnimationOutlinerTreeNode::~SAnimationOutlinerTreeNode()
{
DisplayNode->OnRenameRequested().RemoveAll(this);
}
void SAnimationOutlinerTreeNode::Construct( const FArguments& InArgs, TSharedRef<FSequencerDisplayNode> Node, const TSharedRef<SSequencerTreeViewRow>& InTableRow )
{
DisplayNode = Node;
bIsTopLevelNode = !Node->GetParent().IsValid();
if (bIsTopLevelNode)
{
ExpandedBackgroundBrush = FEditorStyle::GetBrush( "Sequencer.AnimationOutliner.TopLevelBorder_Expanded" );
CollapsedBackgroundBrush = FEditorStyle::GetBrush( "Sequencer.AnimationOutliner.TopLevelBorder_Collapsed" );
}
else
{
ExpandedBackgroundBrush = FEditorStyle::GetBrush( "Sequencer.AnimationOutliner.DefaultBorder" );
CollapsedBackgroundBrush = FEditorStyle::GetBrush( "Sequencer.AnimationOutliner.DefaultBorder" );
}
TableRowStyle = &FEditorStyle::Get().GetWidgetStyle<FTableRowStyle>("TableView.Row");
FSlateFontInfo NodeFont = FEditorStyle::GetFontStyle("Sequencer.AnimationOutliner.RegularFont");
EditableLabel = SNew(SEditableLabel)
.CanEdit(this, &SAnimationOutlinerTreeNode::HandleNodeLabelCanEdit)
.Font(NodeFont)
.ColorAndOpacity(this, &SAnimationOutlinerTreeNode::GetDisplayNameColor)
.OnTextChanged(this, &SAnimationOutlinerTreeNode::HandleNodeLabelTextChanged)
.Text(this, &SAnimationOutlinerTreeNode::GetDisplayName)
.ToolTipText(this, &SAnimationOutlinerTreeNode::GetDisplayNameToolTipText);
Node->OnRenameRequested().AddRaw(this, &SAnimationOutlinerTreeNode::EnterRenameMode);
auto NodeHeight = [=]() -> FOptionalSize { return DisplayNode->GetNodeHeight(); };
ForegroundColor.Bind(this, &SAnimationOutlinerTreeNode::GetForegroundBasedOnSelection);
TSharedRef<SWidget> FinalWidget =
SNew( SBorder )
.VAlign( VAlign_Center )
.BorderImage( this, &SAnimationOutlinerTreeNode::GetNodeBorderImage )
.BorderBackgroundColor( this, &SAnimationOutlinerTreeNode::GetNodeBackgroundTint )
.Padding(FMargin(0, Node->GetNodePadding().Combined() / 2))
[
SNew( SHorizontalBox )
+ SHorizontalBox::Slot()
[
SNew(SBox)
.HeightOverride_Lambda(NodeHeight)
.Padding(FMargin(5.0f, 0.0f))
[
SNew( SHorizontalBox )
// Expand track lanes button
+ SHorizontalBox::Slot()
.Padding(FMargin(2.f, 0.f, 4.f, 0.f))
.VAlign( VAlign_Center )
.AutoWidth()
[
SNew(SExpanderArrow, InTableRow).IndentAmount(SequencerLayoutConstants::IndentAmount)
]
// Icon
+ SHorizontalBox::Slot()
.Padding(FMargin(0.f, 0.f, 4.f, 0.f))
.VAlign(VAlign_Center)
.AutoWidth()
[
SNew(SOverlay)
+ SOverlay::Slot()
[
SNew(SImage)
.Image(InArgs._IconBrush)
]
+ SOverlay::Slot()
.VAlign(VAlign_Top)
.HAlign(HAlign_Right)
[
SNew(SImage)
.Image(InArgs._IconOverlayBrush)
]
+ SOverlay::Slot()
[
SNew(SSpacer)
.Visibility(EVisibility::Visible)
.ToolTipText(InArgs._IconToolTipText)
]
]
// Label Slot
+ SHorizontalBox::Slot()
.VAlign(VAlign_Center)
.Padding(FMargin(0.f, 0.f, 4.f, 0.f))
.AutoWidth()
[
EditableLabel.ToSharedRef()
]
// Arbitrary customization slot
+ SHorizontalBox::Slot()
[
InArgs._CustomContent.Widget
]
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SComboButton)
.ContentPadding(0)
.VAlign(VAlign_Fill)
.HasDownArrow(false)
.ButtonStyle(FEditorStyle::Get(), "Sequencer.AnimationOutliner.ColorStrip")
.OnGetMenuContent(this, &SAnimationOutlinerTreeNode::OnGetColorPicker)
.OnMenuOpenChanged_Lambda([](bool bIsOpen){
if (bIsOpen)
{
STrackColorPicker::OnOpen();
}
else if (!bIsOpen)
{
STrackColorPicker::OnClose();
}
})
.ButtonContent()
[
SNew(SBox)
.WidthOverride(6.f)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("WhiteBrush"))
.ColorAndOpacity(this, &SAnimationOutlinerTreeNode::GetTrackColorTint)
]
]
]
];
ChildSlot
[
FinalWidget
];
}
void SAnimationOutlinerTreeNode::EnterRenameMode()
{
EditableLabel->EnterTextMode();
}
void SAnimationOutlinerTreeNode::GetAllDescendantNodes(TSharedPtr<FSequencerDisplayNode> RootNode, TArray<TSharedRef<FSequencerDisplayNode> >& AllNodes)
{
if (!RootNode.IsValid())
{
return;
}
AllNodes.Add(RootNode.ToSharedRef());
const FSequencerDisplayNode* RootNodeC = RootNode.Get();
for (TSharedRef<FSequencerDisplayNode> ChildNode : RootNodeC->GetChildNodes())
{
AllNodes.Add(ChildNode);
GetAllDescendantNodes(ChildNode, AllNodes);
}
}
void SAnimationOutlinerTreeNode::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
DisplayNode->GetParentTree().SetHoveredNode(DisplayNode);
SWidget::OnMouseEnter(MyGeometry, MouseEvent);
}
void SAnimationOutlinerTreeNode::OnMouseLeave(const FPointerEvent& MouseEvent)
{
DisplayNode->GetParentTree().SetHoveredNode(nullptr);
SWidget::OnMouseLeave(MouseEvent);
}
const FSlateBrush* SAnimationOutlinerTreeNode::GetNodeBorderImage() const
{
return DisplayNode->IsExpanded() ? ExpandedBackgroundBrush : CollapsedBackgroundBrush;
}
FSlateColor SAnimationOutlinerTreeNode::GetNodeBackgroundTint() const
{
FSequencer& Sequencer = DisplayNode->GetSequencer();
const bool bIsSelected = Sequencer.GetSelection().IsSelected(DisplayNode.ToSharedRef());
if (bIsSelected)
{
return FEditorStyle::GetSlateColor("SelectionColor_Pressed");
}
else if (Sequencer.GetSelection().NodeHasSelectedKeysOrSections(DisplayNode.ToSharedRef()))
{
return FLinearColor(FColor(115, 115, 115, 255));
}
else if (DisplayNode->IsHovered())
{
return bIsTopLevelNode ? FLinearColor(FColor(52, 52, 52, 255)) : FLinearColor(FColor(72, 72, 72, 255));
}
else
{
return bIsTopLevelNode ? FLinearColor(FColor(48, 48, 48, 255)) : FLinearColor(FColor(62, 62, 62, 255));
}
}
TSharedRef<SWidget> SAnimationOutlinerTreeNode::OnGetColorPicker() const
{
UMovieSceneTrack* Track = nullptr;
FSequencerDisplayNode* Current = DisplayNode.Get();
while (Current && Current->GetType() != ESequencerNode::Object)
{
if (Current->GetType() == ESequencerNode::Track)
{
Track = static_cast<FSequencerTrackNode*>(Current)->GetTrack();
if (Track)
{
break;
}
}
Current = Current->GetParent().Get();
}
if (!Track)
{
return SNullWidget::NullWidget;
}
return SNew(STrackColorPicker, Track);
}
FSlateColor SAnimationOutlinerTreeNode::GetTrackColorTint() const
{
FSequencerDisplayNode* Current = DisplayNode.Get();
while (Current && Current->GetType() != ESequencerNode::Object)
{
if (Current->GetType() == ESequencerNode::Track)
{
UMovieSceneTrack* Track = static_cast<FSequencerTrackNode*>(Current)->GetTrack();
if (Track)
{
return FSequencerSectionPainter::BlendColor(Track->GetColorTint());
}
}
Current = Current->GetParent().Get();
}
return FLinearColor::Transparent;
}
FSlateColor SAnimationOutlinerTreeNode::GetForegroundBasedOnSelection() const
{
FSequencer& Sequencer = DisplayNode->GetSequencer();
const bool bIsSelected = Sequencer.GetSelection().IsSelected(DisplayNode.ToSharedRef());
return bIsSelected ? TableRowStyle->SelectedTextColor : TableRowStyle->TextColor;
}
EVisibility SAnimationOutlinerTreeNode::GetExpanderVisibility() const
{
return DisplayNode->GetNumChildren() > 0 ? EVisibility::Visible : EVisibility::Hidden;
}
FSlateColor SAnimationOutlinerTreeNode::GetDisplayNameColor() const
{
return DisplayNode->GetDisplayNameColor();
}
FText SAnimationOutlinerTreeNode::GetDisplayNameToolTipText() const
{
return DisplayNode->GetDisplayNameToolTipText();
}
FText SAnimationOutlinerTreeNode::GetDisplayName() const
{
return DisplayNode->GetDisplayName();
}
bool SAnimationOutlinerTreeNode::HandleNodeLabelCanEdit() const
{
return DisplayNode->CanRenameNode();
}
void SAnimationOutlinerTreeNode::HandleNodeLabelTextChanged(const FText& NewLabel)
{
DisplayNode->SetDisplayName(NewLabel);
}
#undef LOCTEXT_NAMESPACE