FReply SColorGradientEditor::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { const float DragThresholdDist = 5.0f; if( IsEditingEnabled.Get() == true ) { if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { if( bDraggingStop == true ) { // We stopped dragging GEditor->EndTransaction(); } else if( DistanceDragged < DragThresholdDist && !SelectedStop.IsValid( *CurveOwner ) ) { FGeometry ColorMarkAreaGeometry = GetColorMarkAreaGeometry( MyGeometry ); FGeometry AlphaMarkAreaGeometry = GetAlphaMarkAreaGeometry( MyGeometry ); if( ColorMarkAreaGeometry.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { // Add a new color mark bool bColorStop = true; SelectedStop = AddStop( MouseEvent.GetScreenSpacePosition(), MyGeometry, bColorStop ); return FReply::Handled().CaptureMouse( SharedThis(this) ); } else if( AlphaMarkAreaGeometry.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { // Add a new alpha mark bool bColorStop = false; SelectedStop = AddStop( MouseEvent.GetScreenSpacePosition(), MyGeometry, bColorStop ); return FReply::Handled().CaptureMouse( SharedThis(this) ); } } DistanceDragged = 0; bDraggingStop = false; return FReply::Handled().ReleaseMouseCapture(); } else if( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) { // Didnt move the mouse too far, open a context menu if( DistanceDragged < DragThresholdDist && SelectedStop.IsValid( *CurveOwner ) ) { OpenGradientStopContextMenu( MouseEvent.GetScreenSpacePosition() ); } DistanceDragged = 0; return FReply::Handled().ReleaseMouseCapture(); } } return FReply::Unhandled(); }
FSelectedKey SSection::GetKeyUnderMouse( const FVector2D& MousePosition, const FGeometry& AllottedGeometry ) const { UMovieSceneSection& Section = *SectionInterface->GetSectionObject(); // Search every key area until we find the one under the mouse for( int32 KeyAreaIndex = 0; KeyAreaIndex < KeyAreas.Num(); ++KeyAreaIndex ) { const FKeyAreaElement& Element = KeyAreas[KeyAreaIndex]; TSharedRef<IKeyArea> KeyArea = Element.KeyAreaNode.GetKeyArea( SectionIndex ); // Compute the current key area geometry FGeometry KeyAreaGeometryPadded = GetKeyAreaGeometry( Element, AllottedGeometry ); // Is the key area under the mouse if( KeyAreaGeometryPadded.IsUnderLocation( MousePosition ) ) { FGeometry SectionGeometry = AllottedGeometry.MakeChild(FVector2D(SequencerSectionConstants::SectionGripSize, 0), AllottedGeometry.GetDrawSize() - FVector2D(SequencerSectionConstants::SectionGripSize*2, 0.0f)); FGeometry KeyAreaGeometry = GetKeyAreaGeometry( Element, SectionGeometry ); FVector2D LocalSpaceMousePosition = KeyAreaGeometry.AbsoluteToLocal( MousePosition ); FTimeToPixel TimeToPixelConverter = Section.IsInfinite() ? FTimeToPixel( ParentGeometry, GetSequencer().GetViewRange()) : FTimeToPixel( KeyAreaGeometry, TRange<float>( Section.GetStartTime(), Section.GetEndTime() ) ); // Check each key until we find one under the mouse (if any) TArray<FKeyHandle> KeyHandles = KeyArea->GetUnsortedKeyHandles(); for( int32 KeyIndex = 0; KeyIndex < KeyHandles.Num(); ++KeyIndex ) { FKeyHandle KeyHandle = KeyHandles[KeyIndex]; float KeyPosition = TimeToPixelConverter.TimeToPixel( KeyArea->GetKeyTime(KeyHandle) ); FGeometry KeyGeometry = KeyAreaGeometry.MakeChild( FVector2D( KeyPosition - FMath::TruncToFloat(SequencerSectionConstants::KeySize.X/2.0f), ((KeyAreaGeometry.Size.Y*.5f)-(SequencerSectionConstants::KeySize.Y*.5f)) ), SequencerSectionConstants::KeySize ); if( KeyGeometry.IsUnderLocation( MousePosition ) ) { // The current key is under the mouse return FSelectedKey( Section, KeyArea, KeyHandle ); } } // no key was selected in the current key area but the mouse is in the key area so it cannot possibly be in any other key area return FSelectedKey(); } } // No key was selected in any key area return FSelectedKey(); }
FGradientStopMark SColorGradientEditor::GetGradientStopAtPoint( const FVector2D& MousePos, const FGeometry& MyGeometry ) { FGeometry ColorMarkAreaGeometry = GetColorMarkAreaGeometry( MyGeometry ); FGeometry AlphaMarkAreaGeometry = GetAlphaMarkAreaGeometry( MyGeometry ); FTrackScaleInfo ScaleInfo(ViewMinInput.Get(), ViewMaxInput.Get(), 0.0f, 1.0f, MyGeometry.Size); if( ColorMarkAreaGeometry.IsUnderLocation( MousePos ) || AlphaMarkAreaGeometry.IsUnderLocation( MousePos ) ) { TArray<FGradientStopMark> ColorMarks; TArray<FGradientStopMark> AlphaMarks; GetGradientStopMarks( ColorMarks, AlphaMarks ); // See if any color stops are under the mouse for( int32 ColorIndex = 0; ColorIndex < ColorMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = ColorMarks[ColorIndex]; // Convert the time to a screen coordinate float XVal = ScaleInfo.InputToLocalX( Mark.Time ); if( XVal >= 0 ) { FGeometry MarkGeometry = ColorMarkAreaGeometry.MakeChild( FVector2D( XVal-HandleRect.Left, HandleRect.Top ), FVector2D( HandleRect.Right, HandleRect.Bottom ) ); if( MarkGeometry.IsUnderLocation( MousePos ) ) { return Mark; } } } // See if any color stops are under the mouse for( int32 ColorIndex = 0; ColorIndex < AlphaMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = AlphaMarks[ColorIndex]; float XVal = ScaleInfo.InputToLocalX( Mark.Time ); if( XVal >= 0 ) { FGeometry MarkGeometry = AlphaMarkAreaGeometry.MakeChild( FVector2D( XVal-HandleRect.Left, HandleRect.Top ), FVector2D( HandleRect.Right, HandleRect.Bottom ) ); if( MarkGeometry.IsUnderLocation( MousePos ) ) { return Mark; } } } } return FGradientStopMark(); }
void SSection::CheckForEdgeInteraction( const FPointerEvent& MouseEvent, const FGeometry& SectionGeometry ) { bLeftEdgeHovered = false; bRightEdgeHovered = false; bLeftEdgePressed = false; bRightEdgePressed = false; if (!SectionInterface->SectionIsResizable()) { return; } // Make areas to the left and right of the geometry. We will use these areas to determine if someone dragged the left or right edge of a section FGeometry SectionRectLeft = SectionGeometry.MakeChild( FVector2D::ZeroVector, FVector2D( SequencerSectionConstants::SectionGripSize, SectionGeometry.Size.Y ) ); FGeometry SectionRectRight = SectionGeometry.MakeChild( FVector2D( SectionGeometry.Size.X - SequencerSectionConstants::SectionGripSize, 0 ), SectionGeometry.Size ); if( SectionRectLeft.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { bLeftEdgePressed = true; } else { bLeftEdgeHovered = true; } } else if( SectionRectRight.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { bRightEdgePressed = true; } else { bRightEdgeHovered = true; } } }
FReply SButton::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { FReply Reply = FReply::Unhandled(); const bool bMustBePressed = ClickMethod == EButtonClickMethod::DownAndUp; const bool bMeetsPressedRequirements = (!bMustBePressed || (bIsPressed && bMustBePressed)); if (bMeetsPressedRequirements && IsEnabled() && ( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton || MouseEvent.IsTouchEvent() ) ) { Release(); if( ClickMethod == EButtonClickMethod::MouseDown ) { // NOTE: If we're configured to click on mouse-down/precise-tap, then we never capture the mouse thus // may never receive an OnMouseButtonUp() call. We make sure that our bIsPressed // state is reset by overriding OnMouseLeave(). } else { bool bEventOverButton = IsHovered(); if (!bEventOverButton && MouseEvent.IsTouchEvent()) { bEventOverButton = MyGeometry.IsUnderLocation(MouseEvent.GetScreenSpacePosition()); } if (bEventOverButton) { // If we asked for a precise tap, all we need is for the user to have not moved their pointer very far. const bool bTriggerForTouchEvent = IsPreciseTapOrClick(MouseEvent); // If we were asked to allow the button to be clicked on mouse up, regardless of whether the user // pressed the button down first, then we'll allow the click to proceed without an active capture const bool bTriggerForMouseEvent = ( ClickMethod == EButtonClickMethod::MouseUp || HasMouseCapture() ); if( (bTriggerForTouchEvent || bTriggerForMouseEvent) && OnClicked.IsBound() == true ) { Reply = OnClicked.Execute(); } } } //If the user of the button didn't handle this click, then the button's //default behavior handles it. if ( Reply.IsEventHandled() == false ) { Reply = FReply::Handled(); } //If the user hasn't requested a new mouse captor and the button still has mouse capture, //then the default behavior of the button is to release mouse capture. if (Reply.GetMouseCaptor().IsValid() == false && HasMouseCapture()) { Reply.ReleaseMouseCapture(); } } Invalidate(EInvalidateWidget::Layout); return Reply; }
FReply FTextEditHelper::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& InMouseEvent, const TSharedRef< ITextEditorWidget >& TextEditor ) { FReply Reply = FReply::Unhandled(); // The mouse must have been captured by either left or right button down before we'll process mouse ups if( TextEditor->GetWidget()->HasMouseCapture() ) { if( InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && TextEditor->IsDragSelecting() ) { // No longer drag-selecting TextEditor->EndDragSelection(); // If we received keyboard focus on this click, then we'll want to select all of the text // when the user releases the mouse button, unless the user actually dragged the mouse // while holding the button down, in which case they've already selected some text and // we'll leave things alone! if( TextEditor->WasFocusedByLastMouseDown() ) { if( !TextEditor->HasDragSelectedSinceFocused() ) { if( TextEditor->SelectAllTextWhenFocused() ) { // Move the cursor to the end of the string TextEditor->JumpTo(ETextLocation::EndOfDocument, ECursorAction::MoveCursor); // User wasn't dragging the mouse, so go ahead and select all of the text now // that we've become focused TextEditor->SelectAllText(); // @todo Slate: In this state, the caret should actually stay hidden (until the user interacts again), and we should not move the caret } } TextEditor->SetWasFocusedByLastMouseDown( false ); } // Release mouse capture Reply = FReply::Handled(); Reply.ReleaseMouseCapture(); } else if( InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) { if ( MyGeometry.IsUnderLocation( InMouseEvent.GetScreenSpacePosition() ) ) { // Right clicked, so summon a context menu if the cursor is within the widget TextEditor->SummonContextMenu( InMouseEvent.GetScreenSpacePosition() ); } // Release mouse capture Reply = FReply::Handled(); Reply.ReleaseMouseCapture(); } } return Reply; }
/** * See SWidget::OnMouseButtonUp. * * @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 SCheckBox::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { bIsPressed = false; if( ClickMethod == EButtonClickMethod::MouseDown ) { // NOTE: If we're configured to click on mouse-down, then we never capture the mouse thus // may never receive an OnMouseButtonUp() call. We make sure that our bIsPressed // state is reset by overriding OnMouseLeave(). } else { const bool IsUnderMouse = MyGeometry.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ); if ( IsUnderMouse ) { // If we were asked to allow the button to be clicked on mouse up, regardless of whether the user // pressed the button down first, then we'll allow the click to proceed without an active capture if( ClickMethod == EButtonClickMethod::MouseUp || HasMouseCapture() ) { ToggleCheckedState(); const TAttribute<ESlateCheckBoxState::Type>& State = IsCheckboxChecked.Get(); if(State == ESlateCheckBoxState::Checked) { PlayCheckedSound(); } else if(State == ESlateCheckBoxState::Unchecked) { PlayUncheckedSound(); } } } } return FReply::Handled().ReleaseMouseCapture(); } return FReply::Unhandled(); }
void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override { if ( AllottedGeometry.IsUnderLocation(FSlateApplication::Get().GetCursorPos()) ) { if ( !ResizeCurve.IsPlaying() ) { if ( ResizeCurve.IsAtStart() ) { ResizeCurve.Play(); } else if ( ResizeCurve.IsAtEnd() ) { ResizeCurve.PlayReverse(); } } } else { if ( !ResizeCurve.IsAtStart() && ((!ResizeCurve.IsInReverse() && ResizeCurve.IsPlaying()) || !ResizeCurve.IsPlaying()) ) { ResizeCurve.PlayReverse(); } } }
/** SWidget interface */ void Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) override { SNodePanel::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); // scroll to world center on first open if (bIsFirstTickCall) { bIsFirstTickCall = false; ViewOffset-= AllottedGeometry.Size*0.5f/GetZoomAmount(); } FVector2D CursorPosition = FSlateApplication::Get().GetCursorPos(); // Update cached variables WorldMouseLocation = CursorToWorldPosition(AllottedGeometry, CursorPosition); WorldMarqueeSize = Marquee.Rect.GetSize()/AllottedGeometry.Scale; // Update streaming preview data const bool bShowPotentiallyVisibleLevels = FSlateApplication::Get().GetModifierKeys().IsAltDown() && AllottedGeometry.IsUnderLocation(CursorPosition); WorldModel->UpdateStreamingPreview(WorldMouseLocation, bShowPotentiallyVisibleLevels); // deferred scroll and zooming requests if (bHasScrollToRequest || bHasScrollByRequest) { // zoom to if (RequestedAllowZoomIn) { RequestedAllowZoomIn = false; FVector2D SizeWithZoom = RequestedZoomArea*ZoomLevels->GetZoomAmount(ZoomLevel); if (SizeWithZoom.X >= AllottedGeometry.Size.X || SizeWithZoom.Y >= AllottedGeometry.Size.Y) { // maximum zoom out by default ZoomLevel = ZoomLevels->GetDefaultZoomLevel(); // expand zoom area little bit, so zooming will fit original area not so tight RequestedZoomArea*= 1.2f; // find more suitable zoom value for (int32 Zoom = 0; Zoom < ZoomLevels->GetDefaultZoomLevel(); ++Zoom) { SizeWithZoom = RequestedZoomArea*ZoomLevels->GetZoomAmount(Zoom); if (SizeWithZoom.X >= AllottedGeometry.Size.X || SizeWithZoom.Y >= AllottedGeometry.Size.Y) { ZoomLevel = Zoom; break; } } } } // scroll to if (bHasScrollToRequest) { bHasScrollToRequest = false; ViewOffset = RequestedScrollToValue - AllottedGeometry.Size*0.5f/GetZoomAmount(); } // scroll by if (bHasScrollByRequest) { bHasScrollByRequest = false; ViewOffset+= RequestedScrollByValue; } } }
bool USlateBlueprintLibrary::IsUnderLocation(const FGeometry& Geometry, const FVector2D& AbsoluteCoordinate) { return Geometry.IsUnderLocation(AbsoluteCoordinate); }
FReply SSection::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if( bDragging && DragOperation.IsValid() ) { // If dragging tell the operation we are no longer dragging DragOperation->OnEndDrag(ParentSectionArea); } else { if( ( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton || MouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) && HasMouseCapture() && MyGeometry.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { HandleSelection( MyGeometry, MouseEvent ); } if( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && HasMouseCapture() ) { TSharedPtr<SWidget> MenuContent = OnSummonContextMenu( MyGeometry, MouseEvent ); if (MenuContent.IsValid()) { FWidgetPath WidgetPath = MouseEvent.GetEventPath() != nullptr ? *MouseEvent.GetEventPath() : FWidgetPath(); FSlateApplication::Get().PushMenu( AsShared(), WidgetPath, MenuContent.ToSharedRef(), MouseEvent.GetScreenSpacePosition(), FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu ) ); return FReply::Handled().ReleaseMouseCapture().SetUserFocus(MenuContent.ToSharedRef(), EFocusCause::SetDirectly); } } } ResetState(); return FReply::Handled().ReleaseMouseCapture(); }