178 lines
5.7 KiB
C++
Raw Permalink Normal View History

2025-08-30 18:03:42 +08:00
// Fill out your copyright notice in the Description page of Project Settings.
2025-10-15 18:25:31 +08:00
#include "Widgets/ShapeGridWidget.h"
2025-08-30 18:03:42 +08:00
2025-10-15 18:25:31 +08:00
const float SShapeGridWidget::CellSize = 32.0f;
const float SShapeGridWidget::SeparatorWidth = 2.0f;
void SShapeGridWidget::Construct(const FArguments& InArgs)
2025-08-30 18:03:42 +08:00
{
BagShapeAsset = InArgs._BagShapeAsset;
OnSlotClicked = InArgs._OnSlotClicked;
}
2025-10-15 18:25:31 +08:00
void SShapeGridWidget::UpdateBagShapeAsset(UShapeAsset* InBagShapeAsset)
2025-08-30 18:03:42 +08:00
{
BagShapeAsset = InBagShapeAsset;
Invalidate(EInvalidateWidget::Paint);
}
2025-10-15 18:25:31 +08:00
FReply SShapeGridWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
2025-08-30 18:03:42 +08:00
{
if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && BagShapeAsset.IsValid())
{
FVector2D LocalPosition = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition());
FVector2D GridCell = GetGridCellFromPosition(LocalPosition);
int32 GridX = FMath::FloorToInt(GridCell.X);
int32 GridY = FMath::FloorToInt(GridCell.Y);
if (IsValidGridPosition(GridX, GridY))
{
OnSlotClicked.ExecuteIfBound(GridX, GridY);
return FReply::Handled();
}
}
return FReply::Unhandled();
}
2025-10-15 18:25:31 +08:00
int32 SShapeGridWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
2025-08-30 18:03:42 +08:00
const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,
const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
if (!BagShapeAsset.IsValid())
{
return LayerId;
}
// Calculate grid dimensions with separators
float Scale = CellSize + SeparatorWidth;
2025-10-15 18:25:31 +08:00
float GridWidth = BagShapeAsset->ShapeWidth * Scale - SeparatorWidth;
float GridHeight = BagShapeAsset->ShapeHeight * Scale - SeparatorWidth;
2025-08-30 18:03:42 +08:00
// Center the grid in the available space
FVector2D GridStartPos = FVector2D(
(AllottedGeometry.GetLocalSize().X - GridWidth) * 0.5f,
(AllottedGeometry.GetLocalSize().Y - GridHeight) * 0.5f
);
// Draw background
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId,
AllottedGeometry.ToPaintGeometry(AllottedGeometry.GetLocalSize(), FSlateLayoutTransform()),
FCoreStyle::Get().GetBrush("WhiteBrush"),
ESlateDrawEffect::None,
FLinearColor(0.1f, 0.1f, 0.1f, 1.0f)
);
// Draw cells
2025-10-15 18:25:31 +08:00
for (int32 Y = 0; Y < BagShapeAsset->ShapeHeight; Y++)
2025-08-30 18:03:42 +08:00
{
2025-10-15 18:25:31 +08:00
for (int32 X = 0; X < BagShapeAsset->ShapeWidth; X++)
2025-08-30 18:03:42 +08:00
{
FVector2D CellPos = GridStartPos + FVector2D(X * Scale, Y * Scale);
bool bIsActive = BagShapeAsset->IsSlotActive(X, Y);
// Draw cell background
FLinearColor CellColor = bIsActive ? FLinearColor(0.2f, 0.8f, 0.2f, 1.0f) : FLinearColor(0.15f, 0.15f, 0.15f, 1.0f);
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId + 1,
AllottedGeometry.ToPaintGeometry(FVector2D(CellSize, CellSize), FSlateLayoutTransform(CellPos)),
FCoreStyle::Get().GetBrush("WhiteBrush"),
ESlateDrawEffect::None,
CellColor
);
}
}
// Draw vertical separators
2025-10-15 18:25:31 +08:00
for (int32 X = 1; X < BagShapeAsset->ShapeWidth; X++)
2025-08-30 18:03:42 +08:00
{
float SeparatorX = GridStartPos.X + X * Scale - SeparatorWidth;
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId + 2,
AllottedGeometry.ToPaintGeometry(FVector2D(SeparatorWidth, GridHeight), FSlateLayoutTransform(FVector2D(SeparatorX, GridStartPos.Y))),
FCoreStyle::Get().GetBrush("WhiteBrush"),
ESlateDrawEffect::None,
FLinearColor::White
);
}
// Draw horizontal separators
2025-10-15 18:25:31 +08:00
for (int32 Y = 1; Y < BagShapeAsset->ShapeHeight; Y++)
2025-08-30 18:03:42 +08:00
{
float SeparatorY = GridStartPos.Y + Y * Scale - SeparatorWidth;
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId + 2,
AllottedGeometry.ToPaintGeometry(FVector2D(GridWidth, SeparatorWidth), FSlateLayoutTransform(FVector2D(GridStartPos.X, SeparatorY))),
FCoreStyle::Get().GetBrush("WhiteBrush"),
ESlateDrawEffect::None,
FLinearColor::White
);
}
// Draw outer border
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId + 3,
AllottedGeometry.ToPaintGeometry(FVector2D(GridWidth, GridHeight), FSlateLayoutTransform(GridStartPos)),
FCoreStyle::Get().GetBrush("Border"),
ESlateDrawEffect::None,
FLinearColor::White
);
return LayerId + 4;
}
2025-10-15 18:25:31 +08:00
FVector2D SShapeGridWidget::ComputeDesiredSize(float X) const
2025-08-30 18:03:42 +08:00
{
if (!BagShapeAsset.IsValid())
{
return FVector2D(200, 200);
}
float Scale = CellSize + SeparatorWidth;
return FVector2D(
2025-10-15 18:25:31 +08:00
BagShapeAsset->ShapeWidth * Scale - SeparatorWidth + 20.0f, // Add padding
BagShapeAsset->ShapeHeight * Scale - SeparatorWidth + 20.0f
2025-08-30 18:03:42 +08:00
);
}
2025-10-15 18:25:31 +08:00
FVector2D SShapeGridWidget::GetGridCellFromPosition(const FVector2D& Position) const
2025-08-30 18:03:42 +08:00
{
if (!BagShapeAsset.IsValid())
{
return FVector2D(-1, -1);
}
float Scale = CellSize + SeparatorWidth;
2025-10-15 18:25:31 +08:00
float GridWidth = BagShapeAsset->ShapeWidth * Scale - SeparatorWidth;
float GridHeight = BagShapeAsset->ShapeHeight * Scale - SeparatorWidth;
2025-08-30 18:03:42 +08:00
FVector2D GridStartPos = FVector2D(
(GetCachedGeometry().GetLocalSize().X - GridWidth) * 0.5f,
(GetCachedGeometry().GetLocalSize().Y - GridHeight) * 0.5f
);
FVector2D RelativePos = Position - GridStartPos;
return FVector2D(
RelativePos.X / Scale,
RelativePos.Y / Scale
);
}
2025-10-15 18:25:31 +08:00
bool SShapeGridWidget::IsValidGridPosition(int32 X, int32 Y) const
2025-08-30 18:03:42 +08:00
{
if (!BagShapeAsset.IsValid())
{
return false;
}
2025-10-15 18:25:31 +08:00
return X >= 0 && X < BagShapeAsset->ShapeWidth && Y >= 0 && Y < BagShapeAsset->ShapeHeight;
2025-08-30 18:03:42 +08:00
}