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();
}
Exemple #2
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();
}
Exemple #3
0
TSharedPtr<SWidget> STrack::SummonContextMenu(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	bool SummonedContextMenu = false;

	const bool bCloseWindowAfterMenuSelection = true;
	FMenuBuilder MenuBuilder( bCloseWindowAfterMenuSelection, EditorActions );

	FVector2D CursorPos = MouseEvent.GetScreenSpacePosition();
	float DataPos = LocalToDataX( MyGeometry.AbsoluteToLocal(CursorPos).X, MyGeometry );

	// Context menu for a node
	int NotifyIndex = GetHitNode(MyGeometry, MyGeometry.AbsoluteToLocal(CursorPos));
	if(NotifyIndex != INDEX_NONE)
	{
		if(TrackNodes[NotifyIndex]->OnNodeRightClickContextMenu.IsBound())
		{
			TrackNodes[NotifyIndex]->OnNodeRightClickContextMenu.Execute(MenuBuilder);
			SummonedContextMenu = true;
		}
	}

	// Context menu for track itself
	if(OnTrackRightClickContextMenu.IsBound())
	{
		SummonedContextMenu = true;
		OnTrackRightClickContextMenu.Execute(MenuBuilder, DataPos, DraggableBarIndex);
	}

	// Build the menu if we actually added anything to it
	TSharedPtr<SWindow> ContextMenuWindow = NULL;
	if(SummonedContextMenu)
	{
		ContextMenuWindow =
			FSlateApplication::Get().PushMenu( SharedThis( this ), MenuBuilder.MakeWidget(), CursorPos, FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu ));
	}

	return ContextMenuWindow;
}
FReply FSceneViewport::OnTouchMoved( const FGeometry& MyGeometry, const FPointerEvent& TouchEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	UpdateCachedMousePos(MyGeometry, TouchEvent);
	UpdateCachedGeometry(MyGeometry);

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		const FVector2D TouchPosition = MyGeometry.AbsoluteToLocal(TouchEvent.GetScreenSpacePosition());

		if( !ViewportClient->InputTouch( this, TouchEvent.GetUserIndex(), TouchEvent.GetPointerIndex(), ETouchType::Moved, TouchPosition, FDateTime::Now(), TouchEvent.GetTouchpadIndex()) )
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}

	return CurrentReplyState;
}
Exemple #5
0
TSharedPtr<SWidget> SSection::OnSummonContextMenu( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	FSelectedKey Key = GetKeyUnderMouse( MouseEvent.GetScreenSpacePosition(), MyGeometry );

	FSequencer& Sequencer = GetSequencer();

	UMovieSceneSection* SceneSection = SectionInterface->GetSectionObject();

	// @todo sequencer replace with UI Commands instead of faking it
	const bool bShouldCloseWindowAfterMenuSelection = true;
	FMenuBuilder MenuBuilder(bShouldCloseWindowAfterMenuSelection, NULL);

	if (Key.IsValid())
	{
		MenuBuilder.AddMenuEntry(
			NSLOCTEXT("Sequencer", "DeleteKey", "Delete"),
			NSLOCTEXT("Sequencer", "DeleteKeyToolTip", "Deletes the selected keys."),
			FSlateIcon(),
			FUIAction(FExecuteAction::CreateSP(&Sequencer, &FSequencer::DeleteSelectedKeys))
			);
	}
	else
	{
		SectionInterface->BuildSectionContextMenu(MenuBuilder);

		// @todo Sequencer this should delete all selected sections
		// delete/selection needs to be rethought in general
		MenuBuilder.AddMenuEntry(
			NSLOCTEXT("Sequencer", "DeleteSection", "Delete"),
			NSLOCTEXT("Sequencer", "DeleteSectionToolTip", "Deletes this section."),
			FSlateIcon(),
			FUIAction(FExecuteAction::CreateSP(&Sequencer, &FSequencer::DeleteSection, SceneSection))
			);
	}
	
	return MenuBuilder.MakeWidget();
}
FReply SProfilerThreadView::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	FReply Reply = FReply::Unhandled();

	if( IsReady() )
	{
		MousePositionOnButtonDown = MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() );

		if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton )
		{
			bIsLeftMousePressed = true;
			DistanceDragged = PositionXMS;

			// Capture mouse, so we can move outside this widget.
			Reply = FReply::Handled().CaptureMouse( SharedThis( this ) );
		}
		else if( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton )
		{
			bIsRightMousePressed = true;
		}
	}

	return Reply;
}
void STableViewBase::OnRightMouseButtonUp(const FPointerEvent& MouseEvent)
{
	const FVector2D& SummonLocation = MouseEvent.GetScreenSpacePosition();
	const bool bShouldOpenContextMenu = !IsRightClickScrolling();
	const bool bContextMenuOpeningBound = OnContextMenuOpening.IsBound();

	if ( bShouldOpenContextMenu && bContextMenuOpeningBound )
	{
		// Get the context menu content. If NULL, don't open a menu.
		TSharedPtr<SWidget> MenuContent = OnContextMenuOpening.Execute();

		if( MenuContent.IsValid() )
		{
			bShowSoftwareCursor = false;

			FWidgetPath WidgetPath = MouseEvent.GetEventPath() != nullptr ? *MouseEvent.GetEventPath() : FWidgetPath();
			FSlateApplication::Get().PushMenu(AsShared(), WidgetPath, MenuContent.ToSharedRef(), SummonLocation, FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu));


		}
	}

	AmountScrolledWhileRightMouseDown = 0;
}
FReply SVirtualJoystick::OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& Event)
{
	FVector2D LocalCoord = MyGeometry.AbsoluteToLocal( Event.GetScreenSpacePosition() );

	for (int32 ControlIndex = 0; ControlIndex < Controls.Num(); ControlIndex++)
	{
		FControlInfo& Control = Controls[ControlIndex];

		// is this control the one captured to this pointer?
		if (Control.CapturedPointerIndex == Event.GetPointerIndex())
		{
			if (Control.bNeedUpdatedCenter)
			{
				return FReply::Unhandled();
			}
			else if (HandleTouch(ControlIndex, LocalCoord, MyGeometry.Size))
			{
				return FReply::Handled();
			}
		}
	}

	return FReply::Unhandled();
}
Exemple #9
0
bool SColorWheel::ProcessMouseAction(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bProcessWhenOutsideColorWheel)
{
	const FVector2D LocalMouseCoordinate = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
	const FVector2D Location = LocalMouseCoordinate / (MyGeometry.Size * 0.5f) - FVector2D(1.0f, 1.0f);
	const float Radius = Location.Size();

	if (Radius <= 1.0f || bProcessWhenOutsideColorWheel)
	{
		float Angle = FMath::Atan2(Location.Y, Location.X);

		if (Angle < 0.0f)
		{
			Angle += 2.0f * PI;
		}

		FLinearColor NewColor = SelectedColor.Get();
		NewColor.R = Angle * 180.0f * INV_PI;
		NewColor.G = FMath::Min(Radius, 1.0f);

		OnValueChanged.ExecuteIfBound(NewColor);
	}

	return (Radius <= 1.0f);
}
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;
}
int32 SWidget::FindChildUnderMouse( const FArrangedChildren& Children, const FPointerEvent& MouseEvent )
{
	const FVector2D& AbsoluteCursorLocation = MouseEvent.GetScreenSpacePosition();
	return SWidget::FindChildUnderPosition( Children, AbsoluteCursorLocation );
}
	virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override
	{
		struct FWidgetPicker
		{
			static bool FindWidgetsUnderPoint(const FVector2D& InHitTestPoint, const FVector2D& InWindowPosition, const TSharedRef<FWidgetReflectorNodeBase>& InWidget, TArray<TSharedRef<FWidgetReflectorNodeBase>>& OutWidgets)
			{
				const bool bNeedsHitTesting = InWidget->GetHitTestInfo().IsHitTestVisible || InWidget->GetHitTestInfo().AreChildrenHitTestVisible;
				if (bNeedsHitTesting)
				{
					const FSlateRect HitTestRect = FSlateRect::FromPointAndExtent(
						InWidget->GetAccumulatedLayoutTransform().GetTranslation() - InWindowPosition, 
						TransformPoint(InWidget->GetAccumulatedLayoutTransform().GetScale(), InWidget->GetLocalSize())
						);

					if (HitTestRect.ContainsPoint(InHitTestPoint))
					{
						OutWidgets.Add(InWidget);

						if (InWidget->GetHitTestInfo().AreChildrenHitTestVisible)
						{
							for (const auto& ChildWidget : InWidget->GetChildNodes())
							{
								if (FindWidgetsUnderPoint(InHitTestPoint, InWindowPosition, ChildWidget, OutWidgets))
								{
									return true;
								}
							}
						}

						return InWidget->GetHitTestInfo().IsHitTestVisible;
					}
				}

				return false;
			}
		};

		if (bIsPicking)
		{
			// We need to pick in the snapshot window space, so convert the mouse co-ordinates to be relative to our top-left position
			const FVector2D& ScreenMousePos = MouseEvent.GetScreenSpacePosition();
			const FVector2D LocalMousePos = MyGeometry.AbsoluteToLocal(ScreenMousePos);
			const FVector2D ScrolledPos = LocalMousePos - PhysicalOffset;

			PickedWidgets.Reset();

			TSharedPtr<FWidgetReflectorNodeBase> Window = SnapshotDataPtr->GetWindow(SelectedWindowIndex);
			if (Window.IsValid())
			{
				FWidgetPicker::FindWidgetsUnderPoint(
					ScrolledPos, 
					Window->GetAccumulatedLayoutTransform().GetTranslation(), 
					Window.ToSharedRef(), 
					PickedWidgets
					);
			}

			if (PickedWidgets.Num() > 0)
			{
				OnWidgetPathPicked.ExecuteIfBound(PickedWidgets);
			}
		}

		return ScrollyZoomy.OnMouseMove(AsShared(), *this, MyGeometry, MouseEvent);
	}
