Files
UnrealEngineUWP/Engine/Source/Editor/Sequencer/Private/Tools/DragOperation_Stretch.cpp
Max Chen 0167d4ea0f Sequencer: MVVM2 branch and Layer Bars
Copying //Tasks/UE5/Dev-SequencerMVVM2 to Main (//UE5/Main) @20364093

#preflight 628866dfb94f739b152c1e29
#preflight 628866e4585e8f793ee80943
#rb ludovic.chabant, andrew.rodham
#fyi ludovic.chabant, andrew.rodham, andrew.porter
#jira UE-105322

[CL 20364493 by Max Chen in ue5-main branch]
2022-05-25 10:39:33 -04:00

230 lines
7.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DragOperation_Stretch.h"
#include "MVVM/ViewModels/ViewModel.h"
#include "SequencerSettings.h"
#include "ISequencer.h"
#include "Sequencer.h"
#include "SequencerSelection.h"
#include "MVVM/ViewModels/SectionModel.h"
#include "MVVM/ViewModels/VirtualTrackArea.h"
#define LOCTEXT_NAMESPACE "FEditToolDragOperation_Stretch"
namespace UE
{
namespace Sequencer
{
FEditToolDragOperation_Stretch::FEditToolDragOperation_Stretch(ISequencer* InSequencer, EStretchConstraint InStretchConstraint, FFrameNumber InDragStartPosition)
: Sequencer(InSequencer)
, DragStartPosition(InDragStartPosition)
, StretchConstraint(InStretchConstraint)
{
GlobalParameters.Anchor = GlobalParameters.Handle = InDragStartPosition.Value;
}
bool FEditToolDragOperation_Stretch::InitiateStretch(TSharedPtr<FViewModel> Controller, TSharedPtr<IStretchableExtension> Target, int32 Priority, const FStretchParameters& InParams)
{
if (!ensure(InParams.IsValid()))
{
return false;
}
if (FStretchTarget* ExistingTarget = StretchTargets.Find(Target))
{
if (ExistingTarget->Priority < Priority)
{
ExistingTarget->Params = InParams;
return true;
}
}
else
{
StretchTargets.Add(Target, FStretchTarget{ InParams, Priority });
return true;
}
return false;
}
void FEditToolDragOperation_Stretch::DoNotSnapTo(TSharedPtr<FViewModel> Model)
{
if (FSectionModel* SectionModel = Model->CastThis<FSectionModel>())
{
SnapExclusion.Add(SectionModel->GetSection());
}
}
void FEditToolDragOperation_Stretch::OnBeginDrag(const FPointerEvent& MouseEvent, FVector2D LocalMousePos, const FVirtualTrackArea& VirtualTrackArea)
{
TArray<IStretchableExtension*> AllStretchables;
for (TWeakPtr<FViewModel> WeakSelectedModel : Sequencer->GetSelection().GetSelectedTrackAreaItems())
{
TSharedPtr<FViewModel> Model = WeakSelectedModel.Pin();
IStretchableExtension* Stretchable = Model ? Model->CastThis<IStretchableExtension>() : nullptr;
if (Stretchable)
{
Stretchable->OnInitiateStretch(*this, StretchConstraint, &GlobalParameters);
}
}
Transaction = MakeUnique<FScopedTransaction>(LOCTEXT("StretchTransaction", "Stretch"));
FStretchScreenParameters ScreenParameters;
ScreenParameters.DragStartPosition = DragStartPosition;
ScreenParameters.CurrentDragPosition = DragStartPosition;
ScreenParameters.LocalMousePos = LocalMousePos;
ScreenParameters.MouseEvent = &MouseEvent;
ScreenParameters.VirtualTrackArea = &VirtualTrackArea;
FStretchParameters TempParams;
const bool bUseGlobalParams = MouseEvent.IsAltDown() == false;
for (auto TargetIt = StretchTargets.CreateIterator(); TargetIt; ++TargetIt)
{
FStretchParameters* Params = &TargetIt.Value().Params;
if (bUseGlobalParams)
{
// Ensure the TempParams match the global ones (in-case something overwrote them)
TempParams = GlobalParameters;
Params = &TempParams;
}
EStretchResult Result = TargetIt.Key()->OnBeginStretch(*this, ScreenParameters, Params);
// Don't drag if the parameters are invalid
if (Result == EStretchResult::Failure)
{
TargetIt.RemoveCurrent();
}
}
SnapField = MakeUnique<FSequencerSnapField>();
SnapField->Initialize(*static_cast<FSequencer*>(Sequencer), *this);
SnapField->AddExplicitSnap(FSnapPoint{FSnapPoint::CustomSection, DragStartPosition });
SnapField->Finalize();
}
void FEditToolDragOperation_Stretch::OnDrag(const FPointerEvent& MouseEvent, FVector2D LocalMousePos, const FVirtualTrackArea& VirtualTrackArea)
{
UE::MovieScene::FScopedSignedObjectModifyDefer DeferMarkAsChanged(true);
FFrameTime CurrentTime = VirtualTrackArea.PixelToFrame(LocalMousePos.X);
if (Sequencer->GetSequencerSettings()->GetIsSnapEnabled())
{
const float PixelSnapWidth = 10.f;
const float SnapThresholdPx = VirtualTrackArea.PixelToSeconds(PixelSnapWidth) - VirtualTrackArea.PixelToSeconds(0.f);
const int32 SnapThreshold = (SnapThresholdPx * Sequencer->GetFocusedTickResolution()).FloorToFrame().Value;
TOptional<FFrameNumber> SnappedResult = SnapField->Snap(CurrentTime.RoundToFrame(), SnapThreshold);
if (SnappedResult.IsSet())
{
CurrentTime = SnappedResult.GetValue();
}
}
FStretchScreenParameters ScreenParameters;
ScreenParameters.DragStartPosition = DragStartPosition;
ScreenParameters.CurrentDragPosition = CurrentTime;
ScreenParameters.LocalMousePos = LocalMousePos;
ScreenParameters.MouseEvent = &MouseEvent;
ScreenParameters.VirtualTrackArea = &VirtualTrackArea;
FStretchParameters TempParams;
const bool bUseGlobalParams = MouseEvent.IsAltDown() == false;
for (TPair<TSharedPtr<IStretchableExtension>, FStretchTarget> Pair : StretchTargets)
{
FStretchParameters* Params = &Pair.Value.Params;
if (bUseGlobalParams)
{
// Ensure the TempParams match the global ones (in-case something overwrote them)
TempParams = GlobalParameters;
Params = &TempParams;
}
Pair.Key->OnStretch(*this, ScreenParameters, Params);
}
}
void FEditToolDragOperation_Stretch::OnEndDrag( const FPointerEvent& MouseEvent, FVector2D LocalMousePos, const FVirtualTrackArea& VirtualTrackArea)
{
FFrameTime CurrentTime = VirtualTrackArea.PixelToFrame(LocalMousePos.X);
if (Sequencer->GetSequencerSettings()->GetIsSnapEnabled())
{
const float PixelSnapWidth = 10.f;
const float SnapThresholdPx = VirtualTrackArea.PixelToSeconds(PixelSnapWidth) - VirtualTrackArea.PixelToSeconds(0.f);
const int32 SnapThreshold = (SnapThresholdPx * Sequencer->GetFocusedTickResolution()).FloorToFrame().Value;
TOptional<FFrameNumber> SnappedResult = SnapField->Snap(CurrentTime.RoundToFrame(), SnapThreshold);
if (SnappedResult.IsSet())
{
CurrentTime = SnappedResult.GetValue();
}
}
FStretchScreenParameters ScreenParameters;
ScreenParameters.DragStartPosition = DragStartPosition;
ScreenParameters.CurrentDragPosition = VirtualTrackArea.PixelToFrame(LocalMousePos.X);
ScreenParameters.LocalMousePos = LocalMousePos;
ScreenParameters.MouseEvent = &MouseEvent;
ScreenParameters.VirtualTrackArea = &VirtualTrackArea;
FStretchParameters TempParams;
const bool bUseGlobalParams = MouseEvent.IsAltDown() == false;
for (TPair<TSharedPtr<IStretchableExtension>, FStretchTarget> Pair : StretchTargets)
{
FStretchParameters* Params = &Pair.Value.Params;
if (bUseGlobalParams)
{
// Ensure the TempParams match the global ones (in-case something overwrote them)
TempParams = GlobalParameters;
Params = &TempParams;
}
Pair.Key->OnEndStretch(*this, ScreenParameters, Params);
}
Transaction.Reset();
}
bool FEditToolDragOperation_Stretch::IsKeyApplicable(FKeyHandle KeyHandle, const FViewModelPtr& Owner) const
{
TSharedPtr<FChannelModel> Channel = Owner.ImplicitCast();
return !Channel || !SnapExclusion.Contains(Channel->GetSection());
}
bool FEditToolDragOperation_Stretch::AreSectionBoundsApplicable(UMovieSceneSection* Section) const
{
return !SnapExclusion.Contains(Section);
}
bool FEditToolDragOperation_Stretch::AreSectionCustomSnapsApplicable(UMovieSceneSection* Section) const
{
return !SnapExclusion.Contains(Section);
}
FCursorReply FEditToolDragOperation_Stretch::GetCursor() const
{
return FCursorReply::Cursor(EMouseCursor::ResizeLeftRight);
}
int32 FEditToolDragOperation_Stretch::OnPaint(const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId) const
{
return LayerId;
}
} // namespace Sequencer
} // namespace UE
#undef LOCTEXT_NAMESPACE