Files
ZMMO/Source/ZMMO/Game/UI/Common/UIDraggableWindow_Base.cpp
Mateus Rodrigues 6a6a28a086 refactor: prefixo ZMMO -> Zeus em classes/módulos C++ do cliente
- Renomeia ~50 classes UCLASS/USTRUCT/UENUM/UINTERFACE pra Zeus*
  (AZeusGameMode, AZeusCharacter, UZeusGameInstance, IZeusEntityInterface,
  UZeusWorldSubsystem, FZeusEntitySnapshot, etc.)
- Encurta AZMMOPlayerCharacter -> AZeusCharacter
- Renomeia módulos satélite ZMMOAttributes -> ZeusAttributes e
  ZMMOJobs -> ZeusJobs (pasta + .Build.cs + .uproject)
- Mantém módulo principal ZMMO (renomeia depois quando jogo ganhar nome)
- DefaultEngine.ini: ActiveClassRedirects ZMMOX -> ZeusX (preserva BPs/assets)
- DefaultGame.ini: sections atualizadas pra ZeusThemeSubsystem/ZeusPlayerState
- Category="ZMMO|..." -> "Zeus|..." em UPROPERTYs
- Preserva LogZMMO, ZMMO_API, /Script/ZMMO., /Game/ZMMO/, classes Target

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 17:24:38 -03:00

132 lines
4.1 KiB
C++

#include "UIDraggableWindow_Base.h"
#include "Components/Border.h"
#include "Engine/Engine.h"
#include "Engine/GameViewportClient.h"
#include "Input/Reply.h"
#include "UIWindowSaveGame.h"
void UUIDraggableWindow_Base::NativeOnActivated()
{
Super::NativeOnActivated();
ApplySavedPosition();
// Validacao usa translation + viewport size, ambos disponiveis ja' aqui
// (sem precisar do CachedGeometry/layout pass).
ValidatePositionInViewport();
}
void UUIDraggableWindow_Base::ApplySavedPosition()
{
const FName Id = GetWindowId();
if (Id.IsNone()) return;
UZeusUISaveGame* Save = UZeusUISaveGame::LoadOrCreate();
FVector2D Pos;
if (Save && Save->TryGetWindowPosition(Id, Pos))
{
SetRenderTranslation(Pos);
}
}
void UUIDraggableWindow_Base::PersistCurrentPosition()
{
const FName Id = GetWindowId();
if (Id.IsNone()) return;
UZeusUISaveGame* Save = UZeusUISaveGame::LoadOrCreate();
if (!Save) return;
Save->SetWindowPosition(Id, GetRenderTransform().Translation);
UZeusUISaveGame::SaveNow(Save);
}
bool UUIDraggableWindow_Base::IsDragHandleHit(const FPointerEvent& MouseEvent) const
{
if (!Border_DragHandle) return false;
const FGeometry HandleGeom = Border_DragHandle->GetCachedGeometry();
return HandleGeom.IsUnderLocation(MouseEvent.GetScreenSpacePosition());
}
FReply UUIDraggableWindow_Base::NativeOnMouseButtonDown(const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent)
{
if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && IsDragHandleHit(InMouseEvent))
{
bMaybeDragging = true;
bDragging = false;
DragStartScreenPos = InMouseEvent.GetScreenSpacePosition();
WidgetStartTranslation = GetRenderTransform().Translation;
return FReply::Handled().CaptureMouse(TakeWidget());
}
return Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
}
FReply UUIDraggableWindow_Base::NativeOnMouseMove(const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent)
{
if (!bMaybeDragging && !bDragging)
{
return Super::NativeOnMouseMove(InGeometry, InMouseEvent);
}
const FVector2D Delta = InMouseEvent.GetScreenSpacePosition() - DragStartScreenPos;
if (!bDragging && Delta.SizeSquared() < DragStartThresholdPx * DragStartThresholdPx)
{
return FReply::Handled();
}
bDragging = true;
SetRenderTranslation(WidgetStartTranslation + Delta);
return FReply::Handled();
}
FReply UUIDraggableWindow_Base::NativeOnMouseButtonUp(const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent)
{
if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && (bMaybeDragging || bDragging))
{
const bool bWasRealDrag = bDragging;
bMaybeDragging = false;
bDragging = false;
if (bWasRealDrag)
{
PersistCurrentPosition();
}
return FReply::Handled().ReleaseMouseCapture();
}
return Super::NativeOnMouseButtonUp(InGeometry, InMouseEvent);
}
void UUIDraggableWindow_Base::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
{
Super::NativeOnMouseLeave(InMouseEvent);
}
void UUIDraggableWindow_Base::ValidatePositionInViewport()
{
if (!GEngine || !GEngine->GameViewport) return;
FVector2D ViewportSize;
GEngine->GameViewport->GetViewportSize(ViewportSize);
if (ViewportSize.IsNearlyZero()) return;
// RenderTransform.Translation esta em coordenadas de viewport (pixels),
// independente de DPI/offset do editor — comparacao direta funciona em
// PIE e em build standalone. Assume slot centralizado (default UMG
// stack); meio-viewport e' o quanto a translation pode crescer antes
// da janela sair completamente.
const FVector2D Tr = GetRenderTransform().Translation;
const float HalfX = ViewportSize.X * 0.5f;
const float HalfY = ViewportSize.Y * 0.5f;
const bool bOutOfBounds =
FMath::Abs(Tr.X) > HalfX - MinVisiblePixels ||
FMath::Abs(Tr.Y) > HalfY - MinVisiblePixels;
UE_LOG(LogTemp, Verbose, TEXT("DraggableWindow::Validate translation=(%.0f,%.0f) viewport=(%.0f,%.0f) outOfBounds=%d"),
Tr.X, Tr.Y, ViewportSize.X, ViewportSize.Y, bOutOfBounds ? 1 : 0);
if (bOutOfBounds)
{
SetRenderTranslation(FVector2D::ZeroVector);
PersistCurrentPosition();
}
}