Exemple #13
0
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;
}
void FSceneViewport::UpdateCachedMousePos( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	CachedMousePos = InGeometry.AbsoluteToLocal( InMouseEvent.GetScreenSpacePosition() ).IntPoint();
}
FReply FSceneViewport::OnMouseButtonDown( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	// Start a new reply state
	// Prevent throttling when interacting with the viewport so we can move around in it
	CurrentReplyState = FReply::Handled().PreventThrottling();

	KeyStateMap.Add(InMouseEvent.GetEffectingButton(), true);
	UpdateModifierKeys( InMouseEvent );
	UpdateCachedMousePos( InGeometry, InMouseEvent );
	UpdateCachedGeometry(InGeometry);

	// Switch to the viewport clients world before processing input
	FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue )
	{
		// If we're obtaining focus, we have to copy the modifier key states prior to processing this mouse button event, as this is the only point at which the mouse down
		// event is processed when focus initially changes and the modifier keys need to be in-place to detect any unique drag-like events.
		if ( !HasFocus() )
		{
			FModifierKeysState KeysState = FSlateApplication::Get().GetModifierKeys();
			ApplyModifierKeys( KeysState );
		}

		const bool bAnyMenuWasVisible = FSlateApplication::Get().AnyMenusVisible();

		// Process the mouse event
		if (!ViewportClient->InputKey(this, InMouseEvent.GetUserIndex(), InMouseEvent.GetEffectingButton(), IE_Pressed))
		{
			CurrentReplyState = FReply::Unhandled(); 
		}

		// a new menu was opened if there was previously not a menu visible but now there is
		const bool bNewMenuWasOpened = !bAnyMenuWasVisible && FSlateApplication::Get().AnyMenusVisible();

		if (!ViewportClient->IgnoreInput() &&
			!bNewMenuWasOpened && // We should not focus the viewport if a menu was opened as it would close the menu
			( ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CapturePermanently ||
			  ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringMouseDown ||
			  ( ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringRightMouseDown && InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) ) )
		{
			TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.Pin().ToSharedRef();

			// Mouse down should focus viewport for user input
			CurrentReplyState.SetUserFocus(ViewportWidgetRef, EFocusCause::SetDirectly, true);
			
			UWorld* World = ViewportClient->GetWorld();
			if (World && World->IsGameWorld() && World->GetFirstPlayerController())
			{
				CurrentReplyState.CaptureMouse(ViewportWidgetRef);
				CurrentReplyState.LockMouseToWidget(ViewportWidgetRef);

				bool bShouldShowMouseCursor = World->GetFirstPlayerController()->ShouldShowMouseCursor();
				if (ViewportClient->HideCursorDuringCapture() && bShouldShowMouseCursor)
				{
					bCursorHiddenDueToCapture = true;
					MousePosBeforeHiddenDueToCapture = FIntPoint( InMouseEvent.GetScreenSpacePosition().X, InMouseEvent.GetScreenSpacePosition().Y );
				}
				if (bCursorHiddenDueToCapture || !bShouldShowMouseCursor)
				{
					CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef);
				}
			}
			else
			{
				CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef);
			}
		}
	}
	
	// Re-set prevent throttling here as it can get reset when inside of InputKey()
	CurrentReplyState.PreventThrottling();

	return CurrentReplyState;
}
float SDockingTabWell::ComputeDraggedTabOffset( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, const FVector2D& InTabGrabOffsetFraction ) const
{
	const FVector2D ComputedChildSize = ComputeChildSize(MyGeometry);
	return MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ).X - InTabGrabOffsetFraction .X * ComputedChildSize.X;
}
void SColorGradientEditor::OpenGradientStopContextMenu(const FPointerEvent& MouseEvent)
{
	const FVector2D& Location = MouseEvent.GetScreenSpacePosition();

	FMenuBuilder GradientStopMenu( true, NULL );

	
	FUIAction RemoveStopAction( FExecuteAction::CreateSP( this, &SColorGradientEditor::OnRemoveSelectedGradientStop ) );
	{
		TSharedPtr<SWidget> WidgetToFocus;

		// Set color
		if( SelectedStop.IsValidColorMark( CurveOwner->GetCurves() ) )
		{
			GradientStopMenu.BeginSection( NAME_None, LOCTEXT("ColorMenuSecton", "Color") );

			FUIAction SetColorAction( FExecuteAction::CreateSP( this, &SColorGradientEditor::OpenGradientStopColorPicker ) );

			GradientStopMenu.AddMenuEntry( LOCTEXT("SetColorMenuItem", "Choose Color..."), LOCTEXT("SetColorMenuItem_ToolTip", "Opens a color picker to change the color of the stop"), FSlateIcon(), SetColorAction );

			GradientStopMenu.EndSection();
		}
		else
		{
			GradientStopMenu.BeginSection( NAME_None, LOCTEXT("AlphaMenuSection", "Opacity") );


			TSharedRef<SWidget> Widget = 
				SNew( SBox )
				.WidthOverride( 100.0f )
				[
					SNew( SSpinBox<float> )
					.MinSliderValue(0.0f)
					.MaxSliderValue(1.0f)
					.MinValue(-FLT_MAX)
					.MaxValue(FLT_MAX)
					.Value( SelectedStop.GetColor( *CurveOwner ).A )
					.OnBeginSliderMovement( this, &SColorGradientEditor::OnBeginChangeAlphaValue )
					.OnEndSliderMovement( this, &SColorGradientEditor::OnEndChangeAlphaValue )
					.OnValueChanged( this, &SColorGradientEditor::OnAlphaValueChanged )
					.OnValueCommitted( this, &SColorGradientEditor::OnAlphaValueCommitted )
				];

			GradientStopMenu.AddWidget( Widget, FText::GetEmpty() );

			GradientStopMenu.EndSection();
		}

		// Set time
		{
			TSharedRef<SEditableTextBox> EditableTextBox = 
				SNew( SEditableTextBox )
				.MinDesiredWidth(50.0f)
				.Text( FText::AsNumber( SelectedStop.Time ) )
				.OnTextCommitted( this, &SColorGradientEditor::OnSetGradientStopTimeFromPopup )
				.SelectAllTextWhenFocused( true )
				.ClearKeyboardFocusOnCommit( false )
				.SelectAllTextOnCommit( true );


			GradientStopMenu.BeginSection( NAME_None, LOCTEXT("TimeMenuSection", "Time") );

			GradientStopMenu.AddWidget( EditableTextBox, FText::GetEmpty() );

			GradientStopMenu.EndSection();

			WidgetToFocus = EditableTextBox;
		}


		GradientStopMenu.AddMenuSeparator();

		// Add a Remove option
		GradientStopMenu.AddMenuEntry( LOCTEXT("RemoveGradientStop", "Remove Stop"), LOCTEXT("RemoveGradientStopTooltip", "Removes the selected gradient stop"), FSlateIcon(), RemoveStopAction );

		FWidgetPath WidgetPath = MouseEvent.GetEventPath() != nullptr ? *MouseEvent.GetEventPath() : FWidgetPath();
		FSlateApplication::Get().PushMenu(AsShared(), WidgetPath, GradientStopMenu.MakeWidget(), Location, FPopupTransitionEffect::ContextMenu);

		FSlateApplication::Get().SetKeyboardFocus( WidgetToFocus.ToSharedRef() );
	}

	ContextMenuPosition = Location;
}
/**
 * Invoked when the drag and drop operation has ended.
 * 
 * @param bDropWasHandled   true when the drop was handled by some widget; false otherwise
 */
