FReply FSequencerTimeSliderController::OnMouseButtonUp( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { bool bHandleLeftMouseButton = MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && WidgetOwner->HasMouseCapture(); bool bHandleRightMouseButton = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && WidgetOwner->HasMouseCapture() && TimeSliderArgs.AllowZoom ; if ( bHandleRightMouseButton ) { if (!bPanning) { // return unhandled in case our parent wants to use our right mouse button to open a context menu return FReply::Unhandled().ReleaseMouseCapture(); } bPanning = false; return FReply::Handled().ReleaseMouseCapture(); } else if ( bHandleLeftMouseButton ) { if( bDraggingScrubber ) { TimeSliderArgs.OnEndScrubberMovement.ExecuteIfBound(); } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = RangeToScreen.LocalXToInput(CursorPos.X); const USequencerSnapSettings* SnapSettings = GetDefault<USequencerSnapSettings>(); if ( SnapSettings->GetIsSnapEnabled() && SnapSettings->GetSnapPlayTimeToInterval() ) { NewValue = SnapSettings->SnapToInterval( NewValue ); } CommitScrubPosition( NewValue, /*bIsScrubbing=*/false ); } bDraggingScrubber = false; return FReply::Handled().ReleaseMouseCapture(); } return FReply::Unhandled(); }
FReply FVisualLoggerTimeSliderController::OnMouseButtonUp( SWidget& WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { bool bHandleLeftMouseButton = MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && WidgetOwner.HasMouseCapture(); bool bHandleRightMouseButton = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && WidgetOwner.HasMouseCapture() && TimeSliderArgs.AllowZoom ; if ( bHandleRightMouseButton ) { if (!bPanning) { // return unhandled in case our parent wants to use our right mouse button to open a context menu return FReply::Unhandled().ReleaseMouseCapture(); } bPanning = false; FReply::Handled().CaptureMouse(WidgetOwner.AsShared()).UseHighPrecisionMouseMovement(WidgetOwner.AsShared()); return FReply::Handled().ReleaseMouseCapture(); } else if ( bHandleLeftMouseButton ) { if( bDraggingScrubber ) { TimeSliderArgs.OnEndScrubberMovement.ExecuteIfBound(); } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = RangeToScreen.LocalXToInput(CursorPos.X); CommitScrubPosition( NewValue, /*bIsScrubbing=*/false ); } bDraggingScrubber = false; return FReply::Handled().ReleaseMouseCapture(); } return FReply::Unhandled(); }
FReply FVisualLoggerTimeSliderController::OnMouseButtonDown( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { bool bHandleLeftMouseButton = MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton; bool bHandleRightMouseButton = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && TimeSliderArgs.AllowZoom; DistanceDragged = 0; if ( bHandleLeftMouseButton ) { // Always capture mouse if we left or right click on the widget FScrubRangeToScreen RangeToScreen(TimeSliderArgs.ViewRange.Get(), MyGeometry.Size); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = RangeToScreen.LocalXToInput(CursorPos.X); CommitScrubPosition(NewValue, /*bIsScrubbing=*/false); return FReply::Handled().CaptureMouse( WidgetOwner ).PreventThrottling(); } else if ( bHandleRightMouseButton ) { return FReply::Handled().CaptureMouse(WidgetOwner); } return FReply::Unhandled(); }
FReply FSequencerTimeSliderController::OnMouseMove( SWidget& WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( WidgetOwner.HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton )) { if (!bPanning) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { bPanning = true; } } else { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); FScrubRangeToScreen ScaleInfo( LocalViewRange, MyGeometry.Size ); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; float NewViewOutputMin = LocalViewRangeMin - InputDelta.X; float NewViewOutputMax = LocalViewRangeMax - InputDelta.X; ClampViewRange(NewViewOutputMin, NewViewOutputMax); SetViewRange(NewViewOutputMin, NewViewOutputMax, EViewRangeInterpolation::Immediate); } } else if (MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton )) { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( MouseDragType == DRAG_NONE ) { if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { FScrubRangeToScreen RangeToScreen(LocalViewRange, MyGeometry.Size); const float ScrubPosition = TimeSliderArgs.ScrubPosition.Get(); TRange<float> PlaybackRange = TimeSliderArgs.PlaybackRange.Get(); float LocalMouseDownPos = RangeToScreen.InputToLocalX(MouseDownRange[0]); // Favor dragging the end position if (HitTestPlaybackEnd(RangeToScreen, PlaybackRange, LocalMouseDownPos, ScrubPosition)) { MouseDragType = DRAG_END_RANGE; TimeSliderArgs.OnBeginPlaybackRangeDrag.ExecuteIfBound(); } else if (HitTestPlaybackStart(RangeToScreen, PlaybackRange, LocalMouseDownPos, ScrubPosition)) { MouseDragType = DRAG_START_RANGE; TimeSliderArgs.OnBeginPlaybackRangeDrag.ExecuteIfBound(); } else if (FSlateApplication::Get().GetModifierKeys().AreModifersDown(EModifierKey::Control)) { MouseDragType = DRAG_SETTING_RANGE; } else { MouseDragType = DRAG_SCRUBBING_TIME; TimeSliderArgs.OnBeginScrubberMovement.ExecuteIfBound(); } } } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetLastScreenSpacePosition() ); float NewValue = RangeToScreen.LocalXToInput( CursorPos.X ); // Set the start range time? if (MouseDragType == DRAG_START_RANGE) { if (TimeSliderArgs.Settings->GetIsSnapEnabled()) { NewValue = TimeSliderArgs.Settings->SnapTimeToInterval(NewValue); } SetPlaybackRangeStart(NewValue); } // Set the end range time? else if(MouseDragType == DRAG_END_RANGE) { if (TimeSliderArgs.Settings->GetIsSnapEnabled()) { NewValue = TimeSliderArgs.Settings->SnapTimeToInterval(NewValue); } SetPlaybackRangeEnd(NewValue); } else if (MouseDragType == DRAG_SCRUBBING_TIME) { if ( TimeSliderArgs.Settings->GetIsSnapEnabled() && TimeSliderArgs.Settings->GetSnapPlayTimeToInterval() ) { NewValue = TimeSliderArgs.Settings->SnapTimeToInterval(NewValue); } // Delegate responsibility for clamping to the current viewrange to the client CommitScrubPosition( NewValue, /*bIsScrubbing=*/true ); } else if (MouseDragType == DRAG_SETTING_RANGE) { MouseDownRange[1] = NewValue; } } } return FReply::Handled(); } return FReply::Unhandled(); }
FReply FSequencerTimeSliderController::OnMouseButtonUp( SWidget& WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { bool bHandleLeftMouseButton = MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && WidgetOwner.HasMouseCapture(); bool bHandleRightMouseButton = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && WidgetOwner.HasMouseCapture() && TimeSliderArgs.AllowZoom ; if ( bHandleRightMouseButton ) { if (!bPanning) { // Open a context menu if allowed if (ContextMenuSupression == 0 && TimeSliderArgs.PlaybackRange.IsSet()) { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); float MouseValue = RangeToScreen.LocalXToInput( CursorPos.X ); if (TimeSliderArgs.Settings->GetIsSnapEnabled()) { MouseValue = TimeSliderArgs.Settings->SnapTimeToInterval(MouseValue); } TSharedRef<SWidget> MenuContent = OpenSetPlaybackRangeMenu(MouseValue); FSlateApplication::Get().PushMenu( WidgetOwner.AsShared(), MouseEvent.GetEventPath() != nullptr ? *MouseEvent.GetEventPath() : FWidgetPath(), MenuContent, MouseEvent.GetScreenSpacePosition(), FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu ) ); return FReply::Handled().SetUserFocus(MenuContent, EFocusCause::SetDirectly).ReleaseMouseCapture(); } // return unhandled in case our parent wants to use our right mouse button to open a context menu return FReply::Unhandled().ReleaseMouseCapture(); } bPanning = false; return FReply::Handled().ReleaseMouseCapture(); } else if ( bHandleLeftMouseButton ) { if (MouseDragType == DRAG_START_RANGE) { TimeSliderArgs.OnEndPlaybackRangeDrag.ExecuteIfBound(); } // Set the end range time? else if (MouseDragType == DRAG_END_RANGE) { TimeSliderArgs.OnEndPlaybackRangeDrag.ExecuteIfBound(); } else if (MouseDragType == DRAG_SETTING_RANGE) { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = RangeToScreen.LocalXToInput(CursorPos.X); if ( TimeSliderArgs.Settings->GetIsSnapEnabled() ) { NewValue = TimeSliderArgs.Settings->SnapTimeToInterval(NewValue); } float DownValue = MouseDownRange[0]; if ( TimeSliderArgs.Settings->GetIsSnapEnabled() ) { DownValue = TimeSliderArgs.Settings->SnapTimeToInterval(DownValue); } // Zoom in if (NewValue > DownValue) { // push the current value onto the stack RangeStack.Add(FVector2D(TimeSliderArgs.ViewRange.Get().GetLowerBoundValue(), TimeSliderArgs.ViewRange.Get().GetUpperBoundValue())); } // Zoom out else if (RangeStack.Num()) { // pop the stack FVector2D LastRange = RangeStack.Pop(); DownValue = LastRange[0]; NewValue = LastRange[1]; } TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound(TRange<float>(DownValue, NewValue), EViewRangeInterpolation::Immediate); if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves TimeSliderArgs.ViewRange.Set( TRange<float>( DownValue, NewValue ) ); } } else { TimeSliderArgs.OnEndScrubberMovement.ExecuteIfBound(); FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = RangeToScreen.LocalXToInput(CursorPos.X); if ( TimeSliderArgs.Settings->GetIsSnapEnabled() && TimeSliderArgs.Settings->GetSnapPlayTimeToInterval() ) { NewValue = TimeSliderArgs.Settings->SnapTimeToInterval(NewValue); } CommitScrubPosition( NewValue, /*bIsScrubbing=*/false ); } MouseDragType = DRAG_NONE; return FReply::Handled().ReleaseMouseCapture(); } return FReply::Unhandled(); }
FReply FVisualLoggerTimeSliderController::OnMouseMove( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( WidgetOwner->HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) { if (!bPanning) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { FReply::Handled().CaptureMouse(WidgetOwner).UseHighPrecisionMouseMovement(WidgetOwner); SoftwareCursorPosition = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); bPanning = true; } } else { SoftwareCursorPosition = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); FScrubRangeToScreen ScaleInfo( LocalViewRange, MyGeometry.Size ); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; float NewViewOutputMin = LocalViewRangeMin - InputDelta.X; float NewViewOutputMax = LocalViewRangeMax - InputDelta.X; float LocalClampMin = TimeSliderArgs.ClampRange.Get().GetLowerBoundValue(); float LocalClampMax = TimeSliderArgs.ClampRange.Get().GetUpperBoundValue(); // Clamp the range if ( NewViewOutputMin < LocalClampMin ) { NewViewOutputMin = LocalClampMin; } if ( NewViewOutputMax > LocalClampMax ) { NewViewOutputMax = LocalClampMax; } TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound(TRange<float>(NewViewOutputMin, NewViewOutputMax), EViewRangeInterpolation::Immediate, false); if (Scrollbar.IsValid()) { float InOffsetFraction = (NewViewOutputMin - LocalClampMin) / (LocalClampMax - LocalClampMin); float InThumbSizeFraction = (NewViewOutputMax - NewViewOutputMin) / (LocalClampMax - LocalClampMin); Scrollbar->SetState(InOffsetFraction, InThumbSizeFraction); } if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves TimeSliderArgs.ViewRange.Set( TRange<float>( NewViewOutputMin, NewViewOutputMax ) ); } } } else if (MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton )) { if ( !bDraggingScrubber ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > 0/*FSlateApplication::Get().GetDragTriggerDistance()*/ ) { bDraggingScrubber = true; TimeSliderArgs.OnBeginScrubberMovement.ExecuteIfBound(); } } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetLastScreenSpacePosition() ); float NewValue = RangeToScreen.LocalXToInput( CursorPos.X ); float LocalClampMin = TimeSliderArgs.ClampRange.Get().GetLowerBoundValue(); float LocalClampMax = TimeSliderArgs.ClampRange.Get().GetUpperBoundValue(); if (NewValue < LocalClampMin) { NewValue = LocalClampMin; } if (NewValue > LocalClampMax) { NewValue = LocalClampMax; } CommitScrubPosition(NewValue, /*bIsScrubbing=*/true); } } return FReply::Handled(); } return FReply::Unhandled(); }
FReply FSequencerTimeSliderController::OnMouseMove( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( WidgetOwner->HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton )) { if (!bPanning) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistnace() ) { bPanning = true; } } else { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); FScrubRangeToScreen ScaleInfo( LocalViewRange, MyGeometry.Size ); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; float NewViewOutputMin = LocalViewRangeMin - InputDelta.X; float NewViewOutputMax = LocalViewRangeMax - InputDelta.X; TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); // Clamp the range if clamp values are set if ( LocalClampMin.IsSet() && NewViewOutputMin < LocalClampMin.GetValue() ) { NewViewOutputMin = LocalClampMin.GetValue(); } if ( LocalClampMax.IsSet() && NewViewOutputMax > LocalClampMax.GetValue() ) { NewViewOutputMax = LocalClampMax.GetValue(); } TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound(TRange<float>(NewViewOutputMin, NewViewOutputMax)); if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves TimeSliderArgs.ViewRange.Set( TRange<float>( NewViewOutputMin, NewViewOutputMax ) ); } } } else if (MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton )) { if ( !bDraggingScrubber ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistnace() ) { bDraggingScrubber = true; TimeSliderArgs.OnBeginScrubberMovement.ExecuteIfBound(); } } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetLastScreenSpacePosition() ); float NewValue = RangeToScreen.LocalXToInput( CursorPos.X ); const USequencerSnapSettings* SnapSettings = GetDefault<USequencerSnapSettings>(); if ( SnapSettings->GetIsSnapEnabled() && SnapSettings->GetSnapPlayTimeToInterval() ) { NewValue = SnapSettings->SnapToInterval(NewValue); } CommitScrubPosition( NewValue, /*bIsScrubbing=*/true ); } } return FReply::Handled(); } return FReply::Unhandled(); }
FReply FSequencerTimeSliderController::OnMouseMove( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( WidgetOwner->HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton )) { if (!bPanning) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { bPanning = true; } } else { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); FScrubRangeToScreen ScaleInfo( LocalViewRange, MyGeometry.Size ); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; float NewViewOutputMin = LocalViewRangeMin - InputDelta.X; float NewViewOutputMax = LocalViewRangeMax - InputDelta.X; SetViewRange(NewViewOutputMin, NewViewOutputMax, EViewRangeInterpolation::Immediate); } } else if (MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton )) { if ( !bDraggingScrubber ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { bDraggingScrubber = true; TimeSliderArgs.OnBeginScrubberMovement.ExecuteIfBound(); } } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetLastScreenSpacePosition() ); float NewValue = RangeToScreen.LocalXToInput( CursorPos.X ); const USequencerSettings* Settings = GetDefault<USequencerSettings>(); if ( Settings->GetIsSnapEnabled() && Settings->GetSnapPlayTimeToInterval() ) { NewValue = Settings->SnapTimeToInterval(NewValue); } CommitScrubPosition( NewValue, /*bIsScrubbing=*/true ); } } return FReply::Handled(); } return FReply::Unhandled(); }