FReply FCEFWebBrowserWindow::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup)
{
	FReply Reply = FReply::Unhandled();
	if(IsValid())
	{
		// The original delta is reduced so this should bring it back to what CEF expects
		const float SpinFactor = 50.0f;
		const float TrueDelta = MouseEvent.GetWheelDelta() * SpinFactor;
		CefMouseEvent Event = GetCefMouseEvent(MyGeometry, MouseEvent, bIsPopup);
		InternalCefBrowser->GetHost()->SendMouseWheelEvent(Event,
															MouseEvent.IsShiftDown() ? TrueDelta : 0,
															!MouseEvent.IsShiftDown() ? TrueDelta : 0);
		Reply = FReply::Handled();
	}
	return Reply;
}
Esempio n. 2
0
/**
 * The system calls this method to notify the widget that a mouse button was release within it. This event is bubbled.
 *
 * @param MyGeometry The Geometry of the widget receiving the event
 * @param MouseEvent Information about the input event
 *
 * @return Whether the event was handled along with possible requests for the system to take action.
 */
FReply SGraphPin::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if (MouseEvent.IsShiftDown())
	{
		// Either store the shift-clicked pin or attempt to connect it if already stored
		TSharedPtr<SGraphPanel> OwnerPanelPtr = OwnerNodePtr.Pin()->GetOwnerPanel();
		check(OwnerPanelPtr.IsValid());
		if (OwnerPanelPtr->MarkedPin.IsValid())
		{
			// avoid creating transaction if toggling the marked pin
			if (!OwnerPanelPtr->MarkedPin.HasSameObject(this))
			{
				const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "GraphEd_CreateConnection", "Create Pin Link") );
				TryHandlePinConnection(*OwnerPanelPtr->MarkedPin.Pin());
			}
			OwnerPanelPtr->MarkedPin.Reset();
		}
		else
		{
			OwnerPanelPtr->MarkedPin = SharedThis(this);
		}
		return FReply::Handled();
	}
	return FReply::Unhandled();
}
Esempio n. 3
0
void FWebBrowserWindow::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if(IsValid())
	{
		// The original delta is reduced so this should bring it back to what CEF expects
		const float SpinFactor = 120.0f;
		const float TrueDelta = MouseEvent.GetWheelDelta() * SpinFactor;
		CefMouseEvent Event;
		FVector2D LocalPos = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
		Event.x = LocalPos.X;
		Event.y = LocalPos.Y;
		Event.modifiers = GetCefMouseModifiers(MouseEvent);
		
		InternalCefBrowser->GetHost()->SendMouseWheelEvent(Event,
															MouseEvent.IsShiftDown() ? TrueDelta : 0,
															!MouseEvent.IsShiftDown() ? TrueDelta : 0);
	}
}
FReply FSequencerTimeSliderController::OnMouseWheel( SWidget& WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	TOptional<TRange<float>> NewTargetRange;

	float MouseFractionX = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()).X / MyGeometry.GetLocalSize().X;
	if ( TimeSliderArgs.AllowZoom && MouseEvent.IsControlDown() )
	{
		const float ZoomDelta = -0.2f * MouseEvent.GetWheelDelta();
		if (ZoomByDelta(ZoomDelta, MouseFractionX))
		{
			return FReply::Handled();
		}
	}
	else if (MouseEvent.IsShiftDown())
	{
		PanByDelta(-MouseEvent.GetWheelDelta());
		return FReply::Handled();
	}
	
	return FReply::Unhandled();
}
Esempio n. 5
0
TSharedPtr<SWidget> SGraphPanel::OnSummonContextMenu(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	//Editability is up to the user to consider for menu options
	{
		// If we didn't drag very far, summon a context menu.
		// Figure out what's under the mouse: Node, Pin or just the Panel, and summon the context menu for that.
		UEdGraphNode* NodeUnderCursor = NULL;
		UEdGraphPin* PinUnderCursor = NULL;
		{
			FArrangedChildren ArrangedNodes(EVisibility::Visible);
			this->ArrangeChildrenForContextMenuSummon(MyGeometry, ArrangedNodes);
			const int32 HoveredNodeIndex = SWidget::FindChildUnderMouse( ArrangedNodes, MouseEvent );
			if (HoveredNodeIndex != INDEX_NONE)
			{
				const FArrangedWidget& HoveredNode = ArrangedNodes[HoveredNodeIndex];
				TSharedRef<SGraphNode> GraphNode = StaticCastSharedRef<SGraphNode>(HoveredNode.Widget);
				TSharedPtr<SGraphNode> GraphSubNode = GraphNode->GetNodeUnderMouse(HoveredNode.Geometry, MouseEvent);
				GraphNode = GraphSubNode.IsValid() ? GraphSubNode.ToSharedRef() : GraphNode;
				NodeUnderCursor = GraphNode->GetNodeObj();

				// Selection should switch to this code if it isn't already selected.
				// When multiple nodes are selected, we do nothing, provided that the
				// node for which the context menu is being created is in the selection set.
				if (!SelectionManager.IsNodeSelected(GraphNode->GetObjectBeingDisplayed()))
				{
					SelectionManager.SelectSingleNode(GraphNode->GetObjectBeingDisplayed());
				}

				const TSharedPtr<SGraphPin> HoveredPin = GraphNode->GetHoveredPin( HoveredNode.Geometry, MouseEvent );
				if (HoveredPin.IsValid())
				{
					PinUnderCursor = HoveredPin->GetPinObj();
				}
			}				
		}

		const FVector2D NodeAddPosition = PanelCoordToGraphCoord( MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()) );
		TArray<UEdGraphPin*> NoSourcePins;

		return SummonContextMenu(MouseEvent.GetScreenSpacePosition(), NodeAddPosition, NodeUnderCursor, PinUnderCursor, NoSourcePins, MouseEvent.IsShiftDown());
	}

	return TSharedPtr<SWidget>();
}
Esempio n. 6
0
FReply SGraphPin::OnPinMouseDown( const FGeometry& SenderGeometry, const FPointerEvent& MouseEvent )
{
	bIsMovingLinks = false;

	if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		if (!GraphPinObj->bNotConnectable && IsEditable.Get())
		{
			if (MouseEvent.IsAltDown())
			{
				// Alt-Left clicking will break all existing connections to a pin
				const UEdGraphSchema* Schema = GraphPinObj->GetSchema();
				Schema->BreakPinLinks(*GraphPinObj, true);
				return FReply::Handled();
			}

			auto OwnerNodePinned = OwnerNodePtr.Pin();
			if (MouseEvent.IsControlDown() && (GraphPinObj->LinkedTo.Num() > 0))
			{
				// Get a reference to the owning panel widget
				check(OwnerNodePinned.IsValid());
				TSharedPtr<SGraphPanel> OwnerPanelPtr = OwnerNodePinned->GetOwnerPanel();
				check(OwnerPanelPtr.IsValid());

				// Obtain the set of all pins within the panel
				TSet<TSharedRef<SWidget> > AllPins;
				OwnerPanelPtr->GetAllPins(AllPins);

				// Construct a UEdGraphPin->SGraphPin mapping for the full pin set
				TMap< UEdGraphPin*, TSharedRef<SGraphPin> > PinToPinWidgetMap;
				for( TSet< TSharedRef<SWidget> >::TIterator ConnectorIt(AllPins); ConnectorIt; ++ConnectorIt )
				{
					const TSharedRef<SWidget>& SomePinWidget = *ConnectorIt;
					const SGraphPin& PinWidget = static_cast<const SGraphPin&>(SomePinWidget.Get());

					PinToPinWidgetMap.Add(PinWidget.GetPinObj(), StaticCastSharedRef<SGraphPin>(SomePinWidget));
				}

				// Define a local struct to temporarily store lookup information for pins that we are currently linked to
				struct LinkedToPinInfo
				{
					// Pin name string
					FString PinName;

					// A weak reference to the node object that owns the pin
					TWeakObjectPtr<UEdGraphNode> OwnerNodePtr;
				};

				// Build a lookup table containing information about the set of pins that we're currently linked to
				TArray<LinkedToPinInfo> LinkedToPinInfoArray;
				for( TArray<UEdGraphPin*>::TIterator LinkArrayIter(GetPinObj()->LinkedTo); LinkArrayIter; ++LinkArrayIter )
				{
					if (auto PinWidget = PinToPinWidgetMap.Find(*LinkArrayIter))
					{
						check((*PinWidget)->OwnerNodePtr.IsValid());

						LinkedToPinInfo PinInfo;
						PinInfo.PinName = (*PinWidget)->GetPinObj()->PinName;
						PinInfo.OwnerNodePtr = (*PinWidget)->OwnerNodePtr.Pin()->GetNodeObj();
						LinkedToPinInfoArray.Add(PinInfo);
					}
				}

				// Control-Left clicking will break all existing connections to a pin
				// Note that for some nodes, this can cause reconstruction. In that case, pins we had previously linked to may now be destroyed.
				const UEdGraphSchema* Schema = GraphPinObj->GetSchema();
				Schema->BreakPinLinks(*GraphPinObj, true);

				// Check to see if the panel has been invalidated by a graph change notification
				if (!OwnerPanelPtr->Contains(OwnerNodePinned->GetNodeObj()))
				{
					// Force the panel to update. This will cause node & pin widgets to be reinstanced to match any reconstructed node/pin object references.
					OwnerPanelPtr->Update();

					// Obtain the full set of pins again after the update
					AllPins.Empty(AllPins.Num());
					OwnerPanelPtr->GetAllPins(AllPins);

					// Rebuild the UEdGraphPin->SGraphPin mapping for the full pin set
					PinToPinWidgetMap.Empty(PinToPinWidgetMap.Num());
					for( TSet< TSharedRef<SWidget> >::TIterator ConnectorIt(AllPins); ConnectorIt; ++ConnectorIt )
					{
						const TSharedRef<SWidget>& SomePinWidget = *ConnectorIt;
						const SGraphPin& PinWidget = static_cast<const SGraphPin&>(SomePinWidget.Get());

						PinToPinWidgetMap.Add(PinWidget.GetPinObj(), StaticCastSharedRef<SGraphPin>(SomePinWidget));
					}
				}
				
				// Now iterate over our lookup table to find the instances of pin widgets that we had previously linked to
				TArray<TSharedRef<SGraphPin>> PinArray;
				for(auto LinkedToPinInfoIter = LinkedToPinInfoArray.CreateConstIterator(); LinkedToPinInfoIter; ++LinkedToPinInfoIter)
				{
					LinkedToPinInfo PinInfo = *LinkedToPinInfoIter;
					UEdGraphNode* OwnerNodeObj = PinInfo.OwnerNodePtr.Get();
					if(OwnerNodeObj != NULL)
					{
						for(auto PinIter = PinInfo.OwnerNodePtr.Get()->Pins.CreateConstIterator(); PinIter; ++PinIter)
						{
							UEdGraphPin* Pin = *PinIter;
							if(Pin->PinName == PinInfo.PinName)
							{
								if (auto pWidget = PinToPinWidgetMap.Find(Pin))
								{
									PinArray.Add(*pWidget);
								}
							}
						}
					}
				}

				if(PinArray.Num() > 0)
				{
					bIsMovingLinks = true;

					return FReply::Handled().BeginDragDrop(SpawnPinDragEvent(OwnerPanelPtr.ToSharedRef(), PinArray, /*bIsShiftOperation=*/ false));
				}
				else
				{
					// Shouldn't get here, but just in case we lose our previous links somehow after breaking them, we'll just skip the drag.
					return FReply::Handled();
				}
			}
			
			// Start a drag-drop on the pin
			if (ensure(OwnerNodePinned.IsValid()))
			{
				TArray<TSharedRef<SGraphPin>> PinArray;
				PinArray.Add(SharedThis(this));

				return FReply::Handled().BeginDragDrop(SpawnPinDragEvent(OwnerNodePinned->GetOwnerPanel().ToSharedRef(), PinArray, MouseEvent.IsShiftDown()));
			}
			else
			{
				return FReply::Unhandled();
			}
		}
		else
		{
			// It's not connectable, but we don't want anything above us to process this left click.
			return FReply::Handled();
		}
	}
	else
	{
		return FReply::Unhandled();
	}
}
FReply SAnimationOutlinerTreeNode::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && DisplayNode->IsSelectable() )
	{
		FSequencer& Sequencer = DisplayNode->GetSequencer();
		bool bSelected = Sequencer.GetSelection().IsSelected(DisplayNode.ToSharedRef());

		TArray<TSharedPtr<FSequencerDisplayNode> > AffectedNodes;
		AffectedNodes.Add(DisplayNode.ToSharedRef());

		if (MouseEvent.IsShiftDown())
		{
			FSequencerNodeTree& ParentTree = DisplayNode->GetParentTree();

			const TArray< TSharedRef<FSequencerDisplayNode> >RootNodes = ParentTree.GetRootNodes();

			// Get all nodes in order
			TArray<TSharedRef<FSequencerDisplayNode> > AllNodes;
			for (int32 i = 0; i < RootNodes.Num(); ++i)
			{
				GetAllDescendantNodes(RootNodes[i], AllNodes);
			}

			int32 FirstIndexToSelect = INT32_MAX;
			int32 LastIndexToSelect = INT32_MIN;

			for (int32 ChildIndex = 0; ChildIndex < AllNodes.Num(); ++ChildIndex)
			{
				TSharedRef<FSequencerDisplayNode> ChildNode = AllNodes[ChildIndex];

				if (ChildNode == DisplayNode.ToSharedRef() || Sequencer.GetSelection().IsSelected(ChildNode))
				{
					if (ChildIndex < FirstIndexToSelect)
					{
						FirstIndexToSelect = ChildIndex;
					}
					if (ChildIndex > LastIndexToSelect)
					{
						LastIndexToSelect = ChildIndex;
					}
				}
			}

			if (FirstIndexToSelect != INT32_MAX && LastIndexToSelect != INT32_MIN)
			{
				for (int32 ChildIndex = FirstIndexToSelect; ChildIndex <= LastIndexToSelect; ++ChildIndex)
				{
					TSharedRef<FSequencerDisplayNode> ChildNode = AllNodes[ChildIndex];

					if (!Sequencer.GetSelection().IsSelected(ChildNode))
					{
						Sequencer.GetSelection().AddToSelection(ChildNode);
						AffectedNodes.Add(ChildNode);
					}
				}
			}
		}
		else if( MouseEvent.IsControlDown() )
		{
			// Toggle selection when control is down
			if (bSelected)
			{
				Sequencer.GetSelection().RemoveFromSelection(DisplayNode.ToSharedRef());
			}
			else
			{
				Sequencer.GetSelection().AddToSelection(DisplayNode.ToSharedRef());
			}
		}
		else
		{
			// Deselect the other nodes and select this node.
			Sequencer.GetSelection().EmptySelectedOutlinerNodes();
			Sequencer.GetSelection().AddToSelection(DisplayNode.ToSharedRef());
		}

		OnSelectionChanged.ExecuteIfBound( AffectedNodes );
		return FReply::Handled();
	}

	return FReply::Unhandled();
}
Esempio n. 8
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;
}
FReply SInlineEditableTextBlock::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if( !MouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton) || MouseEvent.IsControlDown() || MouseEvent.IsShiftDown())
	{
		return FReply::Unhandled();
	}

	if(IsSelected.IsBound())
	{
		if(IsSelected.Execute() && !bIsReadOnly.Get() && !ActiveTimerHandle.IsValid())
		{
			RegisterActiveTimer(0.5f, FWidgetActiveTimerDelegate::CreateSP(this, &SInlineEditableTextBlock::TriggerEditMode));
		}
	}
	else
	{
		// The widget is not managed by another widget, so handle the mouse input and enter edit mode if ready.
		if(HasKeyboardFocus())
		{
			EnterEditingMode();
		}
		return FReply::Handled();
	}

	// Do not handle the mouse input, this will allow for drag and dropping events to trigger.
	return FReply::Unhandled();
}