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();
}
FReply SAnimationOutlinerTreeNode::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && DisplayNode->IsSelectable() )
	{
		bool bSelected = DisplayNode->IsSelected();

		if( MouseEvent.IsControlDown() )
		{
			const bool bDeselectOtherNodes = false;
			// Select the node if we were clicked on
			DisplayNode->SetSelectionState( !bSelected, bDeselectOtherNodes );
		}
		else
		{
			const bool bDeselectOtherNodes = true;
			// Select the node if we were clicked on
			DisplayNode->SetSelectionState( true, bDeselectOtherNodes );
		}

		OnSelectionChanged.ExecuteIfBound( DisplayNode );
		return FReply::Handled();
	}
	else if( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton )
	{
		return FReply::Handled().CaptureMouse(SharedThis(this));
	}

	return FReply::Unhandled();
}
FReply SSequencerSectionAreaView::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	// Clear selected sections
	if( !MouseEvent.IsControlDown() )
	{
		GetSequencer().ClearSectionSelection();
	}

	return FReply::Handled();
}
Exemple #4
0
void SSection::HandleSectionSelection( const FPointerEvent& MouseEvent )
{
	if( !MouseEvent.IsControlDown() )
	{
		GetSequencer().GetSelection().EmptySelectedSections();
	}

	// handle selecting sections 
	UMovieSceneSection* Section = SectionInterface->GetSectionObject();
	GetSequencer().GetSelection().AddToSelection(Section);
}
Exemple #5
0
void SSection::HandleKeySelection( const FSelectedKey& Key, const FPointerEvent& MouseEvent, bool bSelectDueToDrag )
{
	if( Key.IsValid() )
	{
		// Clear previous key selection if:
		// we are selecting due to drag and the key being dragged is not selected or control is not down
		bool bShouldClearSelectionDueToDrag =  bSelectDueToDrag ? !GetSequencer().GetSelection().IsSelected( Key ) : true;
		
		// Keep key selection if right clicking to bring up a menu and the current key is selected
		bool bKeepKeySelection = MouseEvent.GetEffectingButton() == EKeys::RightMouseButton && GetSequencer().GetSelection().IsSelected( Key );

		if( (!MouseEvent.IsControlDown() && bShouldClearSelectionDueToDrag) && !bKeepKeySelection )
		{
			GetSequencer().GetSelection().EmptySelectedKeys();
		}
		GetSequencer().GetSelection().AddToSelection( Key );
	}
}
FReply SFlipbookTimeline::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (MouseEvent.IsControlDown())
	{
		const float DirectionScale = 0.08f;
		const float MinFrameSize = 16.0f;
		const float Direction = MouseEvent.GetWheelDelta();
		const float NewUnitsPerFrame = FMath::Max(MinFrameSize, SlateUnitsPerFrame * (1.0f + Direction * DirectionScale));
		SlateUnitsPerFrame = NewUnitsPerFrame;
		
		CheckForRebuild(/*bRebuildAll=*/ true);

		return FReply::Handled();
	}
	else
	{
		return FReply::Unhandled();
	}
}
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();
}
	virtual FReply OnMouseButtonUp(const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent) override
	{
		if (!InMouseEvent.IsControlDown())
		{
			return SCheckBox::OnMouseButtonUp(InMyGeometry, InMouseEvent);
		}
		
		if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
		{
			bIsPressed = false;

			if (IsHovered() && HasMouseCapture())
			{
				if (OnLayerCtrlClicked.IsBound())
				{
					return OnLayerCtrlClicked.Execute();
				}
			}
		}

		return FReply::Handled().ReleaseMouseCapture();
	}
FReply STableViewBase::OnMouseWheel( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	if( !MouseEvent.IsControlDown() )
	{
		// Make sure scroll velocity is cleared so it doesn't fight with the mouse wheel input
		this->InertialScrollManager.ClearScrollVelocity();

		const float AmountScrolledInItems = this->ScrollBy( MyGeometry, -MouseEvent.GetWheelDelta()*WheelScrollAmount, EAllowOverscroll::No );

		switch ( ConsumeMouseWheel )
		{
		case EConsumeMouseWheel::Always:
			return FReply::Handled();
		case EConsumeMouseWheel::WhenScrollingPossible: //default behavior
		default:
			if ( FMath::Abs( AmountScrolledInItems ) > 0.0f )
			{
				return FReply::Handled();
			}
		}
		
	}
	return FReply::Unhandled();
}
Exemple #10
0
FReply SGraphPin::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
{
	bIsMovingLinks = MouseEvent.IsControlDown() && (GraphPinObj->LinkedTo.Num() > 0);

	return FReply::Unhandled();
}
Exemple #11
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();
}
void FResizeSection::OnDrag( const FPointerEvent& MouseEvent, const FVector2D& LocalMousePos, const FTimeToPixel& TimeToPixelConverter, TSharedPtr<FTrackNode> SequencerNode )
{
	bool bIsDilating = MouseEvent.IsControlDown();

	if( Section.IsValid() )
	{
		// Convert the current mouse position to a time
		float NewTime = TimeToPixelConverter.PixelToTime( LocalMousePos.X );

		// Find the borders of where you can drag to
		TRange<float> SectionBoundaries = GetSectionBoundaries(Section.Get(), SequencerNode);
		
		// Snapping
		if ( Settings->GetIsSnapEnabled() )
		{
			bool bSnappedToSection = false;
			if ( Settings->GetSnapSectionTimesToSections() )
		{
			TArray<float> TimesToSnapTo;
			GetSectionSnapTimes(TimesToSnapTo, Section.Get(), SequencerNode, bIsDilating);

			TOptional<float> NewSnappedTime = SnapToTimes(NewTime, TimesToSnapTo, TimeToPixelConverter);

			if (NewSnappedTime.IsSet())
			{
				NewTime = NewSnappedTime.GetValue();
					bSnappedToSection = true;
				}
			}

			if ( bSnappedToSection == false && Settings->GetSnapSectionTimesToInterval() )
			{
				NewTime = Settings->SnapTimeToInterval(NewTime);
			}
		}

		if( bDraggingByEnd )
		{
			// Dragging the end of a section
			// Ensure we aren't shrinking past the start time
			NewTime = FMath::Clamp( NewTime, Section->GetStartTime(), SectionBoundaries.GetUpperBoundValue() );

			if (bIsDilating)
			{
				float NewSize = NewTime - Section->GetStartTime();
				float DilationFactor = NewSize / Section->GetTimeSize();
				Section->DilateSection(DilationFactor, Section->GetStartTime(), DraggedKeyHandles);
			}
			else
			{
				Section->SetEndTime( NewTime );
			}
		}
		else if( !bDraggingByEnd )
		{
			// Dragging the start of a section
			// Ensure we arent expanding past the end time
			NewTime = FMath::Clamp( NewTime, SectionBoundaries.GetLowerBoundValue(), Section->GetEndTime() );
			
			if (bIsDilating)
			{
				float NewSize = Section->GetEndTime() - NewTime;
				float DilationFactor = NewSize / Section->GetTimeSize();
				Section->DilateSection(DilationFactor, Section->GetEndTime(), DraggedKeyHandles);
			}
			else
			{
				Section->SetStartTime( NewTime );
			}
		}
	}
}