FReply SScrubWidget::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { bool bHandleLeftMouseButton = MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && this->HasMouseCapture(); bool bHandleRightMouseButton = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && this->HasMouseCapture() && bAllowZoom; if ( bHandleRightMouseButton ) { bPanning = false; FTrackScaleInfo TimeScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, MyGeometry.Size); FVector2D CursorPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetLastScreenSpacePosition()); float NewValue = TimeScaleInfo.LocalXToInput(CursorPos.X); if( !bMouseMovedDuringPanning ) { CreateContextMenu(NewValue, MouseEvent); } return FReply::Handled().ReleaseMouseCapture(); } else if ( bHandleLeftMouseButton ) { if(DraggingBar) { DraggingBar = false; } else if( bDragging ) { OnEndSliderMovement.ExecuteIfBound( ValueAttribute.Get() ); } else { 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 ); } bDragging = false; return FReply::Handled().ReleaseMouseCapture(); } return FReply::Unhandled(); }
/** This function is used by a few random widgets and is mostly arbitrary. It could be moved anywhere. */ int32 SScrubWidget::GetDivider(float InputMinX, float InputMaxX, FVector2D WidgetSize, float SequenceLength, int32 NumFrames) { FTrackScaleInfo TimeScaleInfo(InputMinX, InputMaxX, 0.f, 0.f, WidgetSize); float TimePerKey = (NumFrames > 0) ? SequenceLength / (float)(NumFrames) : 0.0f; float TotalWidgetWidth = TimeScaleInfo.WidgetSize.X; float NumKeys = TimeScaleInfo.ViewInputRange / TimePerKey; float KeyWidgetWidth = TotalWidgetWidth / NumKeys; int32 Divider = 1; if (KeyWidgetWidth > 0) { Divider = FMath::Max<int32>(50 / KeyWidgetWidth, 1); } return Divider; }
/** This function is used by a few random widgets and is mostly arbitrary. It could be moved anywhere. */ int32 SScrubWidget::GetDivider(float InputMinX, float InputMaxX, FVector2D WidgetSize, float SequenceLength, int32 NumFrames) { FTrackScaleInfo TimeScaleInfo(InputMinX, InputMaxX, 0.f, 0.f, WidgetSize); const FAnimKeyHelper Helper(SequenceLength, NumFrames); float TimePerKey = Helper.TimePerKey(); float TotalWidgetWidth = TimeScaleInfo.WidgetSize.X; int32 NumKeys = TimeScaleInfo.ViewInputRange / TimePerKey; float KeyWidgetWidth = TotalWidgetWidth / (float)Helper.GetNumKeys(); int32 Divider = 1; if (KeyWidgetWidth > 0) { Divider = FMath::Max<int32>(50 / KeyWidgetWidth, 1); } return Divider; }
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(); }