//////////////////////////////////////////////////////////// // // RootCanvas.h // // UlxRootCanvasPanel is a UCanvasPanel subclass whose // slots (UlxRootCanvasSlot) carry input-mode configuration // in addition to layout. The PlayerController scans these // slots, sorted by ZOrder, to arbitrate pointer visibility, // capture, focus, and input-component blocking for // top-level widgets. ZOrder therefore serves double duty: // it determines draw order AND input priority. // //////////////////////////////////////////////////////////// #pragma once #include "CoreMinimal.h" #include "Common.h" #include "Blueprint/UserWidget.h" #include "Components/CanvasPanel.h" #include "Components/CanvasPanelSlot.h" #include "RootCanvas.generated.h" class UWidget; //////////////////////////////////////////////////////////// // // UlxRootCanvasSlot // // Luprex provides a "window management system" for root widgets. // This system is documented in Docs/Keyboard-Focus-and-Input-Modes.md // The Root Canvas Slot is how widgets ask the window management system // to engage certain behaviors. // //////////////////////////////////////////////////////////// UCLASS() class INTEGRATION_API UlxRootCanvasSlot : public UCanvasPanelSlot { GENERATED_BODY() public: UlxRootCanvasSlot(const FObjectInitializer& ObjectInitializer); // When this window is in front, the mouse pointer is shown and the // viewport does not capture the mouse. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Input Mode") bool ShowPointer = false; // When this window is in front, this window's input component blocks // lower-priority input components in the input stack. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Input Mode") bool BlockInput = false; // If true, this widget's input component is enabled, which is to say, // that enhanced input events are enabled. If false, enhanced input // events in the Event Graph are deactivated. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Input Mode") bool EnableEnhancedInput = true; }; //////////////////////////////////////////////////////////// // // UlxRootCanvasPanel // // A UCanvasPanel that uses UlxRootCanvasSlot for its // children instead of the plain UCanvasPanelSlot. Layout // behavior is identical to UCanvasPanel; only the slot // type differs. // //////////////////////////////////////////////////////////// UCLASS() class INTEGRATION_API UlxRootCanvasPanel : public UCanvasPanel { GENERATED_BODY() public: // Convenience wrapper around AddChild that returns the // derived slot type, so callers don't have to cast. UFUNCTION() UlxRootCanvasSlot* AddChildToRootCanvas(UWidget* Content); // Find children of type UserWidget. Return them in a sorted // order, with the highest Zorder first. TArray GetSortedUserWidgets(); // Return the largest ZOrder across all slots, or 0 if empty. // Used as the basis for placing new widgets on top. int32 GetMaxZOrder() const; // This function updates several window-management-related properties // which are stored in the UserWidget and the lxRootCanvasSlot. Note that // it is perfectly legal to edit these properties by other means: this // function is one of many valid setters. See the documentation in // Docs/Keyboard-Focus-and-Input-Modes.md for information about how Luprex // window management works. UFUNCTION(BlueprintCallable, Category = "Luprex|Window Management", meta = (DefaultToSelf = "Widget", EnableEnhancedInput = "true")) static void SetWidgetWindowManagement(class UUserWidget *Widget, bool ShowPointer, bool BlockInput, bool EnableEnhancedInput, bool BringToFront, UWidget *DesiredFocusWidget); // Fetch the UlxRootCanvasSlot for a widget that is parented to a // UlxRootCanvasPanel. Returns nullptr via the WrongType exec pin // if the widget isn't a root widget (no slot, or slot is not a // UlxRootCanvasSlot). UFUNCTION(BlueprintCallable, Category = "Luprex|Window Management", meta = (DefaultToSelf = "Widget", ExpandEnumAsExecs = "Result")) static UlxRootCanvasSlot *GetRootCanvasSlot(class UUserWidget *Widget, ElxSuccessOrWrongType &Result); protected: // UPanelWidget virtual UClass* GetSlotClass() const override; }; //////////////////////////////////////////////////////////// // // UlxRootWidget // // A trivial concrete UUserWidget subclass used by the // PlayerController to host the root UlxRootCanvasPanel. // UUserWidget itself is marked Abstract in UMG, so we need // a non-abstract class to instantiate. // //////////////////////////////////////////////////////////// UCLASS() class INTEGRATION_API UlxRootWidget : public UUserWidget { GENERATED_BODY() };