/** Handle a click on the specified editor viewport client */ bool FComponentVisualizerManager::HandleClick(FEditorViewportClient* InViewportClient, HHitProxy* HitProxy, const FViewportClick& Click) { bool bHandled = HandleProxyForComponentVis(InViewportClient, HitProxy, Click); if (bHandled && Click.GetKey() == EKeys::RightMouseButton) { TSharedPtr<SWidget> MenuWidget = GenerateContextMenuForComponentVis(); if (MenuWidget.IsValid()) { TSharedPtr<SEditorViewport> ViewportWidget = InViewportClient->GetEditorViewportWidget(); if (ViewportWidget.IsValid()) { FSlateApplication::Get().PushMenu( ViewportWidget.ToSharedRef(), FWidgetPath(), MenuWidget.ToSharedRef(), FSlateApplication::Get().GetCursorPos(), FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu)); return true; } } } return false; }
bool FSplineComponentVisualizer::VisProxyHandleClick(FLevelEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy, const FViewportClick& Click) { if(VisProxy && VisProxy->Component.IsValid()) { const USplineComponent* SplineComp = CastChecked<const USplineComponent>(VisProxy->Component.Get()); SplineCompPropName = GetComponentPropertyName(SplineComp); if(SplineCompPropName.IsValid()) { AActor* OldSplineOwningActor = SplineOwningActor.Get(); SplineOwningActor = SplineComp->GetOwner(); if (OldSplineOwningActor != SplineOwningActor) { // Reset selection state if we are selecting a different actor to the one previously selected ChangeSelectionState(INDEX_NONE, false); SelectedSegmentIndex = INDEX_NONE; SelectedTangentHandle = INDEX_NONE; SelectedTangentHandleType = ESelectedTangentHandle::None; } if (VisProxy->IsA(HSplineKeyProxy::StaticGetType())) { // Control point clicked HSplineKeyProxy* KeyProxy = (HSplineKeyProxy*)VisProxy; // Modify the selection state, unless right-clicking on an already selected key if (Click.GetKey() != EKeys::RightMouseButton || !SelectedKeys.Contains(KeyProxy->KeyIndex)) { ChangeSelectionState(KeyProxy->KeyIndex, InViewportClient->IsCtrlPressed()); } SelectedSegmentIndex = INDEX_NONE; SelectedTangentHandle = INDEX_NONE; SelectedTangentHandleType = ESelectedTangentHandle::None; if (LastKeyIndexSelected == INDEX_NONE) { SplineOwningActor = nullptr; return false; } CachedRotation = SplineComp->GetQuaternionAtSplinePoint(LastKeyIndexSelected, ESplineCoordinateSpace::World); return true; } else if (VisProxy->IsA(HSplineSegmentProxy::StaticGetType())) { // Spline segment clicked // Divide segment into subsegments and test each subsegment against ray representing click position and camera direction. // Closest encounter with the spline determines the spline position. const int32 NumSubdivisions = 16; HSplineSegmentProxy* SegmentProxy = (HSplineSegmentProxy*)VisProxy; ChangeSelectionState(SegmentProxy->SegmentIndex, InViewportClient->IsCtrlPressed()); SelectedSegmentIndex = SegmentProxy->SegmentIndex; SelectedTangentHandle = INDEX_NONE; SelectedTangentHandleType = ESelectedTangentHandle::None; if (LastKeyIndexSelected == INDEX_NONE) { SplineOwningActor = nullptr; return false; } CachedRotation = SplineComp->GetQuaternionAtSplinePoint(LastKeyIndexSelected, ESplineCoordinateSpace::World); float SubsegmentStartKey = static_cast<float>(SelectedSegmentIndex); FVector SubsegmentStart = SplineComp->GetLocationAtSplineInputKey(SubsegmentStartKey, ESplineCoordinateSpace::World); float ClosestDistance = TNumericLimits<float>::Max(); FVector BestLocation = SubsegmentStart; for (int32 Step = 1; Step < NumSubdivisions; Step++) { const float SubsegmentEndKey = SelectedSegmentIndex + Step / static_cast<float>(NumSubdivisions); const FVector SubsegmentEnd = SplineComp->GetLocationAtSplineInputKey(SubsegmentEndKey, ESplineCoordinateSpace::World); FVector SplineClosest; FVector RayClosest; FMath::SegmentDistToSegmentSafe(SubsegmentStart, SubsegmentEnd, Click.GetOrigin(), Click.GetOrigin() + Click.GetDirection() * 50000.0f, SplineClosest, RayClosest); const float Distance = FVector::DistSquared(SplineClosest, RayClosest); if (Distance < ClosestDistance) { ClosestDistance = Distance; BestLocation = SplineClosest; } SubsegmentStartKey = SubsegmentEndKey; SubsegmentStart = SubsegmentEnd; } SelectedSplinePosition = BestLocation; return true; } else if (VisProxy->IsA(HSplineTangentHandleProxy::StaticGetType())) { // Tangent handle clicked HSplineTangentHandleProxy* KeyProxy = (HSplineTangentHandleProxy*)VisProxy; // Note: don't change key selection when a tangent handle is clicked SelectedSegmentIndex = INDEX_NONE; SelectedTangentHandle = KeyProxy->KeyIndex; SelectedTangentHandleType = KeyProxy->bArriveTangent ? ESelectedTangentHandle::Arrive : ESelectedTangentHandle::Leave; CachedRotation = SplineComp->GetQuaternionAtSplinePoint(SelectedTangentHandle, ESplineCoordinateSpace::World); return true; } } else { SplineOwningActor = nullptr; } } return false; }
bool FPlacementMode::HandleClick(FEditorViewportClient* InViewportClient, HHitProxy *HitProxy, const FViewportClick &Click ) { bool Handled = false; if ( IsCurrentlyPlacing() ) { if ( Click.GetKey() == EKeys::LeftMouseButton ) { TArray< UObject* > Assets; for (int Index = 0; Index < AssetsToPlace.Num(); Index++) { if ( AssetsToPlace[Index].IsValid() ) { Assets.Add( AssetsToPlace[Index].Get() ); } } TArray<AActor*> OutNewActors; const bool bCreateDropPreview = false; const bool SelectActor = false; const FViewport* const Viewport = Click.GetViewportClient()->Viewport; bool AllAssetsCanBeDropped = true; // Determine if we can drop the assets for ( auto AssetIt = Assets.CreateConstIterator(); AssetIt; ++AssetIt ) { UObject* Asset = *AssetIt; FDropQuery DropResult = InViewportClient->CanDropObjectsAtCoordinates( Viewport->GetMouseX(), Viewport->GetMouseY(), FAssetData( Asset ) ); if ( !DropResult.bCanDrop ) { // At least one of the assets can't be dropped. InViewportClient->DestroyDropPreviewActors(); AllAssetsCanBeDropped = false; CreatedPreviewActors = false; } } if ( AllAssetsCanBeDropped ) { if ( !Click.IsControlDown() ) { ClearAssetsToPlace(); IPlacementModeModule::Get().BroadcastStoppedPlacing( true ); InViewportClient->SetRequiredCursorOverride( true, EMouseCursor::GrabHand ); } InViewportClient->DropObjectsAtCoordinates( Viewport->GetMouseX(), Viewport->GetMouseY(), Assets, OutNewActors, false, bCreateDropPreview, SelectActor, PlacementFactory.Get() ); for (int Index = 0; Index < OutNewActors.Num(); Index++) { if ( OutNewActors[Index] != NULL ) { PlacedActorsThisTrackingSession = true; PlacedActors.Add( OutNewActors[Index] ); } } if ( !Click.IsControlDown() ) { SelectPlacedActors(); ClearAssetsToPlace(); } Handled = true; } } else { InViewportClient->DestroyDropPreviewActors(); CreatedPreviewActors = false; StopPlacing(); } } if ( !Handled ) { Handled = FEdMode::HandleClick(InViewportClient, HitProxy, Click); } return Handled; }