Add widget position and transform offset functions.

This commit is contained in:
2026-03-07 16:54:15 +01:00
parent 9b1a210262
commit 6c4ba505e1

View File

@@ -2,7 +2,20 @@
#include "Engine_classes.hpp"
std::shared_ptr<spdlog::logger> g_logger;
// UE settings
void GetResolution(int& outWidth, int& outHeight, float& outAspectRatio) {
SDK::UEngine* Engine = SDK::UEngine::GetEngine();
if (!Engine || !Engine->GameUserSettings) return;
SDK::UGameUserSettings* Settings = SDK::UGameUserSettings::GetGameUserSettings();
if (!Settings) return;
SDK::FIntPoint Res = Settings->GetScreenResolution();
outWidth = (int)Res.X;
outHeight = (int)Res.Y;
outAspectRatio = (float)outWidth / outHeight;
}
// UE objects
SDK::APawn* GetPawnFromWorld(SDK::UWorld* world) {
if (!world) world = SDK::UWorld::GetWorld();
if (!world) return nullptr;
@@ -17,7 +30,7 @@ SDK::APawn* GetPawnFromWorld(SDK::UWorld* world) {
return pawn;
}
// Console
void ReactivateDevConsole(std::shared_ptr<spdlog::logger> logger) {
g_logger = logger;
std::thread([logger]() {
@@ -65,9 +78,27 @@ void ReactivateDevConsole(std::shared_ptr<spdlog::logger> logger) {
}).detach();
}
// --- HUD & UI methods ---
void ApplyOffsetsSmart_Internal( SDK::UWidget* Widget, float Left, float Right, int Depth = 0, int MaxDepth = 1) {
void ApplyPositionOffset(SDK::UUserWidget* Widget, float offset, SDK::FVector2D Alignment) {
if (!Widget) return;
if (Widget->Slot && Widget->Slot->IsA(SDK::UCanvasPanelSlot::StaticClass())) {
auto* canvasSlot = static_cast<SDK::UCanvasPanelSlot*>(Widget->Slot);
canvasSlot->SetPosition(SDK::FVector2D(offset, 0));
canvasSlot->SetAlignment(Alignment);
}
}
void ApplyTransformOffset(SDK::UWidget* Widget, float OffsetX, float OffsetY) {
if (!Widget) return;
SDK::FWidgetTransform Transform = Widget->RenderTransform;
Transform.Translation.X = OffsetX; // Horizontal shifting
Transform.Translation.Y = OffsetY; // Vertical shifting (optional)
Widget->SetRenderTransform(Transform);
}
float ApplyOffsetsSmart_Internal(SDK::UWidget* Widget, float Left, float Right, int Depth = 0, int MaxDepth = 1) {
if (!Widget) return 0;
static float leftApplied = 0;
// Apply if CanvasSlot
if (Widget->Slot && Widget->Slot->IsA(SDK::UCanvasPanelSlot::StaticClass())) {
if (Depth <= MaxDepth) {
@@ -79,17 +110,18 @@ void ApplyOffsetsSmart_Internal( SDK::UWidget* Widget, float Left, float Right,
float MinX = Anchors.Minimum.X;
float MaxX = Anchors.Maximum.X;
#ifdef MY_VERBOSE_LOGS
if (g_logger) g_logger->debug("CanvasPanelSlot: {} {} - Slot: {} {} - Offets: {} {} {} {} - Anchors: {} {} {} {}",
std::string indent(Depth * 2, ' '); // 2 espaces par niveau
if (g_logger) g_logger->debug("{}CanvasPanelSlot: {} {} - Slot: {} {} - Offets: {} {} {} {} - Anchors: {} {} {} {}",indent,
Widget->GetName(), Widget->Class->GetName(),
Slot->GetName(), Slot->Class->GetName(),
Offsets.Left, Offsets.Top, Offsets.Right, Offsets.Bottom,
Anchors.Minimum.X, Anchors.Minimum.Y, Anchors.Maximum.X, Anchors.Maximum.Y);
#endif
if (MinX == 0.f && MaxX == 1.f) return; // Ignore stretch
if (MinX == 0.5f && MaxX == 0.5f) return; // Ignore centered
if (MinX == 0.f && MaxX == 1.f) return 0; // Ignore stretch
if (MinX == 0.5f && MaxX == 0.5f) return 0; // Ignore centered
if (MinX == 0.f && MaxX == 0.f) // Modify only pure left
Offsets.Left = Left;
leftApplied = Offsets.Left = Left;
else if (MinX == 1.f && MaxX == 1.f) // Modify only pure right
Offsets.Left = -Right;
@@ -98,7 +130,7 @@ void ApplyOffsetsSmart_Internal( SDK::UWidget* Widget, float Left, float Right,
}
// Stop to max depth
if (Depth >= MaxDepth) return;
if (Depth >= MaxDepth) return leftApplied;
// Browse the children
if (Widget->IsA(SDK::UPanelWidget::StaticClass())) {
@@ -114,16 +146,12 @@ void ApplyOffsetsSmart_Internal( SDK::UWidget* Widget, float Left, float Right,
if (UW->WidgetTree && UW->WidgetTree->RootWidget)
ApplyOffsetsSmart_Internal(UW->WidgetTree->RootWidget, Left, Right, Depth + 1, MaxDepth);
}
return leftApplied;
}
void ApplyOffsetsSmart(SDK::UWidget* Widget, float Left, float Right, int MaxDepth) {
#ifdef MY_VERBOSE_LOGS
if (g_logger) g_logger->debug("=========================================================");
if (g_logger) g_logger->debug("Widget offset applying: {} {}",
Widget->GetName(), Widget->Class->GetName());
if (g_logger) g_logger->debug("=========================================================");
#endif
ApplyOffsetsSmart_Internal(Widget, Left, Right, 0, MaxDepth);
float ApplyOffsetsSmart(SDK::UWidget* Widget, float Left, float Right, int MaxDepth) {
float leftApplied = ApplyOffsetsSmart_Internal(Widget, Left, Right, 0, MaxDepth);
return leftApplied;
}
static void ApplyOffsetsRecursive_Internal(SDK::UWidget* Widget, float Left, float Right,
@@ -239,15 +267,16 @@ void ApplyOverlayOffsetRecursive(SDK::UWidget* Widget, float left, float right,
ApplyOverlayOffsetRecursive_Internal(Widget, left, right, alignment, ExcludeNames, 0, MaxDepth);
}
// -- Tracking && dumping widgets for debugging --
void FindAndApplyCanvasRecursive(SDK::UWidget* widget, float offset, int MaxDepth, int currentDepth) {
if (!widget || currentDepth > MaxDepth) return;
// Si c'est un CanvasPanel, on applique directement
// Applying straight if it's a CanvasPanel
if (widget->IsA(SDK::UCanvasPanel::StaticClass())) {
ApplyOffsetsRecursive(widget, offset, offset);
}
// Si c'est un panel, on descend dans les enfants
// We go deeper if
if (widget->IsA(SDK::UPanelWidget::StaticClass())) {
auto* panel = static_cast<SDK::UPanelWidget*>(widget);
int childrenCount = panel->GetChildrenCount();