#pragma once #include "UMG_classes.hpp" #include #include #include inline std::atomic_bool g_Console_Enabled { false }; namespace SDK { class UEngine; class UObject; class UWorld; class UWidget; class APawn; class UGameplayStatics; class UConsole; class UInputSettings; class UKismetStringLibrary; class UGameInstance; class ULocalPlayer; class APlayerController; } struct WidgetTrackInfo { std::string ClassName; std::string RootWidgetClass; std::string OuterClass; bool WasInViewport = false; int ConstructCount = 0; int DestructCount = 0; std::chrono::steady_clock::time_point FirstSeen; }; static std::unordered_map g_WidgetTracker; /** * @brief Gets the current game resolution (not native display) and aspect ratio. * @param outWidth screen width. * @param outHeight screen height. * @param outAspectRatio aspect ratio computed. */ void GetResolution(int& outWidth, int& outHeight, float& outAspectRatio); // Unreal Engine functions /** * @brief Gets the current player Pawn from the world. * @param world Optional UWorld pointer. * @return Player Pawn or nullptr. */ SDK::APawn* GetPawnFromWorld(SDK::UWorld* world = nullptr); /** * @brief Reactivate the development console. * @param logger spdlog. */ void ReactivateDevConsole(std::shared_ptr logger); /** * @brief Reposition from left a widget that only displays at left and nothing at right * @param Widget UUserWdget to offset. * @param offset left offset to apply. * @param Alignment widget aligment (0.5, 0.5) is centered for eg. */ void ApplyPositionOffset(SDK::UUserWidget* Widget, float offset, SDK::FVector2D Alignment); float ApplyOffsetsSmart(SDK::UWidget* Widget, float Left, float Right, int MaxDepth); /** * @brief Apply offsets recursively to UVCanvasPanelSlot. * @param widget UUserWidget* pointer. * @param left offset. * @param right offset. * @param ExcludeObjects excluded objects in depth check * @param ExcludeClass excluded class widgets in depth check */ void ApplyOffsetsRecursive(SDK::UWidget* widget, float left, float right = 0, const std::vector& ExcludeObjects = {}, const std::vector& ExcludeClass = {}, int MaxDepth = INT_MAX); /** * @brief Apply offsets recursively to Overlay. * @param widget UUserWidget* pointer. * @param Offset (left and right offsets). * @param alignment widget (left, right, center, fill ...) * @param ExcludeNames excluded class widgets in depth check * @param MaxDepth Max depth to go through root component */ void ApplyOverlayOffsetRecursive(SDK::UWidget* Widget, float left, float right, SDK::EHorizontalAlignment alignment, const std::vector& ExcludeNames = {}, int MaxDepth = INT_MAX); /** * @brief Apply transform to a widget. * @param Widget UWidget* pointer. * @param OffsetX (left offset). * @param OffsetY (top offset). */ void ApplyTransformOffset(SDK::UWidget* Widget, float OffsetX, float OffsetY = 0); void FindAndApplyCanvasRecursive(SDK::UWidget* widget, float offset, int MaxDepth = INT_MAX, int currentDepth = 0); /** * @brief Tracks potential widgets candidates for HUD & UI at construction * @param widget UUserWidget* pointer. */ void TrackWidgetConstruct(SDK::UUserWidget* widget); /** * @brief Tracks potential widgets candidates for HUD & UI at destruction * @param widget UUserWidget* pointer. */ void TrackWidgetDestruct(SDK::UUserWidget* widget); /** * @brief Dump and log previously searched UI & HUD wisgets * @param logger the log object. */ void DumpUIAnalysis(std::shared_ptr logger); /** * @brief Clear previously tracked widgets */ void ClearWidgetTracking(); /** * @brief Dump all widgets * @param Widget a UWidget instance to browse * @param Depth the depth to start from * @param MaxDepth the maximal depth to reach */ void DumpWidgetRecursive(SDK::UWidget* Widget, int Depth = 0, int MaxDepth = 2);