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; }
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; }
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(); }
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; }