void FDockingDragOperation::OnDrop( bool bDropWasHandled, const FPointerEvent& MouseEvent )
{
	check(CursorDecoratorWindow.IsValid());

	const FVector2D WindowSize = CursorDecoratorWindow->GetSizeInScreen();
	// Destroy the CursorDecoratorWindow by calling the base class implementation because we are relocating the content into a more permanent home.
	FDragDropOperation::OnDrop(bDropWasHandled, MouseEvent);

	TabBeingDragged->SetDraggedOverDockArea( NULL );

	if (!bDropWasHandled)
	{
		// If we dropped the tab into an existing DockNode then it would have handled the DropEvent.
		// We are here because that didn't happen, so make a new window with a new DockNode and drop the tab into that.

		const FVector2D PositionToDrop = MouseEvent.GetScreenSpacePosition() - GetDecoratorOffsetFromCursor();

		TSharedRef<FTabManager> MyTabManager = TabBeingDragged->GetTabManager();
		
		TSharedPtr<SWindow> NewWindowParent = MyTabManager->GetPrivateApi().GetParentWindow();

		
		TSharedRef<SWindow> NewWindow = SNew(SWindow)
			.Title( FGlobalTabmanager::Get()->GetApplicationTitle() )
			.AutoCenter(EAutoCenter::None)
			.ScreenPosition( PositionToDrop )
			// Make room for the title bar; otherwise windows will get progressive smaller whenver you float them.
			.ClientSize( SWindow::ComputeWindowSizeForContent( WindowSize ) )
			.CreateTitleBar(false);

		TSharedPtr<SDockingTabStack> NewDockNode;

		if ( TabBeingDragged->GetTabRole() == ETabRole::NomadTab )
		{
			TabBeingDragged->SetTabManager(FGlobalTabmanager::Get());
		}

		// Create a new dockarea
		TSharedRef<SDockingArea> NewDockArea = 
			SNew(SDockingArea, TabBeingDragged->GetTabManager(), FTabManager::NewPrimaryArea())
			. ParentWindow( NewWindow )
			. InitialContent
			(
				SAssignNew(NewDockNode, SDockingTabStack, FTabManager::NewStack())
			);

		if (TabBeingDragged->GetTabRole() == ETabRole::MajorTab || TabBeingDragged->GetTabRole() == ETabRole::NomadTab)
		{
			TSharedPtr<SWindow> RootWindow = FGlobalTabmanager::Get()->GetRootWindow();
			if ( RootWindow.IsValid() )
			{
				// We have a root window, so all MajorTabs are nested under it.
				FSlateApplication::Get().AddWindowAsNativeChild( NewWindow, RootWindow.ToSharedRef() )->SetContent(NewDockArea);
			}
			else
			{
				// App tabs get put in top-level windows. They show up on the taskbar.
				FSlateApplication::Get().AddWindow( NewWindow )->SetContent(NewDockArea);
			}
		}
		else
		{
			// Other tab types are placed in child windows. Their life is controlled by the top-level windows.
			// They do not show up on the taskbar.

			if ( NewWindowParent.IsValid() )
			{
				FSlateApplication::Get().AddWindowAsNativeChild( NewWindow, NewWindowParent.ToSharedRef() )->SetContent(NewDockArea);
			}
			else
			{
				FSlateApplication::Get().AddWindow( NewWindow )->SetContent(NewDockArea);
			}
		}

		// Do this after the window parenting so that the window title is set correctly
		NewDockNode->OpenTab(TabBeingDragged.ToSharedRef());

		// Let every widget under this tab manager know that this tab has found a new home.
		TabOwnerAreaOfOrigin->GetTabManager()->GetPrivateApi().OnTabRelocated( TabBeingDragged.ToSharedRef(), NewWindow );
	}
	else
	{
		// The event was handled, so we HAVE to have some window that we dropped onto.
		TSharedRef<SWindow> WindowDroppedInto = MouseEvent.GetWindow();

		// Let every widget under this tab manager know that this tab has found a new home.
		TSharedPtr<SWindow> NewWindow = ( TabOwnerAreaOfOrigin->GetParentWindow() == WindowDroppedInto )
			// Tab dropped into same window as before, meaning there is no NewWindow.
			? TSharedPtr<SWindow>()
			// Tab was dropped into a different window, so the tab manager needs to know in order to re-parent child windows.
			: WindowDroppedInto;

		TabOwnerAreaOfOrigin->GetTabManager()->GetPrivateApi().OnTabRelocated( TabBeingDragged.ToSharedRef(), WindowDroppedInto );
	}
}
Exemple #19
0
FReply FTextEditHelper::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& InMouseEvent, const TSharedRef< ITextEditorWidget >& TextEditor )
{
	FReply Reply = FReply::Unhandled();

	// If the mouse is already captured, then don't allow a new action to be taken
	if( !TextEditor->GetWidget()->HasMouseCapture() )
	{
		if( InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ||
			InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton )
		{
			// Am I getting focus right now?
			const bool bIsGettingFocus = !TextEditor->GetWidget()->HasKeyboardFocus();
			if( bIsGettingFocus )
			{
				// We might be receiving keyboard focus due to this event.  Because the keyboard focus received callback
				// won't fire until after this function exits, we need to make sure our widget's state is in order early

				// Assume we'll be given keyboard focus, so load text for editing
				TextEditor->LoadText();

				// Reset 'mouse has moved' state.  We'll use this in OnMouseMove to determine whether we
				// should reset the selection range to the caret's position.
				TextEditor->SetWasFocusedByLastMouseDown( true );
			}

			if( InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton )
			{
				if( InMouseEvent.IsShiftDown() )
				{
					TextEditor->MoveCursor( FMoveCursor::ViaScreenPointer( MyGeometry.AbsoluteToLocal( InMouseEvent.GetScreenSpacePosition( ) ), MyGeometry.Scale, ECursorAction::SelectText ) );
				}
				else
				{
					// Deselect any text that was selected
					TextEditor->ClearSelection();
					TextEditor->MoveCursor( FMoveCursor::ViaScreenPointer( MyGeometry.AbsoluteToLocal( InMouseEvent.GetScreenSpacePosition( ) ), MyGeometry.Scale, ECursorAction::MoveCursor ) );
				}

				// Start drag selection
				TextEditor->BeginDragSelection();
			}
			else if( InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton )
			{
				// If the user right clicked on a character that wasn't already selected, we'll clear
				// the selection
				if ( TextEditor->AnyTextSelected( ) && !TextEditor->IsTextSelectedAt( MyGeometry, InMouseEvent.GetScreenSpacePosition() ) )
				{
					// Deselect any text that was selected
					TextEditor->ClearSelection();
				}
			}

			// Right clicking to summon context menu, but we'll do that on mouse-up.
			Reply = FReply::Handled();
			Reply.CaptureMouse( TextEditor->GetWidget() );
			Reply.SetUserFocus(TextEditor->GetWidget(), EFocusCause::Mouse);
		}
	}

	return Reply;
}
FVector2D UKismetInputLibrary::PointerEvent_GetScreenSpacePosition(const FPointerEvent& Input)
{
	return Input.GetScreenSpacePosition();
}
FReply SCaptureRegionWidget::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if (IsEnabled() && MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		FVector2D ViewportPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition;
		FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion;

		switch (PotentialInteraction)
		{
		case PI_DrawNewCaptureRegion:
			{
				DragStartPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition;
				BuildNewCaptureRegion(DragStartPosition, DragStartPosition);
				CurrentState = State_Dragging;
				break;
			}
		case PI_ResizeBL:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y);
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				CurrentState = State_Dragging;
				break;
			}

		case PI_ResizeTL:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Max.Y);
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				CurrentState = State_Dragging;
				break;
			}
		case PI_ResizeBR:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y);
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				CurrentState = State_Dragging;
				break;
			}

		case PI_ResizeTR:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y);
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				CurrentState = State_Dragging;
				break;
			}

		case PI_ResizeBottom:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y);
				CurrentState = State_YAxisResize;
				break;
			}

		case PI_ResizeTop:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y);
				CurrentState = State_YAxisResize;
				break;
			}

		case PI_ResizeLeft:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y);
				CurrentState = State_XAxisResize;
				break;
			}

		case PI_ResizeRight:
			{
				DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y);
				CurrentState = State_XAxisResize;
				break;
			}

		case PI_MoveExistingRegion:
			{
				DragStartPosition = ViewportPosition;
				CurrentState = State_Moving;
				break;
			}
		}
		
		return FReply::Handled();
	}
	else
	{
		return FReply::Unhandled();
	}
}
FReply SCaptureRegionWidget::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if (IsEnabled())
	{
		FVector2D ViewportPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition;
		FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion;

		switch (CurrentState)
		{
		case State_Dragging:
			{
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				break;
			}

		case State_Moving:
			{
				FVector2D Delta = ViewportPosition - DragStartPosition;
				DragStartPosition = ViewportPosition;
				CurrentCaptureRegion += FIntPoint((int32)Delta.X, (int32)Delta.Y);
				//OnCaptureRegionChanged.ExecuteIfBound(CurrentCaptureRegion);
				SendUpdatedCaptureRegion();
				break;
			}

		case State_XAxisResize:
			{
				ViewportPosition.Y = CurrentCaptureRegion.Max.Y;
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				break;
			}

		case State_YAxisResize:
			{
				ViewportPosition.X = CurrentCaptureRegion.Max.X;
				BuildNewCaptureRegion(ViewportPosition, DragStartPosition);
				break;
			}
		
		case State_Inactive:
			{
				if (CurrentCaptureRegion.Area() > 0 && !bIgnoreExistingCaptureRegion)
				{
					// Common tests
					bool bWithinXRangeOfExistingRegion = ViewportPosition.X >= CurrentCaptureRegion.Min.X && ViewportPosition.X <= CurrentCaptureRegion.Max.X;
					bool bWithinYRangeOfExistingRegion = ViewportPosition.Y >= CurrentCaptureRegion.Min.Y && ViewportPosition.Y <= CurrentCaptureRegion.Max.Y;

					// Distance away from an edge which we consider intersecting
					const float EdgeDistance = 5;

					// Check if we're over the corners
					if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y)).Size() < EdgeDistance)
					{
						this->Cursor = EMouseCursor::ResizeSouthEast;
						PotentialInteraction = PI_ResizeTL;
					}
					else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y)).Size() < EdgeDistance)
					{
						this->Cursor = EMouseCursor::ResizeSouthWest;
						PotentialInteraction = PI_ResizeBL;
					}
					else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y)).Size() < EdgeDistance)
					{
						this->Cursor = EMouseCursor::ResizeSouthWest;
						PotentialInteraction = PI_ResizeTR;
					}
					else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Max.Y)).Size() < EdgeDistance)
					{
						this->Cursor = EMouseCursor::ResizeSouthEast;
						PotentialInteraction = PI_ResizeBR;
					}
					else if (FMath::Abs((float)CurrentCaptureRegion.Min.X - ViewportPosition.X) < EdgeDistance && bWithinYRangeOfExistingRegion)
					{
						this->Cursor = EMouseCursor::ResizeLeftRight;
						PotentialInteraction = PI_ResizeLeft;
					}
					else if (FMath::Abs((float)CurrentCaptureRegion.Max.X - ViewportPosition.X) < EdgeDistance && bWithinYRangeOfExistingRegion)
					{
						this->Cursor = EMouseCursor::ResizeLeftRight;
						PotentialInteraction = PI_ResizeRight;
					}
					else if (FMath::Abs((float)CurrentCaptureRegion.Min.Y - ViewportPosition.Y) < EdgeDistance && bWithinXRangeOfExistingRegion)
					{
						this->Cursor = EMouseCursor::ResizeUpDown;
						PotentialInteraction = PI_ResizeTop;
					}
					else if (FMath::Abs((float)CurrentCaptureRegion.Max.Y - ViewportPosition.Y) < EdgeDistance && bWithinXRangeOfExistingRegion)
					{
						this->Cursor = EMouseCursor::ResizeUpDown;
						PotentialInteraction = PI_ResizeBottom;
					}
					else if (CurrentCaptureRegion.Contains(FIntPoint((int32)ViewportPosition.X, (int32)ViewportPosition.Y)))
					{
						this->Cursor = EMouseCursor::CardinalCross;
						PotentialInteraction = PI_MoveExistingRegion;
					}
					else
					{
						this->Cursor = EMouseCursor::Crosshairs;
						PotentialInteraction = PI_DrawNewCaptureRegion;
					}
				}
				else
				{
					this->Cursor = EMouseCursor::Crosshairs;
					PotentialInteraction = PI_DrawNewCaptureRegion;
				}

				break;
			}

		default:
			{
				check(false);
				break;
			}
		}

		return FReply::Handled();
	}
	else
	{
		return FReply::Unhandled();
	}
}
Exemple #23
0
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 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();
}
	/** 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();
	}
Exemple #26
0
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();
}