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();
}
Example #2
0
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();
}
Example #4
0
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;
		}
	}
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
/**
 * 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();
			}
		}
	}
Example #9
0
	/**  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);
}
Example #11
0
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();
}