153 lines
5.4 KiB
C++
153 lines
5.4 KiB
C++
////////////////////////////////////////////////////////////
|
|
//
|
|
// 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;
|
|
|
|
// Knowing whether the slot is under construction helps us to work
|
|
// around some bugs in Unreal. See below.
|
|
bool SlotUnderConstruction = true;
|
|
|
|
// Reliable version of SetZOrder. There is a bug in the normal version of
|
|
// SetZOrder: it crashes if you use it during OnConstruct. We have a
|
|
// workaround, but it requires using a different getter and setter.
|
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Input Mode")
|
|
void SetZOrderReliable(int32 Order);
|
|
|
|
// Reliable version of GetZOrder. There is a bug in the normal version of
|
|
// SetZOrder: it crashes if you use it during OnConstruct. We have a
|
|
// workaround, but it requires using a different getter and setter.
|
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Input Mode")
|
|
int32 GetZOrderReliable();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//
|
|
// 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<UlxRootCanvasSlot*> 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()
|
|
};
|