diff --git a/Source/JavascriptEditor/JavascriptEdMode.cpp b/Source/JavascriptEditor/JavascriptEdMode.cpp index 01f4bf8d..a8e68e44 100644 --- a/Source/JavascriptEditor/JavascriptEdMode.cpp +++ b/Source/JavascriptEditor/JavascriptEdMode.cpp @@ -12,23 +12,23 @@ PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS /** Util to find named canvas in transient package, and create if not found */ static UCanvas* GetCanvasByName(FName CanvasName) { - // Cache to avoid FString/FName conversions/compares - static TMap CanvasMap; - UCanvas** FoundCanvas = CanvasMap.Find(CanvasName); - if (!FoundCanvas) - { - UCanvas* CanvasObject = FindObject(GetTransientPackage(), *CanvasName.ToString()); - if (!CanvasObject) - { - CanvasObject = NewObject(GetTransientPackage(), CanvasName); - CanvasObject->AddToRoot(); - } - - CanvasMap.Add(CanvasName, CanvasObject); - return CanvasObject; - } - - return *FoundCanvas; + // Cache to avoid FString/FName conversions/compares + static TMap CanvasMap; + UCanvas** FoundCanvas = CanvasMap.Find(CanvasName); + if (!FoundCanvas) + { + UCanvas* CanvasObject = FindObject(GetTransientPackage(), *CanvasName.ToString()); + if (!CanvasObject) + { + CanvasObject = NewObject(GetTransientPackage(), CanvasName); + CanvasObject->AddToRoot(); + } + + CanvasMap.Add(CanvasName, CanvasObject); + return CanvasObject; + } + + return *FoundCanvas; } class FJavascriptEdToolkit : public FModeToolkit, public FGCObject @@ -386,4 +386,4 @@ void UJavascriptEdMode::Unregister() #endif -PRAGMA_ENABLE_SHADOW_VARIABLE_WARNINGS \ No newline at end of file +PRAGMA_ENABLE_SHADOW_VARIABLE_WARNINGS diff --git a/Source/JavascriptEditor/JavascriptEditorViewport.cpp b/Source/JavascriptEditor/JavascriptEditorViewport.cpp index bcad4f0c..60846b03 100644 --- a/Source/JavascriptEditor/JavascriptEditorViewport.cpp +++ b/Source/JavascriptEditor/JavascriptEditorViewport.cpp @@ -8,6 +8,25 @@ PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS + +class FCanvasOwner : public FGCObject +{ + +public: + FCanvasOwner(): FGCObject() + { + Canvas = nullptr; + } + + virtual void AddReferencedObjects(FReferenceCollector& Collector) override + { + Collector.AddReferencedObject(Canvas); + } + +public: + UCanvas* Canvas; +}; + #if WITH_EDITOR class FJavascriptEditorViewportClient : public FEditorViewportClient { @@ -49,6 +68,60 @@ class FJavascriptEditorViewportClient : public FEditorViewportClient } } + virtual bool InputKey(FViewport* Viewport, int32 ControllerId, FKey Key, EInputEvent Event, float AmountDepressed = 1.f, bool bGamepad = false) + { + FEditorViewportClient::InputKey(Viewport, ControllerId, Key, Event, AmountDepressed, bGamepad); + if (Widget.IsValid() && Widget->OnInputKey.IsBound()) + { + return Widget->OnInputKey.Execute(ControllerId, Key, Event, Widget.Get()); + } + else + { + return false; + } + } + + virtual bool InputAxis(FViewport* Viewport, int32 ControllerId, FKey Key, float Delta, float DeltaTime, int32 NumSamples = 1, bool bGamepad = false) override + { + FEditorViewportClient::InputAxis(Viewport, ControllerId, Key, Delta, DeltaTime, NumSamples, bGamepad); + if (Widget.IsValid() && Widget->OnInputAxis.IsBound()) + { + return Widget->OnInputAxis.Execute(ControllerId, Key, Delta, DeltaTime, Widget.Get()); + } + else + { + return false; + } + } + + virtual void MouseEnter(FViewport* Viewport, int32 x, int32 y) override + { + + FEditorViewportClient::MouseEnter(Viewport, x, y); + if (Widget.IsValid() && Widget->OnMouseEnter.IsBound()) + { + Widget->OnMouseEnter.Execute(x, y, Widget.Get()); + } + } + + virtual void MouseMove(FViewport* Viewport, int32 x, int32 y) override + { + FEditorViewportClient::MouseMove(Viewport, x, y); + if (Widget.IsValid() && Widget->OnMouseMove.IsBound()) + { + Widget->OnMouseMove.Execute(x, y, Widget.Get()); + } + } + + virtual void MouseLeave(FViewport* Viewport) override + { + FEditorViewportClient::MouseLeave(Viewport); + if (Widget.IsValid() && Widget->OnMouseLeave.IsBound()) + { + Widget->OnMouseLeave.Execute(Widget.Get()); + } + } + virtual bool InputWidgetDelta(FViewport* InViewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale) override { if (Widget.IsValid() && Widget->OnInputWidgetDelta.IsBound()) @@ -70,6 +143,26 @@ class FJavascriptEditorViewportClient : public FEditorViewportClient Widget->OnDraw.Execute(FJavascriptPDI(PDI),Widget.Get()); } } + + virtual void DrawCanvas(FViewport& InViewport, FSceneView& View, FCanvas& Canvas) override + { + FEditorViewportClient::DrawCanvas(InViewport, View, Canvas); + + if (Widget.IsValid() && Widget->OnDrawCanvas.IsBound()) + { + if(CanvasOwner.Canvas == nullptr){ + CanvasOwner.Canvas = NewObject(Widget.Get()); + } + + CanvasOwner.Canvas->Canvas = &Canvas; + CanvasOwner.Canvas->Init(View.UnscaledViewRect.Width(), View.UnscaledViewRect.Height(), const_cast(&View)); + CanvasOwner.Canvas->ApplySafeZoneTransform(); + + Widget->OnDrawCanvas.Execute(CanvasOwner.Canvas, Widget.Get()); + + CanvasOwner.Canvas->PopSafeZoneTransform(); + } + } virtual FWidget::EWidgetMode GetWidgetMode() const override { @@ -141,6 +234,9 @@ class FJavascriptEditorViewportClient : public FEditorViewportClient FPostProcessSettings PostProcessSettings; float PostProcessSettingsWeight; FLinearColor BackgroundColor; + +private: + FCanvasOwner CanvasOwner; }; class SAutoRefreshEditorViewport : public SEditorViewport @@ -223,6 +319,16 @@ class SAutoRefreshEditorViewport : public SEditorViewport return EditorViewportClient->GetCameraSpeedSetting(); } + void SetViewportType(ELevelViewportType InViewportType) + { + EditorViewportClient->SetViewportType(InViewportType); + } + + void SetViewMode(EViewModeIndex InViewModeIndex) + { + EditorViewportClient->SetViewMode(InViewModeIndex); + } + void OverridePostProcessSettings(const FPostProcessSettings& PostProcessSettings, float Weight) { EditorViewportClient->PostProcessSettings = PostProcessSettings; @@ -259,7 +365,13 @@ class SAutoRefreshEditorViewport : public SEditorViewport void SetWidgetMode(EJavascriptWidgetMode WidgetMode) { EditorViewportClient->SetWidgetMode(WidgetMode == EJavascriptWidgetMode::WM_None ? FWidget::WM_None : (FWidget::EWidgetMode)WidgetMode); - } + } + + EJavascriptWidgetMode GetWidgetMode() + { + FWidget::EWidgetMode WidgetMode = EditorViewportClient->GetWidgetMode(); + return FWidget::WM_None ? EJavascriptWidgetMode::WM_None : (EJavascriptWidgetMode)WidgetMode; + } FString GetEngineShowFlags() { @@ -500,6 +612,55 @@ void UJavascriptEditorViewport::SetWidgetMode(EJavascriptWidgetMode WidgetMode) } } +EJavascriptWidgetMode UJavascriptEditorViewport::GetWidgetMode() +{ + if (ViewportWidget.IsValid()) + { + return ViewportWidget->GetWidgetMode(); + } + else { + return EJavascriptWidgetMode::WM_None; + } +} + +void UJavascriptEditorViewport::SetViewportType(ELevelViewportType InViewportType) +{ + if (ViewportWidget.IsValid()) + { + ViewportWidget->SetViewportType(InViewportType); + } +} + +void UJavascriptEditorViewport::SetViewMode(EViewModeIndex InViewModeIndex) +{ + if (ViewportWidget.IsValid()) + { + ViewportWidget->SetViewMode(InViewModeIndex); + } +} + +void UJavascriptEditorViewport::DeprojectScreenToWorld(const FVector2D &ScreenPosition, FVector &OutRayOrigin, FVector& OutRayDirection) +{ + if (ViewportWidget.IsValid()) + { + FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( ViewportWidget->EditorViewportClient->Viewport, ViewportWidget->EditorViewportClient->GetScene(), ViewportWidget->EditorViewportClient->EngineShowFlags )); + FSceneView* View = ViewportWidget->EditorViewportClient->CalcSceneView(&ViewFamily); + + FSceneView::DeprojectScreenToWorld(ScreenPosition, View->ViewRect, View->ViewMatrices.GetInvViewProjMatrix(), OutRayOrigin, OutRayDirection); + } +} + +void UJavascriptEditorViewport::ProjectWorldToScreen(const FVector &WorldPosition, FVector2D &OutScreenPosition) +{ + if (ViewportWidget.IsValid()) + { + FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( ViewportWidget->EditorViewportClient->Viewport, ViewportWidget->EditorViewportClient->GetScene(), ViewportWidget->EditorViewportClient->EngineShowFlags )); + FSceneView* View = ViewportWidget->EditorViewportClient->CalcSceneView(&ViewFamily); + + FSceneView::ProjectWorldToScreen(WorldPosition, View->ViewRect, View->ViewMatrices.GetViewProjMatrix(), OutScreenPosition); + } +} + FString UJavascriptEditorViewport::GetEngineShowFlags() { if (ViewportWidget.IsValid()) @@ -526,4 +687,4 @@ bool UJavascriptEditorViewport::SetEngineShowFlags(const FString& In) PRAGMA_ENABLE_SHADOW_VARIABLE_WARNINGS -#undef LOCTEXT_NAMESPACE \ No newline at end of file +#undef LOCTEXT_NAMESPACE diff --git a/Source/JavascriptEditor/JavascriptEditorViewport.h b/Source/JavascriptEditor/JavascriptEditorViewport.h index 202fb496..8634369a 100644 --- a/Source/JavascriptEditor/JavascriptEditorViewport.h +++ b/Source/JavascriptEditor/JavascriptEditorViewport.h @@ -25,7 +25,13 @@ class JAVASCRIPTEDITOR_API UJavascriptEditorViewport : public UPanelWidget DECLARE_DYNAMIC_DELEGATE_FourParams(FOnViewportTrackingStarted, const FJavascriptInputEventState&, InputState, bool, bIsDraggingWidget, bool, bNudge, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_OneParam(FOnViewportTrackingStopped, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_RetVal_FourParams(bool, FOnInputWidgetDelta, FVector&, Drag, FRotator&, Rot, FVector&, Scale, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_RetVal_FourParams(bool, FOnInputKey, int32, ControllerId, FKey, Key, EInputEvent, Event, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_RetVal_FiveParams(bool, FOnInputAxis, int32, ControllerId, FKey, Key, float, Delta, float, DeltaTime, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_RetVal_ThreeParams(bool, FOnMouseEnter, int32, x, int32, y, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_RetVal_ThreeParams(bool, FOnMouseMove, int32, x, int32, y, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(bool, FOnMouseLeave, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnViewportDraw, const FJavascriptPDI&, PDI, UJavascriptEditorViewport*, Instance); + DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnViewportDrawCanvas, UCanvas*, Canvas, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(FVector, FOnGetWidgetLocation, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(FRotator, FOnGetWidgetRotation, UJavascriptEditorViewport*, Instance); DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(EJavascriptWidgetMode, FOnGetWidgetMode, UJavascriptEditorViewport*, Instance); @@ -42,9 +48,27 @@ class JAVASCRIPTEDITOR_API UJavascriptEditorViewport : public UPanelWidget UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) FOnInputWidgetDelta OnInputWidgetDelta; + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnInputKey OnInputKey; + + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnInputAxis OnInputAxis; + + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnMouseEnter OnMouseEnter; + + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnMouseMove OnMouseMove; + + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnMouseLeave OnMouseLeave; + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) FOnViewportDraw OnDraw; + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) + FOnViewportDrawCanvas OnDrawCanvas; + UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) FOnGetWidgetLocation OnGetWidgetLocation; @@ -53,7 +77,7 @@ class JAVASCRIPTEDITOR_API UJavascriptEditorViewport : public UPanelWidget UPROPERTY(EditAnywhere, Category = Events, meta = (IsBindableEvent = "True")) FOnGetWidgetMode OnGetWidgetMode; - + UFUNCTION(BlueprintCallable, Category = "Viewport") UWorld* GetViewportWorld() const; @@ -107,13 +131,28 @@ class JAVASCRIPTEDITOR_API UJavascriptEditorViewport : public UPanelWidget UFUNCTION(BlueprintCallable, Category = "Viewport") void SetWidgetMode(EJavascriptWidgetMode WidgetMode); - + + UFUNCTION(BlueprintCallable, Category = "Viewport") + EJavascriptWidgetMode GetWidgetMode(); + UFUNCTION(BlueprintCallable, Category = "Viewport") FString GetEngineShowFlags(); UFUNCTION(BlueprintCallable, Category = "Viewport") bool SetEngineShowFlags(const FString& In); + UFUNCTION(BlueprintCallable, Category = "Viewport") + void SetViewportType(ELevelViewportType InViewportType); + + UFUNCTION(BlueprintCallable, Category = "Viewport") + void SetViewMode(EViewModeIndex InViewModeIndex); + + UFUNCTION(BlueprintCallable, Category = "Viewport") + void DeprojectScreenToWorld(const FVector2D &ScreenPosition, FVector &OutRayOrigin, FVector& OutRayDirection); + + UFUNCTION(BlueprintCallable, Category = "Viewport") + void ProjectWorldToScreen(const FVector &WorldPosition, FVector2D &OutScreenPosition); + // UPanelWidget virtual UClass* GetSlotClass() const override; virtual void OnSlotAdded(UPanelSlot* Slot) override;