FReply SAnimTrackPanel::OnMouseMove( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent ) { const bool bRightMouseButtonDown = InMouseEvent.IsMouseButtonDown(EKeys::RightMouseButton); // When mouse moves, if we are moving a key, update its 'input' position if(bRightMouseButtonDown) { if( !bPanning ) { PanningDistance += FMath::Abs(InMouseEvent.GetCursorDelta().X); if ( PanningDistance > FSlateApplication::Get().GetDragTriggerDistance() ) { bPanning = true; UE_LOG(LogAnimation, Log, TEXT("MouseMove (Capturing Mouse) %d, %0.5f"), bPanning, PanningDistance); return FReply::Handled().CaptureMouse(SharedThis(this)); } } else { FTrackScaleInfo ScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, InMyGeometry.Size); FVector2D ScreenDelta = InMouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; InputDelta.Y = -ScreenDelta.Y/ScaleInfo.PixelsPerOutput; float NewViewInputMin = ViewInputMin.Get() - InputDelta.X; float NewViewInputMax = ViewInputMax.Get() - InputDelta.X; // we'd like to keep the range if outside when panning if ( NewViewInputMin < InputMin.Get() ) { NewViewInputMin = InputMin.Get(); NewViewInputMax = ScaleInfo.ViewInputRange; } else if ( NewViewInputMax > InputMax.Get() ) { NewViewInputMax = InputMax.Get(); NewViewInputMin = NewViewInputMax - ScaleInfo.ViewInputRange; } OnSetInputViewRange.Execute(NewViewInputMin, NewViewInputMax); UE_LOG(LogAnimation, Log, TEXT("MouseMove (Panning) %0.2f, %0.2f"), ViewInputMin.Get(), ViewInputMax.Get()); return FReply::Handled(); } } return FReply::Unhandled(); }
FReply SColorGradientEditor::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if( HasMouseCapture() && IsEditingEnabled.Get() == true ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if( MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton ) && SelectedStop.IsValid( *CurveOwner ) ) { const float DragThresholdDist = 5.0f; if( !bDraggingStop ) { if( DistanceDragged >= DragThresholdDist ) { // Start a transaction, we just started dragging a stop bDraggingStop = true; GEditor->BeginTransaction( LOCTEXT("MoveGradientStop", "Move Gradient Stop") ); CurveOwner->ModifyOwner(); } return FReply::Handled(); } else { // Already dragging a stop, move it FTrackScaleInfo ScaleInfo(ViewMinInput.Get(), ViewMaxInput.Get(), 0.0f, 1.0f, MyGeometry.Size); float MouseTime = ScaleInfo.LocalXToInput( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ).X ); MoveStop( SelectedStop, MouseTime ); return FReply::Handled(); } } } return FReply::Unhandled(); }
FReply STableViewBase::OnTouchMoved( const FGeometry& MyGeometry, const FPointerEvent& InTouchEvent ) { if (bStartedTouchInteraction) { const float ScrollByAmount = InTouchEvent.GetCursorDelta().Y / MyGeometry.Scale; AmountScrolledWhileRightMouseDown += FMath::Abs( ScrollByAmount ); TickScrollDelta -= ScrollByAmount; if (AmountScrolledWhileRightMouseDown > FSlateApplication::Get().GetDragTriggerDistance()) { // Make sure the active timer is registered to update the inertial scroll if ( !bIsScrollingActiveTimerRegistered ) { bIsScrollingActiveTimerRegistered = true; RegisterActiveTimer(0.f, FWidgetActiveTimerDelegate::CreateSP(this, &STableViewBase::UpdateInertialScroll)); } const float AmountScrolled = this->ScrollBy( MyGeometry, -ScrollByAmount, EAllowOverscroll::Yes ); // The user has moved the list some amount; they are probably // trying to scroll. From now on, the list assumes the user is scrolling // until they lift their finger. return FReply::Handled().CaptureMouse( AsShared() ); } return FReply::Handled(); } else { return FReply::Handled(); } }
FReply SButton::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { const float SlateDragStartDistance = FSlateApplication::Get().GetDragTriggerDistance(); if ( IsPreciseTapOrClick(MouseEvent) && MouseEvent.GetCursorDelta().SizeSquared() > ( SlateDragStartDistance*SlateDragStartDistance ) ) { Release(); } return FReply::Unhandled(); }
FReply FSceneViewport::OnMouseMove( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) { // Start a new reply state CurrentReplyState = FReply::Handled(); if( !InMouseEvent.GetCursorDelta().IsZero() ) { UpdateCachedMousePos( InGeometry, InMouseEvent ); UpdateCachedGeometry(InGeometry); const bool bViewportHasCapture = ViewportWidget.IsValid() && ViewportWidget.Pin()->HasMouseCapture(); if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue ) { // Switch to the viewport clients world before processing input FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient ); if( bViewportHasCapture ) { ViewportClient->CapturedMouseMove( this, GetMouseX(), GetMouseY() ); } else { ViewportClient->MouseMove( this, GetMouseX(), GetMouseY() ); } if( bViewportHasCapture ) { // Accumulate delta changes to mouse movment. Depending on the sample frequency of a mouse we may get many per frame. //@todo Slate: In directinput, number of samples in x/y could be different... const FVector2D CursorDelta = InMouseEvent.GetCursorDelta(); MouseDelta.X += CursorDelta.X; ++NumMouseSamplesX; MouseDelta.Y -= CursorDelta.Y; ++NumMouseSamplesY; } } } return CurrentReplyState; }
FReply FTextEditHelper::OnMouseMove( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent, const TSharedRef< ITextEditorWidget >& TextEditor ) { FReply Reply = FReply::Unhandled(); if( TextEditor->IsDragSelecting() && TextEditor->GetWidget()->HasMouseCapture() && InMouseEvent.GetCursorDelta() != FVector2D::ZeroVector ) { TextEditor->MoveCursor( FMoveCursor::ViaScreenPointer( InMyGeometry.AbsoluteToLocal( InMouseEvent.GetScreenSpacePosition( ) ), InMyGeometry.Scale, ECursorAction::SelectText ) ); TextEditor->SetHasDragSelectedSinceFocused( true ); Reply = FReply::Handled(); } return Reply; }
FReply FScrollyZoomy::OnMouseMove( const TSharedRef<SWidget> MyWidget, IScrollableZoomable& ScrollableZoomable, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) { // If scrolling with the right mouse button, we need to remember how much we scrolled. // If we did not scroll at all, we will bring up the context menu when the mouse is released. AmountScrolledWhileRightMouseDown += FMath::Abs( MouseEvent.GetCursorDelta().X ) + FMath::Abs( MouseEvent.GetCursorDelta().Y ); // Has the mouse moved far enough with the right mouse button held down to start capturing // the mouse and dragging the view? if (IsRightClickScrolling()) { this->HorizontalIntertia.AddScrollSample( MouseEvent.GetCursorDelta().X, FPlatformTime::Seconds() ); this->VerticalIntertia.AddScrollSample( MouseEvent.GetCursorDelta().Y, FPlatformTime::Seconds() ); const bool DidScroll = ScrollableZoomable.ScrollBy( MouseEvent.GetCursorDelta() ); FReply Reply = FReply::Handled(); // Capture the mouse if we need to if (MyWidget->HasMouseCapture() == false) { Reply.CaptureMouse( MyWidget ).UseHighPrecisionMouseMovement( MyWidget ); SoftwareCursorPosition = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); bShowSoftwareCursor = true; } // Check if the mouse has moved. if (DidScroll) { SoftwareCursorPosition += MouseEvent.GetCursorDelta(); } return Reply; } } return FReply::Unhandled(); }
FReply SProfilerThreadView::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { // SCOPE_LOG_TIME_FUNC(); FReply Reply = FReply::Unhandled(); if( IsReady() ) { const FVector2D LocalMousePosition = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); HoveredPositionX = 0.0;//PositionToFrameIndex( LocalMousePosition.X ); HoveredPositionY = 0.0; const float CursorPosXDelta = -MouseEvent.GetCursorDelta().X; const float ScrollSpeed = 1.0f / ZoomFactorX; if( MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton ) ) { if( HasMouseCapture() && !MouseEvent.GetCursorDelta().IsZero() ) { DistanceDragged += CursorPosXDelta*ScrollSpeed*0.1; // Inform other widgets that we have scrolled the thread-view. SetPositionX( FMath::Clamp( DistanceDragged, 0.0, TotalRangeXMS - RangeXMS ) ); CursorType = EThreadViewCursor::Hand; Reply = FReply::Handled(); } } else { CursorType = EThreadViewCursor::Default; } } return Reply; }
FReply STableViewBase::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if( MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton ) ) { const float ScrollByAmount = MouseEvent.GetCursorDelta().Y / MyGeometry.Scale; // If scrolling with the right mouse button, we need to remember how much we scrolled. // If we did not scroll at all, we will bring up the context menu when the mouse is released. AmountScrolledWhileRightMouseDown += FMath::Abs( ScrollByAmount ); // Has the mouse moved far enough with the right mouse button held down to start capturing // the mouse and dragging the view? if( IsRightClickScrolling() ) { // Make sure the active timer is registered to update the inertial scroll if (!bIsScrollingActiveTimerRegistered) { bIsScrollingActiveTimerRegistered = true; RegisterActiveTimer(0.f, FWidgetActiveTimerDelegate::CreateSP(this, &STableViewBase::UpdateInertialScroll)); } TickScrollDelta -= ScrollByAmount; const float AmountScrolled = this->ScrollBy( MyGeometry, -ScrollByAmount, AllowOverscroll ); FReply Reply = FReply::Handled(); // The mouse moved enough that we're now dragging the view. Capture the mouse // so the user does not have to stay within the bounds of the list while dragging. if(this->HasMouseCapture() == false) { Reply.CaptureMouse( AsShared() ).UseHighPrecisionMouseMovement( AsShared() ); SoftwareCursorPosition = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); bShowSoftwareCursor = true; } // Check if the mouse has moved. if( AmountScrolled != 0 ) { SoftwareCursorPosition.Y += ScrollByAmount; } return Reply; } } return FReply::Unhandled(); }
FReply SPaperEditorViewport::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { const bool bIsRightMouseButtonDown = MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton); const bool bIsLeftMouseButtonDown = MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton); if (HasMouseCapture()) { // Track how much the mouse moved since the mouse down. const FVector2D CursorDelta = MouseEvent.GetCursorDelta(); TotalMouseDelta += CursorDelta.Size(); if (bIsRightMouseButtonDown) { FReply ReplyState = FReply::Handled(); if (!CursorDelta.IsZero()) { bShowSoftwareCursor = true; } bIsPanning = true; ViewOffset -= CursorDelta / GetZoomAmount(); return ReplyState; } else if (bIsLeftMouseButtonDown) { // TSharedPtr<SNode> NodeBeingDragged = NodeUnderMousePtr.Pin(); // Update the amount to pan panel UpdateViewOffset(MyGeometry, MouseEvent.GetScreenSpacePosition()); const bool bCursorInDeadZone = TotalMouseDelta <= FSlateApplication::Get().GetDragTriggerDistance(); { // We are marquee selecting const FVector2D GraphMousePos = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) ); Marquee.Rect.UpdateEndPoint(GraphMousePos); return FReply::Handled(); } } } return FReply::Unhandled(); }
FReply SSequencerTrackArea::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { auto SequencerPin = SequencerWidget.Pin(); if (SequencerPin.IsValid()) { FReply Reply = SequencerPin->GetEditTool().OnMouseMove(*this, MyGeometry, MouseEvent); if (Reply.IsEventHandled()) { return Reply; } } if (MouseEvent.IsMouseButtonDown(EKeys::RightMouseButton) && HasMouseCapture()) { TreeView.Pin()->ScrollByDelta( -MouseEvent.GetCursorDelta().Y ); } return TimeSliderController->OnMouseMove( SharedThis(this), MyGeometry, MouseEvent ); }
/** * The system calls this method to notify the widget that a mouse moved within it. This event is bubbled. * * @param MyGeometry The Geometry of the widget receiving the event * @param MouseEvent Information about the input event * * @return Whether the event was handled along with possible requests for the system to take action. */ FReply SSplitter::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { const FVector2D LocalMousePosition = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); TArray<FLayoutGeometry> LayoutChildren = ArrangeChildrenForLayout(MyGeometry); if ( bIsResizing ) { if ( !MouseEvent.GetCursorDelta().IsZero() ) { if (Orientation == Orient_Horizontal) { HandleResizing<Orient_Horizontal>( PhysicalSplitterHandleSize, ResizeMode, HoveredHandleIndex, LocalMousePosition, Children, LayoutChildren ); } else { HandleResizing<Orient_Vertical>( PhysicalSplitterHandleSize, ResizeMode, HoveredHandleIndex, LocalMousePosition, Children, LayoutChildren ); } } return FReply::Handled(); } else { // Hit test which handle we are hovering over. HoveredHandleIndex = (Orientation == Orient_Horizontal) ? GetHandleBeingResizedFromMousePosition<Orient_Horizontal>( PhysicalSplitterHandleSize, HitDetectionSplitterHandleSize, LocalMousePosition, LayoutChildren ) : GetHandleBeingResizedFromMousePosition<Orient_Vertical>( PhysicalSplitterHandleSize, HitDetectionSplitterHandleSize, LocalMousePosition, LayoutChildren ); if (HoveredHandleIndex != INDEX_NONE) { if ( FindResizeableSlotBeforeHandle(HoveredHandleIndex, Children) <= INDEX_NONE || FindResizeableSlotAfterHandle(HoveredHandleIndex, Children) >= Children.Num() ) { HoveredHandleIndex = INDEX_NONE; } } return FReply::Unhandled(); } }
FReply STableViewBase::OnTouchMoved( const FGeometry& MyGeometry, const FPointerEvent& InTouchEvent ) { if (bStartedTouchInteraction) { const float ScrollByAmount = InTouchEvent.GetCursorDelta().Y / MyGeometry.Scale; AmountScrolledWhileRightMouseDown += FMath::Abs( ScrollByAmount ); TickScrollDelta -= ScrollByAmount; if (AmountScrolledWhileRightMouseDown > FSlateApplication::Get().GetDragTriggerDistance()) { const float AmountScrolled = this->ScrollBy( MyGeometry, -ScrollByAmount, EAllowOverscroll::Yes ); // The user has moved the list some amount; they are probably // trying to scroll. From now on, the list assumes the user is scrolling // until they lift their finger. return FReply::Handled().CaptureMouse( AsShared() ); } return FReply::Handled(); } else { return FReply::Handled(); } }
FReply SSection::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if( HasMouseCapture() ) { // Have mouse capture and there are drag operations that need to be performed if( MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton ) ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); FVector2D LocalMousePos = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); if( !bDragging ) { // If we are not dragging determine if the mouse has moved far enough to start a drag if( DistanceDragged >= SequencerSectionConstants::SectionDragStartDistance ) { bDragging = true; if( PressedKey.IsValid() ) { // Clear selected sections when beginning to drag keys GetSequencer().GetSelection().EmptySelectedSections(); bool bSelectDueToDrag = true; HandleKeySelection( PressedKey, MouseEvent, bSelectDueToDrag ); bool bKeysUnderMouse = true; CreateDragOperation( MyGeometry, MouseEvent, bKeysUnderMouse ); } else { // Clear selected keys when beginning to drag a section GetSequencer().GetSelection().EmptySelectedKeys(); HandleSectionSelection( MouseEvent ); bool bKeysUnderMouse = false; CreateDragOperation( MyGeometry, MouseEvent, bKeysUnderMouse ); } if( DragOperation.IsValid() ) { DragOperation->OnBeginDrag(LocalMousePos, ParentSectionArea); } } } else if( DragOperation.IsValid() ) { // Already in a drag, tell all operations to perform their drag implementations FTimeToPixel TimeToPixelConverter = SectionInterface->GetSectionObject()->IsInfinite() ? FTimeToPixel( ParentGeometry, GetSequencer().GetViewRange()) : FTimeToPixel( MyGeometry, TRange<float>( SectionInterface->GetSectionObject()->GetStartTime(), SectionInterface->GetSectionObject()->GetEndTime() ) ); DragOperation->OnDrag( MouseEvent, LocalMousePos, TimeToPixelConverter, ParentSectionArea ); } } return FReply::Handled(); } else { // Not dragging ResetHoveredState(); // Checked for hovered key // @todo Sequencer - Needs visual cue HoveredKey = GetKeyUnderMouse( MouseEvent.GetScreenSpacePosition(), MyGeometry ); // Only check for edge interaction if not hovering over a key if( !HoveredKey.IsValid() ) { CheckForEdgeInteraction( MouseEvent, MyGeometry ); } } 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().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(); }
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(); }
FVector2D UKismetInputLibrary::PointerEvent_GetCursorDelta(const FPointerEvent& Input) { return Input.GetCursorDelta(); }
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(); }
/** SWidget interface */ virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override { const bool bIsRightMouseButtonDown = MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton ); const bool bIsLeftMouseButtonDown = MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton ); PastePosition = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) ); if ( this->HasMouseCapture() ) { const FVector2D CursorDelta = MouseEvent.GetCursorDelta(); // Track how much the mouse moved since the mouse down. TotalMouseDelta += CursorDelta.Size(); if (bIsRightMouseButtonDown) { FReply ReplyState = FReply::Handled(); if( !CursorDelta.IsZero() ) { bShowSoftwareCursor = true; } // Panning and mouse is outside of panel? Pasting should just go to the screen center. PastePosition = PanelCoordToGraphCoord( 0.5 * MyGeometry.Size ); this->bIsPanning = true; ViewOffset -= CursorDelta / GetZoomAmount(); return ReplyState; } else if (bIsLeftMouseButtonDown) { TSharedPtr<SNode> NodeBeingDragged = NodeUnderMousePtr.Pin(); if ( IsEditable.Get() ) { // Update the amount to pan panel UpdateViewOffset(MyGeometry, MouseEvent.GetScreenSpacePosition()); const bool bCursorInDeadZone = TotalMouseDelta <= FSlateApplication::Get().GetDragTriggerDistance(); if ( NodeBeingDragged.IsValid() ) { if ( !bCursorInDeadZone ) { // Note, NodeGrabOffset() comes from the node itself, so it's already scaled correctly. FVector2D AnchorNodeNewPos = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) ) - NodeGrabOffset; // Dragging an unselected node automatically selects it. SelectionManager.StartDraggingNode(NodeBeingDragged->GetObjectBeingDisplayed(), MouseEvent); // Move all the selected nodes. { const FVector2D AnchorNodeOldPos = NodeBeingDragged->GetPosition(); const FVector2D DeltaPos = AnchorNodeNewPos - AnchorNodeOldPos; if (DeltaPos.Size() > KINDA_SMALL_NUMBER) { MoveSelectedNodes(NodeBeingDragged, AnchorNodeNewPos); } } } return FReply::Handled(); } } if ( !NodeBeingDragged.IsValid() ) { // We are marquee selecting const FVector2D GraphMousePos = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) ); Marquee.Rect.UpdateEndPoint(GraphMousePos); FindNodesAffectedByMarquee( /*out*/ Marquee.AffectedNodes ); return FReply::Handled(); } } } return FReply::Unhandled(); }
FReply SScrubWidget::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { // Bar Dragging if(DraggingBar) { // Update bar if we are dragging FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ); FTrackScaleInfo ScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, MyGeometry.Size); float NewDataPos = FMath::Clamp( ScaleInfo.LocalXToInput(CursorPos.X), ViewInputMin.Get(), ViewInputMax.Get() ); OnBarDrag.ExecuteIfBound(DraggableBarIndex, NewDataPos); } else { // Update what bar we are hovering over FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); FTrackScaleInfo ScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, MyGeometry.Size); DraggableBarIndex = INDEX_NONE; if ( DraggableBars.IsBound() ) { const TArray<float>& DraggableBarsVal = DraggableBars.Get(); for ( int32 I=0; I < DraggableBarsVal.Num(); I++ ) { if( FMath::Abs( ScaleInfo.InputToLocalX(DraggableBarsVal[I]) - CursorPos.X ) < 10 ) { DraggableBarIndex = I; break; } } } } if ( this->HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton ) && bPanning) { FTrackScaleInfo ScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, MyGeometry.Size); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); float InputDeltaX = ScreenDelta.X/ScaleInfo.PixelsPerInput; bMouseMovedDuringPanning |= !ScreenDelta.IsNearlyZero(0.001f); float NewViewInputMin = ViewInputMin.Get() - InputDeltaX; float NewViewInputMax = ViewInputMax.Get() - InputDeltaX; // we'd like to keep the range if outside when panning if ( NewViewInputMin < 0.f ) { NewViewInputMin = 0.f; NewViewInputMax = ScaleInfo.ViewInputRange; } else if ( NewViewInputMax > SequenceLength.Get() ) { NewViewInputMax = SequenceLength.Get(); NewViewInputMin = NewViewInputMax - ScaleInfo.ViewInputRange; } OnSetInputViewRange.ExecuteIfBound(NewViewInputMin, NewViewInputMax); } else if (!bDragging) { DistanceDragged += FMath::Abs(MouseEvent.GetCursorDelta().X); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistance() ) { bDragging = true; } if( bDragging ) { OnBeginSliderMovement.ExecuteIfBound(); } } else if (bDragging) { FTrackScaleInfo TimeScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, MyGeometry.Size); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = TimeScaleInfo.LocalXToInput(CursorPos.X); CommitValue( NewValue, true, false ); } return FReply::Handled(); } return FReply::Unhandled(); }
FReply FCanvasSlotExtension::HandleAnchorDragging(const FGeometry& Geometry, const FPointerEvent& Event, EAnchorWidget::Type AnchorType) { if ( bMovingAnchor && !Event.GetCursorDelta().IsZero() ) { float InverseSize = 1.0f / Designer->GetPreviewScale(); for ( FWidgetReference& Selection : SelectionCache ) { UWidget* PreviewWidget = Selection.GetPreview(); if ( UCanvasPanel* Canvas = Cast<UCanvasPanel>(PreviewWidget->GetParent()) ) { UCanvasPanelSlot* PreviewCanvasSlot = Cast<UCanvasPanelSlot>(PreviewWidget->Slot); FGeometry Geometry; if ( Canvas->GetGeometryForSlot(PreviewCanvasSlot, Geometry) ) { FGeometry CanvasGeometry = Canvas->GetCanvasWidget()->GetCachedGeometry(); FVector2D StartLocalPosition = CanvasGeometry.AbsoluteToLocal(MouseDownPosition); FVector2D NewLocalPosition = CanvasGeometry.AbsoluteToLocal(Event.GetScreenSpacePosition()); FVector2D LocalPositionDelta = NewLocalPosition - StartLocalPosition; FVector2D AnchorDelta = LocalPositionDelta / CanvasGeometry.Size; const FAnchorData OldLayoutData = PreviewCanvasSlot->LayoutData; FAnchorData LayoutData = OldLayoutData; switch ( AnchorType ) { case EAnchorWidget::Center: LayoutData.Anchors.Maximum = BeginAnchors.Maximum + AnchorDelta; LayoutData.Anchors.Minimum = BeginAnchors.Minimum + AnchorDelta; LayoutData.Anchors.Minimum.X = FMath::Clamp(LayoutData.Anchors.Minimum.X, 0.0f, 1.0f); LayoutData.Anchors.Maximum.X = FMath::Clamp(LayoutData.Anchors.Maximum.X, 0.0f, 1.0f); LayoutData.Anchors.Minimum.Y = FMath::Clamp(LayoutData.Anchors.Minimum.Y, 0.0f, 1.0f); LayoutData.Anchors.Maximum.Y = FMath::Clamp(LayoutData.Anchors.Maximum.Y, 0.0f, 1.0f); break; } switch ( AnchorType ) { case EAnchorWidget::Left: case EAnchorWidget::TopLeft: case EAnchorWidget::BottomLeft: LayoutData.Anchors.Minimum.X = BeginAnchors.Minimum.X + AnchorDelta.X; LayoutData.Anchors.Minimum.X = FMath::Clamp(LayoutData.Anchors.Minimum.X, 0.0f, LayoutData.Anchors.Maximum.X); break; } switch ( AnchorType ) { case EAnchorWidget::Right: case EAnchorWidget::TopRight: case EAnchorWidget::BottomRight: LayoutData.Anchors.Maximum.X = BeginAnchors.Maximum.X + AnchorDelta.X; LayoutData.Anchors.Maximum.X = FMath::Clamp(LayoutData.Anchors.Maximum.X, LayoutData.Anchors.Minimum.X, 1.0f); break; } switch ( AnchorType ) { case EAnchorWidget::Top: case EAnchorWidget::TopLeft: case EAnchorWidget::TopRight: LayoutData.Anchors.Minimum.Y = BeginAnchors.Minimum.Y + AnchorDelta.Y; LayoutData.Anchors.Minimum.Y = FMath::Clamp(LayoutData.Anchors.Minimum.Y, 0.0f, LayoutData.Anchors.Maximum.Y); break; } switch ( AnchorType ) { case EAnchorWidget::Bottom: case EAnchorWidget::BottomLeft: case EAnchorWidget::BottomRight: LayoutData.Anchors.Maximum.Y = BeginAnchors.Maximum.Y + AnchorDelta.Y; LayoutData.Anchors.Maximum.Y = FMath::Clamp(LayoutData.Anchors.Maximum.Y, LayoutData.Anchors.Minimum.Y, 1.0f); break; } // Major percentage snapping { const float MajorAnchorLine = 0.1f; const float MajorAnchorLineSnapDistance = 0.1f; if ( LayoutData.Anchors.Minimum.X != OldLayoutData.Anchors.Minimum.X ) { ProximitySnapValue(MajorAnchorLine, MajorAnchorLineSnapDistance, LayoutData.Anchors.Minimum.X); } if ( LayoutData.Anchors.Minimum.Y != OldLayoutData.Anchors.Minimum.Y ) { ProximitySnapValue(MajorAnchorLine, MajorAnchorLineSnapDistance, LayoutData.Anchors.Minimum.Y); } if ( LayoutData.Anchors.Maximum.X != OldLayoutData.Anchors.Maximum.X ) { ProximitySnapValue(MajorAnchorLine, MajorAnchorLineSnapDistance, LayoutData.Anchors.Maximum.X); } if ( LayoutData.Anchors.Maximum.Y != OldLayoutData.Anchors.Maximum.Y ) { ProximitySnapValue(MajorAnchorLine, MajorAnchorLineSnapDistance, LayoutData.Anchors.Maximum.Y); } } // Rebase the layout and restore the old value after calculating the new final layout // result. { PreviewCanvasSlot->SaveBaseLayout(); PreviewCanvasSlot->LayoutData = LayoutData; PreviewCanvasSlot->RebaseLayout(); LayoutData = PreviewCanvasSlot->LayoutData; PreviewCanvasSlot->LayoutData = OldLayoutData; } // If control is pressed reset all positional offset information if ( FSlateApplication::Get().GetModifierKeys().IsControlDown() ) { FMargin NewOffsets = FMargin(0, 0, LayoutData.Anchors.IsStretchedHorizontal() ? 0 : LayoutData.Offsets.Right, LayoutData.Anchors.IsStretchedVertical() ? 0 : LayoutData.Offsets.Bottom); LayoutData.Offsets = NewOffsets; } UWidget* TemplateWidget = Selection.GetTemplate(); UCanvasPanelSlot* TemplateCanvasSlot = CastChecked<UCanvasPanelSlot>(TemplateWidget->Slot); static const FName LayoutDataName(TEXT("LayoutData")); FObjectEditorUtils::SetPropertyValue<UCanvasPanelSlot, FAnchorData>(PreviewCanvasSlot, LayoutDataName, LayoutData); FObjectEditorUtils::SetPropertyValue<UCanvasPanelSlot, FAnchorData>(TemplateCanvasSlot, LayoutDataName, LayoutData); } }; return FReply::Handled(); } } return FReply::Unhandled(); }