#pragma once #include #include #include "UmgTypes.hpp" #include "UnrealWrapper.hpp" #include "PanelSlot.hpp" #include "CanvasPanelSlot.hpp" namespace PalUIExtension::Api { class WidgetLayoutLibrary : public UnrealWrapper { public: static auto ClassPath() -> const TCHAR* { return STR("/Script/UMG.WidgetLayoutLibrary"); } static auto CDOPath() -> const TCHAR* { return STR("/Script/UMG.Default__WidgetLayoutLibrary"); } static auto DebugTag() -> const TCHAR* { return STR("WidgetLayoutLibrary"); } static auto Instance() -> WidgetLayoutLibrary& { static WidgetLayoutLibrary Singleton{}; return Singleton; } // ---- slot casts --------------------------------------------------- auto SlotAsCanvasSlot(UObject* Widget) -> CanvasPanelSlot { return GetSingleton(STR("SlotAsCanvasSlot"), Widget); } auto SlotAsWrapBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsWrapBoxSlot"), Widget); } auto SlotAsWidgetSwitcherSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsWidgetSwitcherSlot"), Widget); } auto SlotAsVerticalBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsVerticalBoxSlot"), Widget); } auto SlotAsUniformGridSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsUniformGridSlot"), Widget); } auto SlotAsSizeBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsSizeBoxSlot"), Widget); } auto SlotAsScrollBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsScrollBoxSlot"), Widget); } auto SlotAsScaleBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsScaleBoxSlot"), Widget); } auto SlotAsSafeBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsSafeBoxSlot"), Widget); } auto SlotAsOverlaySlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsOverlaySlot"), Widget); } auto SlotAsHorizontalBoxSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsHorizontalBoxSlot"), Widget); } auto SlotAsGridSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsGridSlot"), Widget); } auto SlotAsBorderSlot(UObject* Widget) -> PanelSlot { return GetSingleton(STR("SlotAsBorderSlot"), Widget); } // ---- viewport / mouse ---------------------------------------------- auto RemoveAllWidgets(UObject* WorldContextObject) -> bool { struct P { UObject* WorldContextObject; } p{ WorldContextObject }; return Call(STR("RemoveAllWidgets"), p); } auto GetViewportSize(UObject* WorldContextObject) -> std::optional { struct P { UObject* WorldContextObject; FVector2D_ ReturnValue; } p{ WorldContextObject, {} }; return CallForReturn(STR("GetViewportSize"), p, &P::ReturnValue); } auto GetViewportScale(UObject* WorldContextObject) -> std::optional { struct P { UObject* WorldContextObject; float ReturnValue; } p{ WorldContextObject, 0.f }; return CallForReturn(STR("GetViewportScale"), p, &P::ReturnValue); } auto GetMousePositionOnViewport(UObject* WorldContextObject) -> std::optional { struct P { UObject* WorldContextObject; FVector2D_ ReturnValue; } p{ WorldContextObject, {} }; return CallForReturn(STR("GetMousePositionOnViewport"), p, &P::ReturnValue); } auto GetMousePositionOnPlatform() -> std::optional { return CallForReturn(STR("GetMousePositionOnPlatform")); } struct MousePositionDPI { float X{}; float Y{}; }; auto GetMousePositionScaledByDPI(UObject* Player) -> std::optional { struct P { UObject* Player; float LocationX; float LocationY; bool ReturnValue; } p{ Player, 0.f, 0.f, false }; if (!Call(STR("GetMousePositionScaledByDPI"), p) || !p.ReturnValue) return std::nullopt; return MousePositionDPI{ p.LocationX, p.LocationY }; } auto ProjectWorldLocationToWidgetPosition(UObject* PlayerController, FVector_ WorldLocation, bool bPlayerViewportRelative) -> std::optional { struct P { UObject* PlayerController; FVector_ WorldLocation; FVector2D_ ScreenPosition; bool bPlayerViewportRelative; bool ReturnValue; } p{ PlayerController, WorldLocation, {}, bPlayerViewportRelative, false }; if (!Call(STR("ProjectWorldLocationToWidgetPosition"), p) || !p.ReturnValue) return std::nullopt; return p.ScreenPosition; } private: WidgetLayoutLibrary() : UnrealWrapper(ResolveCDO(), ClassOf(), DebugTag()) {} WidgetLayoutLibrary(const WidgetLayoutLibrary&) = delete; auto operator=(const WidgetLayoutLibrary&) -> WidgetLayoutLibrary& = delete; static auto ResolveCDO() -> UObject* { static Reflection::UnrealObjectRef Ref{ CDOPath(), DebugTag() }; return Ref.Get(); } auto CallStaticObjectGetter(const TCHAR* FunctionName, UObject* InObject) -> UObject* { struct P { UObject* InObject; UObject* ReturnValue; } p{ InObject, nullptr }; auto Result = CallForReturn(FunctionName, p, &P::ReturnValue); return (Result && *Result) ? *Result : nullptr; } template auto GetSingleton(const TCHAR* FunctionName, UObject* InObject) -> T { UObject* Obj = CallStaticObjectGetter(FunctionName, InObject); return Obj ? T{ Obj } : T{}; } }; }