// Distributed under the MIT License (MIT) (see accompanying LICENSE file) #pragma once #include "ImGuiModuleDebug.h" #include "ImGuiModuleSettings.h" #include // Hide ImGui Widget debug in non-developer mode. #define IMGUI_WIDGET_DEBUG IMGUI_MODULE_DEVELOPER class FImGuiModuleManager; class SImGuiCanvasControl; class UImGuiInputHandler; // Slate widget for rendering ImGui output and storing Slate inputs. class SImGuiWidget : public SCompoundWidget { typedef SCompoundWidget Super; public: SLATE_BEGIN_ARGS(SImGuiWidget) {} SLATE_ARGUMENT(FImGuiModuleManager*, ModuleManager) SLATE_ARGUMENT(UGameViewportClient*, GameViewport) SLATE_ARGUMENT(int32, ContextIndex) SLATE_END_ARGS() void Construct(const FArguments& InArgs); ~SImGuiWidget(); // Get index of the context that this widget is targeting. int32 GetContextIndex() const { return ContextIndex; } //---------------------------------------------------------------------------------------------------- // SWidget overrides //---------------------------------------------------------------------------------------------------- virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; virtual bool SupportsKeyboardFocus() const override { return bInputEnabled && !IsConsoleOpened(); } virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override; virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override; virtual FReply OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override; virtual FReply OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent) override; virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override; virtual void OnFocusLost(const FFocusEvent& FocusEvent) override; virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override; virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override; virtual FReply OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override; virtual FReply OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override; private: void CreateInputHandler(const FStringClassReference& HandlerClassReference); void ReleaseInputHandler(); void RegisterImGuiSettingsDelegates(); void UnregisterImGuiSettingsDelegates(); void SetHideMouseCursor(bool bHide); bool IsConsoleOpened() const; // Update visibility based on input state. void UpdateVisibility(); // Update cursor based on input state. void UpdateMouseCursor(); ULocalPlayer* GetLocalPlayer() const; void TakeFocus(); void ReturnFocus(); // Update input state. void UpdateInputState(); void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry); void HandleWindowFocusLost(); void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo); void UpdateCanvasSize(); void UpdateCanvasControlMode(const FInputEvent& InputEvent); void OnPostImGuiUpdate(); FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const; virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override; virtual FVector2D ComputeDesiredSize(float) const override; void SetImGuiTransform(const FSlateRenderTransform& Transform) { ImGuiTransform = Transform; } #if IMGUI_WIDGET_DEBUG void OnDebugDraw(); #endif // IMGUI_WIDGET_DEBUG FImGuiModuleManager* ModuleManager = nullptr; TWeakObjectPtr GameViewport; TWeakObjectPtr InputHandler; FSlateRenderTransform ImGuiTransform; FSlateRenderTransform ImGuiRenderTransform; mutable TArray VertexBuffer; mutable TArray IndexBuffer; int32 ContextIndex = 0; FVector2D MinCanvasSize = FVector2D::ZeroVector; FVector2D CanvasSize = FVector2D::ZeroVector; bool bInputEnabled = false; bool bForegroundWindow = false; bool bHideMouseCursor = true; bool bTransparentMouseInput = false; bool bAdaptiveCanvasSize = false; bool bUpdateCanvasSize = false; bool bCanvasControlEnabled = false; TSharedPtr CanvasControlWidget; TWeakPtr PreviousUserFocusedWidget; };