FReply STableViewBase::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if ( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton )
	{

		OnRightMouseButtonUp( MouseEvent );

		FReply Reply = FReply::Handled().ReleaseMouseCapture();
		bShowSoftwareCursor = false;

		// If we have mouse capture, snap the mouse back to the closest location that is within the list's bounds
		if ( HasMouseCapture() )
		{
			FSlateRect ListScreenSpaceRect = MyGeometry.GetClippingRect();
			FVector2D CursorPosition = MyGeometry.LocalToAbsolute( SoftwareCursorPosition );

			FIntPoint BestPositionInList(
				FMath::RoundToInt( FMath::Clamp( CursorPosition.X, ListScreenSpaceRect.Left, ListScreenSpaceRect.Right ) ),
				FMath::RoundToInt( FMath::Clamp( CursorPosition.Y, ListScreenSpaceRect.Top, ListScreenSpaceRect.Bottom ) )
				);

			Reply.SetMousePos(BestPositionInList);
		}

		return Reply;
	}
	return FReply::Unhandled();
}
FReply SButton::OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent )
{
	FReply Reply = FReply::Unhandled();
	if (IsEnabled() && (InKeyEvent.GetKey() == EKeys::Enter || InKeyEvent.GetKey() == EKeys::SpaceBar || InKeyEvent.GetKey() == EKeys::Gamepad_FaceButton_Bottom))
	{
		Press();

		if (PressMethod == EButtonPressMethod::ButtonPress)
		{
			//execute our "OnClicked" delegate, and get the reply
			Reply = OnClicked.IsBound() ? OnClicked.Execute() : FReply::Handled();

			//You should ALWAYS handle the OnClicked event.
			ensure(Reply.IsEventHandled() == true);
		}
		else
		{
			Reply = FReply::Handled();
		}
	}
	else
	{
		Reply = SBorder::OnKeyDown(MyGeometry, InKeyEvent);
	}

	//return the constructed reply
	return Reply;
}
FReply SButton::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	FReply Reply = FReply::Unhandled();
	if (IsEnabled() && (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton || MouseEvent.IsTouchEvent()))
	{
		Press();
		
		if( ClickMethod == EButtonClickMethod::MouseDown )
		{
			//get the reply from the execute function
			Reply = OnClicked.IsBound() ? OnClicked.Execute() : FReply::Handled();

			//You should ALWAYS handle the OnClicked event.
			ensure(Reply.IsEventHandled() == true);
		}
		else if ( IsPreciseTapOrClick(MouseEvent) )
		{
			// do not capture the pointer for precise taps or clicks
			// 
		}
		else
		{
			//we need to capture the mouse for MouseUp events
			Reply =  FReply::Handled().CaptureMouse( AsShared() );
		}
	}

	Invalidate(EInvalidateWidget::Layout);

	//return the constructed reply
	return Reply;
}
FReply FScrollyZoomy::OnMouseButtonUp( const TSharedRef<SWidget> MyWidget, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
	{
		AmountScrolledWhileRightMouseDown = 0;

		FReply Reply = FReply::Handled().ReleaseMouseCapture();
		bShowSoftwareCursor = false;

		// If we have mouse capture, snap the mouse back to the closest location that is within the panel's bounds
		if (MyWidget->HasMouseCapture())
		{
			FSlateRect PanelScreenSpaceRect = MyGeometry.GetClippingRect();
			FVector2D CursorPosition = MyGeometry.LocalToAbsolute( SoftwareCursorPosition );

			FIntPoint BestPositionInPanel(
				FMath::RoundToInt( FMath::Clamp( CursorPosition.X, PanelScreenSpaceRect.Left, PanelScreenSpaceRect.Right ) ),
				FMath::RoundToInt( FMath::Clamp( CursorPosition.Y, PanelScreenSpaceRect.Top, PanelScreenSpaceRect.Bottom ) )
				);

			Reply.SetMousePos( BestPositionInPanel );
		}

		if (!bUseIntertialScrolling)
		{
			HorizontalIntertia.ClearScrollVelocity();
			VerticalIntertia.ClearScrollVelocity();
		}

		return Reply;
	}

	return FReply::Unhandled();
}
FReply SButton::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
	FReply Reply = FReply::Unhandled();


	if (IsEnabled() && (/* InKeyEvent.GetKey() == EKeys::Enter || InKeyEvent.GetKey() == EKeys::SpaceBar || */ InKeyEvent.GetKey() == EKeys::Gamepad_FaceButton_Bottom))
	{
		const bool bWasPressed = bIsPressed;

		Release();

		//@Todo Slate: This should check focus, however we don't have that API yet, will be easier when focus is unified.
		if ( PressMethod == EButtonPressMethod::ButtonRelease || ( PressMethod == EButtonPressMethod::DownAndUp && bWasPressed ) )
		{
			//execute our "OnClicked" delegate, and get the reply
			Reply = OnClicked.IsBound() ? OnClicked.Execute() : FReply::Handled();

			//You should ALWAYS handle the OnClicked event.
			ensure(Reply.IsEventHandled() == true);
		}
		else
		{
			Reply = FReply::Handled();
		}
	}

	//return the constructed reply
	return Reply;
}
FReply FSequencerEditTool_Movement::OnMouseMove(SWidget& OwnerWidget, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (DelayedDrag.IsSet())
	{
		const FVirtualTrackArea VirtualTrackArea = SequencerWidget.Pin()->GetVirtualTrackArea();

		FReply Reply = FReply::Handled();

		if (DelayedDrag->IsDragging())
		{
			// If we're already dragging, just update the drag op if it exists
			if (DragOperation.IsValid())
			{
				DragOperation->OnDrag(MouseEvent, MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()), VirtualTrackArea);
			}
		}
		// Otherwise we can attempt a new drag
		else if (DelayedDrag->AttemptDragStart(MouseEvent))
		{
			DragOperation = CreateDrag();

			if (DragOperation.IsValid())
			{
				DragOperation->OnBeginDrag(MouseEvent, DelayedDrag->GetInitialPosition(), VirtualTrackArea);

				// Steal the capture, as we're now the authoritative widget in charge of a mouse-drag operation
				Reply.CaptureMouse(OwnerWidget.AsShared());
			}
		}

		return Reply;
	}
	return FReply::Unhandled();
}
FReply SPaperEditorViewport::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	TotalMouseDelta = 0;

	if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
	{
		// RIGHT BUTTON is for dragging and Context Menu.
		FReply ReplyState = FReply::Handled();
		ReplyState.CaptureMouse( SharedThis(this) );
		ReplyState.UseHighPrecisionMouseMovement( SharedThis(this) );

		SoftwareCursorPosition = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) );

		// clear any interpolation when you manually pan
		//DeferredMovementTargetObject = nullptr;

		return ReplyState;
	}
	else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		// START MARQUEE SELECTION.
		const FVector2D GraphMousePos = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal( MouseEvent.GetScreenSpacePosition() ) );
		Marquee.Start( GraphMousePos, FMarqueeOperation::OperationTypeFromMouseEvent(MouseEvent) );

		// Trigger a selection update now so that single-clicks without a drag still select something
		OnSelectionChanged.ExecuteIfBound(Marquee, true);
		PaperViewportClient->Invalidate();

		return FReply::Handled().CaptureMouse( SharedThis(this) );
	}
	else
	{
		return FReply::Unhandled();
	}
}
static PyObject *py_ue_swidget_on_mouse_button_up(ue_PySWidget *self, PyObject * args)
{
	PyObject *py_geometry;
	PyObject *py_pointer_event;
	if (!PyArg_ParseTuple(args, "OO:on_mouse_button_up", &py_geometry, &py_pointer_event))
	{
		return nullptr;
	}

	ue_PyFGeometry *geometry = py_ue_is_fgeometry(py_geometry);
	if (!geometry)
	{
		return PyErr_Format(PyExc_Exception, "argument is not a FGeomtry");
	}

	ue_PyFPointerEvent *pointer = py_ue_is_fpointer_event(py_pointer_event);
	if (!pointer)
	{
		return PyErr_Format(PyExc_Exception, "argument is not a FPointerEvent");
	}

	FReply reply = self->Widget->OnMouseButtonUp(geometry->geometry, pointer->pointer);

	if (reply.IsEventHandled())
	{
		Py_RETURN_TRUE;
	}

	Py_RETURN_FALSE;
}
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;
}
	virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override
	{
		FReply Reply = SSpinBox<T>::OnMouseButtonDown(MyGeometry, MouseEvent);
		if (Reply.IsEventHandled())
		{
			Reply.PreventThrottling();
		}
		return Reply;
	}
