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]
This commit is contained in:
Max Chen
2016-03-08 16:55:04 -05:00
committed by Max.Chen@epicgames.com
parent 9c8b57b891
commit 4cde9c20a0
440 changed files with 16466 additions and 6125 deletions

View File

@@ -5,6 +5,7 @@
#include "SSequencerTreeView.h"
#include "SSequencerTrackLane.h"
#include "SSequencerTrackArea.h"
#include "SequencerDisplayNodeDragDropOp.h"
static FName TrackAreaName = "TrackArea";
@@ -54,7 +55,12 @@ void SSequencerTreeViewRow::Construct(const FArguments& InArgs, const TSharedRef
Node = InNode;
OnGenerateWidgetForColumn = InArgs._OnGenerateWidgetForColumn;
SMultiColumnTableRow::Construct(SMultiColumnTableRow::FArguments(), OwnerTableView);
SMultiColumnTableRow::Construct(
SMultiColumnTableRow::FArguments()
.OnDragDetected(this, &SSequencerTreeViewRow::OnDragDetected)
.OnCanAcceptDrop(this, &SSequencerTreeViewRow::OnCanAcceptDrop)
.OnAcceptDrop(this, &SSequencerTreeViewRow::OnAcceptDrop),
OwnerTableView);
}
TSharedRef<SWidget> SSequencerTreeViewRow::GenerateWidgetForColumn(const FName& ColumnId)
@@ -68,6 +74,60 @@ TSharedRef<SWidget> SSequencerTreeViewRow::GenerateWidgetForColumn(const FName&
return SNullWidget::NullWidget;
}
FReply SSequencerTreeViewRow::OnDragDetected( const FGeometry& InGeometry, const FPointerEvent& InPointerEvent )
{
TSharedPtr<FSequencerDisplayNode> DisplayNode = Node.Pin();
if ( DisplayNode.IsValid() )
{
FSequencer& Sequencer = DisplayNode->GetParentTree().GetSequencer();
if ( Sequencer.GetSelection().GetSelectedOutlinerNodes().Num() > 0 )
{
TArray<TSharedRef<FSequencerDisplayNode> > DraggableNodes;
for ( const TSharedRef<FSequencerDisplayNode> SelectedNode : Sequencer.GetSelection().GetSelectedOutlinerNodes() )
{
if ( SelectedNode->CanDrag() )
{
DraggableNodes.Add(SelectedNode);
}
}
TSharedRef<FSequencerDisplayNodeDragDropOp> DragDropOp = MakeShareable( new FSequencerDisplayNodeDragDropOp( DraggableNodes ) );
DragDropOp->CurrentHoverText = FText::Format( NSLOCTEXT( "SequencerTreeViewRow", "DefaultDragDropFormat", "Move {0} item(s)" ), FText::AsNumber( DraggableNodes.Num() ) );
DragDropOp->SetupDefaults();
DragDropOp->Construct();
return FReply::Handled().BeginDragDrop( DragDropOp );
}
}
return FReply::Unhandled();
}
TOptional<EItemDropZone> SSequencerTreeViewRow::OnCanAcceptDrop( const FDragDropEvent& DragDropEvent, EItemDropZone ItemDropZone, FDisplayNodeRef DisplayNode )
{
TSharedPtr<FSequencerDisplayNodeDragDropOp> DragDropOp = DragDropEvent.GetOperationAs<FSequencerDisplayNodeDragDropOp>();
if ( DragDropOp.IsValid() )
{
DragDropOp->ResetToDefaultToolTip();
TOptional<EItemDropZone> AllowedDropZone = DisplayNode->CanDrop( *DragDropOp, ItemDropZone );
if ( AllowedDropZone.IsSet() == false )
{
DragDropOp->CurrentIconBrush = FEditorStyle::GetBrush( TEXT( "Graph.ConnectorFeedback.Error" ) );
}
return AllowedDropZone;
}
return TOptional<EItemDropZone>();
}
FReply SSequencerTreeViewRow::OnAcceptDrop( const FDragDropEvent& DragDropEvent, EItemDropZone ItemDropZone, FDisplayNodeRef DisplayNode )
{
TSharedPtr<FSequencerDisplayNodeDragDropOp> DragDropOp = DragDropEvent.GetOperationAs<FSequencerDisplayNodeDragDropOp>();
if ( DragDropOp.IsValid())
{
DisplayNode->Drop( DragDropOp->GetDraggedNodes(), ItemDropZone );
return FReply::Handled();
}
return FReply::Unhandled();
}
TSharedPtr<FSequencerDisplayNode> SSequencerTreeViewRow::GetDisplayNode() const
{
return Node.Pin();
@@ -87,12 +147,15 @@ void SSequencerTreeView::Construct(const FArguments& InArgs, const TSharedRef<FS
{
SequencerNodeTree = InNodeTree;
TrackArea = InTrackArea;
bUpdatingSequencerSelection = false;
bUpdatingTreeSelection = false;
bSequencerSelectionChangeBroadcastWasSupressed = false;
// We 'leak' these delegates (they'll get cleaned up automatically when the invocation list changes)
// It's not safe to attempt their removal in ~SSequencerTreeView because SequencerNodeTree->GetSequencer() may not be valid
FSequencer& Sequencer = InNodeTree->GetSequencer();
Sequencer.GetSettings()->GetOnShowCurveEditorChanged().AddSP(this, &SSequencerTreeView::UpdateTrackArea);
Sequencer.GetSelection().GetOnOutlinerNodeSelectionChanged().AddSP(this, &SSequencerTreeView::OnSequencerSelectionChangedExternally);
Sequencer.GetSelection().GetOnOutlinerNodeSelectionChanged().AddSP(this, &SSequencerTreeView::SynchronizeTreeSelectionWithSequencerSelection);
HeaderRow = SNew(SHeaderRow).Visibility(EVisibility::Collapsed);
@@ -102,13 +165,14 @@ void SSequencerTreeView::Construct(const FArguments& InArgs, const TSharedRef<FS
(
STreeView::FArguments()
.TreeItemsSource(&RootNodes)
.SelectionMode(ESelectionMode::None)
.SelectionMode(ESelectionMode::Multi)
.OnGenerateRow(this, &SSequencerTreeView::OnGenerateRow)
.OnGetChildren(this, &SSequencerTreeView::OnGetChildren)
.HeaderRow(HeaderRow)
.ExternalScrollbar(InArgs._ExternalScrollbar)
.OnExpansionChanged(this, &SSequencerTreeView::OnExpansionChanged)
.AllowOverscroll(EAllowOverscroll::No)
.OnContextMenuOpening( this, &SSequencerTreeView::OnContextMenuOpening )
);
}
@@ -375,33 +439,124 @@ void SSequencerTreeView::UpdateTrackArea()
}
}
void SSequencerTreeView::OnSequencerSelectionChangedExternally()
void SSequencerTreeView::SynchronizeTreeSelectionWithSequencerSelection()
{
Private_ClearSelection();
FSequencer& Sequencer = SequencerNodeTree->GetSequencer();
for (auto& Node : Sequencer.GetSelection().GetSelectedOutlinerNodes())
if ( bUpdatingSequencerSelection == false )
{
Private_SetItemSelection(Node, true, false);
}
bUpdatingTreeSelection = true;
{
Private_ClearSelection();
Private_SignalSelectionChanged(ESelectInfo::Direct);
FSequencer& Sequencer = SequencerNodeTree->GetSequencer();
for ( auto& Node : Sequencer.GetSelection().GetSelectedOutlinerNodes() )
{
Private_SetItemSelection( Node, true, false );
}
Private_SignalSelectionChanged( ESelectInfo::Direct );
}
bUpdatingTreeSelection = false;
}
}
void SSequencerTreeView::Private_SetItemSelection( FDisplayNodeRef TheItem, bool bShouldBeSelected, bool bWasUserDirected )
{
STreeView::Private_SetItemSelection( TheItem, bShouldBeSelected, bWasUserDirected );
if ( bUpdatingTreeSelection == false )
{
// Don't broadcast the sequencer selection change on individual tree changes. Wait for signal selection changed.
FSequencerSelection& SequencerSelection = SequencerNodeTree->GetSequencer().GetSelection();
SequencerSelection.SuspendBroadcast();
bSequencerSelectionChangeBroadcastWasSupressed = true;
if ( bShouldBeSelected )
{
SequencerSelection.AddToSelection( TheItem );
}
else
{
SequencerSelection.RemoveFromSelection( TheItem );
}
SequencerSelection.ResumeBroadcast();
}
}
void SSequencerTreeView::Private_ClearSelection()
{
STreeView::Private_ClearSelection();
if ( bUpdatingTreeSelection == false )
{
// Don't broadcast the sequencer selection change on individual tree changes. Wait for signal selection changed.
FSequencerSelection& SequencerSelection = SequencerNodeTree->GetSequencer().GetSelection();
SequencerSelection.SuspendBroadcast();
bSequencerSelectionChangeBroadcastWasSupressed = true;
SequencerSelection.EmptySelectedOutlinerNodes();
SequencerSelection.ResumeBroadcast();
}
}
void SSequencerTreeView::Private_SelectRangeFromCurrentTo( FDisplayNodeRef InRangeSelectionEnd )
{
STreeView::Private_SelectRangeFromCurrentTo( InRangeSelectionEnd );
if ( bUpdatingTreeSelection == false )
{
// Don't broadcast the sequencer selection change on individual tree changes. Wait for signal selection changed.
FSequencerSelection& SequencerSelection = SequencerNodeTree->GetSequencer().GetSelection();
SequencerSelection.SuspendBroadcast();
bSequencerSelectionChangeBroadcastWasSupressed = true;
SynchronizeSequencerSelectionWithTreeSelection();
SequencerSelection.ResumeBroadcast();
}
}
void SSequencerTreeView::Private_SignalSelectionChanged(ESelectInfo::Type SelectInfo)
{
if (SelectInfo != ESelectInfo::Direct)
if ( bUpdatingTreeSelection == false )
{
bUpdatingSequencerSelection = true;
{
FSequencerSelection& SequencerSelection = SequencerNodeTree->GetSequencer().GetSelection();
SequencerSelection.SuspendBroadcast();
bool bSelectionChanged = SynchronizeSequencerSelectionWithTreeSelection();
SequencerSelection.ResumeBroadcast();
if ( bSequencerSelectionChangeBroadcastWasSupressed || bSelectionChanged )
{
SequencerSelection.RequestOutlinerNodeSelectionChangedBroadcast();
bSequencerSelectionChangeBroadcastWasSupressed = false;
}
}
bUpdatingSequencerSelection = false;
}
STreeView::Private_SignalSelectionChanged(SelectInfo);
}
bool SSequencerTreeView::SynchronizeSequencerSelectionWithTreeSelection()
{
bool bSelectionChanged = false;
const TSet<TSharedRef<FSequencerDisplayNode>>& SequencerSelection = SequencerNodeTree->GetSequencer().GetSelection().GetSelectedOutlinerNodes();
if ( SelectedItems.Num() != SequencerSelection.Num() || SelectedItems.Difference( SequencerSelection ).Num() != 0 )
{
FSequencer& Sequencer = SequencerNodeTree->GetSequencer();
FSequencerSelection& Selection = Sequencer.GetSelection();
Selection.EmptySelectedOutlinerNodes();
for (auto& Item : GetSelectedItems())
for ( auto& Item : GetSelectedItems() )
{
Selection.AddToSelection(Item);
Selection.AddToSelection( Item );
}
bSelectionChanged = true;
}
return bSelectionChanged;
}
STreeView::Private_SignalSelectionChanged(SelectInfo);
TSharedPtr<SWidget> SSequencerTreeView::OnContextMenuOpening()
{
const TSet<TSharedRef<FSequencerDisplayNode>> SelectedNodes = SequencerNodeTree->GetSequencer().GetSelection().GetSelectedOutlinerNodes();
if ( SelectedNodes.Num() == 1 )
{
return SelectedNodes.Array()[0]->OnSummonContextMenu();
}
return TSharedPtr<SWidget>();
}
void SSequencerTreeView::Refresh()
@@ -421,6 +576,12 @@ void SSequencerTreeView::Refresh()
}
}
// Force synchronization of selected tree view items here since the tree nodes may have been rebuilt
// and the treeview's selection will now be invalid.
bUpdatingTreeSelection = true;
SynchronizeTreeSelectionWithSequencerSelection();
bUpdatingTreeSelection = false;
RequestTreeRefresh();
}