Exemple #11
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;
}
FReply FWebBrowserViewport::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	// Release mouse capture when left button released
	FReply Reply = WebBrowserWindow->OnMouseButtonUp(MyGeometry, MouseEvent);
	if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		return Reply.ReleaseMouseCapture();
	}
	return Reply;
}
FReply FWebBrowserViewport::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	// Capture mouse on left button down so that you can drag out of the viewport
	FReply Reply = WebBrowserWindow->OnMouseButtonDown(MyGeometry, MouseEvent);
	if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && ViewportWidget.IsValid())
	{
		return Reply.CaptureMouse(ViewportWidget.Pin().ToSharedRef());
	}
	return Reply;
}
FReply SDetailsViewBase::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent)
{
	FReply Reply = FReply::Handled();

	if (InFocusEvent.GetCause() != EFocusCause::Cleared)
	{
		Reply.SetUserFocus(SearchBox.ToSharedRef(), InFocusEvent.GetCause());
	}

	return Reply;
}
FReply SSequencerTrackArea::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	auto SequencerPin = SequencerWidget.Pin();
	if (SequencerPin.IsValid())
	{
		FReply Reply = SequencerPin->GetEditTool().OnMouseButtonUp(*this, MyGeometry, MouseEvent);
		if (Reply.IsEventHandled())
		{
			return Reply;
		}
	}

	return TimeSliderController->OnMouseButtonUp( SharedThis(this), MyGeometry, MouseEvent );
}
FReply SObjectWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& InAnalogInputEvent)
{
	if ( CanRouteEvent() )
	{
		FReply Result = WidgetObject->NativeOnAnalogValueChanged(MyGeometry, InAnalogInputEvent);
		if ( !Result.IsEventHandled() )
		{
			return SCompoundWidget::OnAnalogValueChanged(MyGeometry, InAnalogInputEvent);
		}

		return Result;
	}

	return FReply::Unhandled();
}
FReply SObjectWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
	if ( CanRouteEvent() )
	{
		FReply Result = WidgetObject->NativeOnKeyUp(MyGeometry, InKeyEvent);
		if ( !Result.IsEventHandled() )
		{
			return SCompoundWidget::OnKeyUp(MyGeometry, InKeyEvent);
		}

		return Result;
	}

	return FReply::Unhandled();
}
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 FKismetDragDropAction::DroppedOnPanel( const TSharedRef< SWidget >& Panel, FVector2D ScreenPosition, FVector2D GraphPosition, UEdGraph& Graph)
{	
	FReply Reply = FReply::Unhandled();

	FText CannotDropReason = FText::GetEmpty();
	if (!CanBeDroppedDelegate.IsBound() || CanBeDroppedDelegate.Execute(ActionNode, GetHoveredGraph(), CannotDropReason))
	{
		Reply = FGraphSchemaActionDragDropAction::DroppedOnPanel(Panel, ScreenPosition, GraphPosition, Graph);
	}

	if (Reply.IsEventHandled())
	{
		AnalyticCallback.ExecuteIfBound();
	}

	return Reply;
}
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 );
}
FReply SComboButton::OnButtonClicked()
{
	TSharedPtr<SWidget> Content = NULL;
	if( OnGetMenuContent.IsBound() )
	{
		Content = OnGetMenuContent.Execute();
		SetMenuContent( Content.ToSharedRef() );
	}

	// Button was clicked; show the popup.
	// Do nothing if clicking on the button also dismissed the menu, because we will end up doing the same thing twice.
	this->SetIsOpen( ShouldOpenDueToClick() );	

	// If the menu is open, execute the related delegate.
	if( IsOpen() && OnComboBoxOpened.IsBound() )
	{
		OnComboBoxOpened.Execute();
	}

	// Focusing any newly-created widgets must occur after they have been added to the UI root.
	FReply ButtonClickedReply = FReply::Handled();
	
	TSharedPtr<SWidget> WidgetToFocus = WidgetToFocusPtr.Pin();
	if (!WidgetToFocus.IsValid())
	{
		// no explicitly focused widget, try to focus the content
		WidgetToFocus = Content;
	}

	if (!WidgetToFocus.IsValid())
	{
		// no content, so try to focus the original widget set on construction
		WidgetToFocus = ContentWidgetPtr.Pin();
	}

	if (WidgetToFocus.IsValid())
	{
		ButtonClickedReply.SetKeyboardFocus( WidgetToFocus.ToSharedRef(), EKeyboardFocusCause::SetDirectly );
	}

	return ButtonClickedReply;
}
Exemple #22
0
FReply SSection::OnMouseButtonDoubleClick( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	ResetState();

	UMovieSceneSection* SectionObject = SectionInterface->GetSectionObject();
	if( GetSequencer().IsSectionVisible( SectionObject ) )
	{
		FReply Reply = SectionInterface->OnSectionDoubleClicked( MyGeometry, MouseEvent );

		if (Reply.IsEventHandled()) {return Reply;}

		if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton )
		{
			GetSequencer().ZoomToSelectedSections();

			return FReply::Handled();
		}
	}

	return FReply::Unhandled();
}
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 SSequencerTrackArea::OnMouseWheel( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	// First try the edit tool
	auto SequencerPin = SequencerWidget.Pin();
	if (SequencerPin.IsValid())
	{
		FReply Reply = SequencerPin->GetEditTool().OnMouseWheel(*this, MyGeometry, MouseEvent);
		if (Reply.IsEventHandled())
		{
			return Reply;
		}
	}

	// Then the time slider
	FReply Reply = TimeSliderController->OnMouseWheel( SharedThis(this), MyGeometry, MouseEvent );
	if (Reply.IsEventHandled())
	{
		return Reply;
	}

	// Failing that, we'll just scroll vertically
	TreeView.Pin()->ScrollByDelta(WheelScrollAmount * -MouseEvent.GetWheelDelta());
	return FReply::Handled();
}
FReply SPaperEditorViewport::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	// Did the user move the cursor sufficiently far, or is it in a dead zone?
	// In Dead zone     - implies actions like summoning context menus and general clicking.
	// Out of Dead Zone - implies dragging actions like moving nodes and marquee selection.
	const bool bCursorInDeadZone = TotalMouseDelta <= FSlateApplication::Get().GetDragTriggerDistance();

	if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
	{
		FReply ReplyState = FReply::Handled();

		if (HasMouseCapture())
		{
			FSlateRect ThisPanelScreenSpaceRect = MyGeometry.GetClippingRect();
			const FVector2D ScreenSpaceCursorPos = MyGeometry.LocalToAbsolute( GraphCoordToPanelCoord( SoftwareCursorPosition ) );

			FIntPoint BestPositionInViewport(
				FMath::RoundToInt( FMath::Clamp( ScreenSpaceCursorPos.X, ThisPanelScreenSpaceRect.Left, ThisPanelScreenSpaceRect.Right ) ),
				FMath::RoundToInt( FMath::Clamp( ScreenSpaceCursorPos.Y, ThisPanelScreenSpaceRect.Top, ThisPanelScreenSpaceRect.Bottom ) )
				);

			if (!bCursorInDeadZone)
			{
				ReplyState.SetMousePos(BestPositionInViewport);
			}
		}

		TSharedPtr<SWidget> WidgetToFocus;
		if (bCursorInDeadZone)
		{
			//WidgetToFocus = OnSummonContextMenu(MyGeometry, MouseEvent);
		}

		bShowSoftwareCursor = false;

		bIsPanning = false;
		return (WidgetToFocus.IsValid())
			? ReplyState.ReleaseMouseCapture().SetUserFocus(WidgetToFocus.ToSharedRef(), EFocusCause::SetDirectly)
			: ReplyState.ReleaseMouseCapture();
	}
	else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		if (OnHandleLeftMouseRelease(MyGeometry, MouseEvent))
		{

		}
		else if (bCursorInDeadZone)
		{
			//@TODO: Move to selection manager
// 			if ( NodeUnderMousePtr.IsValid() )
// 			{
// 				// We clicked on a node!
// 				TSharedRef<SNode> NodeWidgetUnderMouse = NodeUnderMousePtr.Pin().ToSharedRef();
// 
// 				SelectionManager.ClickedOnNode(NodeWidgetUnderMouse->GetObjectBeingDisplayed(), MouseEvent);
// 
// 				// We're done interacting with this node.
// 				NodeUnderMousePtr.Reset();
// 			}
// 			else 
			if (HasMouseCapture())
 			{
 				// We clicked on the panel background

				//@TODO: There isn't a marquee operation for clear, need to signal to remove existing sets too!
				//Marquee.End();
 				//OnSelectionChanged.ExecuteIfBound(Marquee, false);
 			}
		}
		else if (Marquee.IsValid())
		{
			//ApplyMarqueeSelection(Marquee, SelectionManager.SelectedNodes, SelectionManager.SelectedNodes);
			//SelectionManager.OnSelectionChanged.ExecuteIfBound(SelectionManager.SelectedNodes);
			OnSelectionChanged.ExecuteIfBound(Marquee, true);
		}

		// The existing marquee operation ended; reset it.
		Marquee = FMarqueeOperation();

		if (bIsPanning)
		{
			// We have released the left mouse button. But we're still panning
			// (i.e. RIGHT MOUSE is down), so we want to hold on to capturing mouse input.
			return FReply::Handled();
		}
		else
		{
			// We aren't panning, so we can release the mouse capture.
			return FReply::Handled().ReleaseMouseCapture();
		}	
	}

	return FReply::Unhandled();	
}
Exemple #26
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;
}