// Fill out your copyright notice in the Description page of Project Settings. #include "Widgets/BagShapeGridWidget.h" const float SBagShapeGridWidget::CellSize = 32.0f; const float SBagShapeGridWidget::SeparatorWidth = 2.0f; void SBagShapeGridWidget::Construct(const FArguments& InArgs) { BagShapeAsset = InArgs._BagShapeAsset; OnSlotClicked = InArgs._OnSlotClicked; } void SBagShapeGridWidget::UpdateBagShapeAsset(UBagShapeAsset* InBagShapeAsset) { BagShapeAsset = InBagShapeAsset; Invalidate(EInvalidateWidget::Paint); } FReply SBagShapeGridWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { 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(); } int32 SBagShapeGridWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, 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; float GridWidth = BagShapeAsset->BagWidth * Scale - SeparatorWidth; float GridHeight = BagShapeAsset->BagHeight * Scale - SeparatorWidth; // 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 for (int32 Y = 0; Y < BagShapeAsset->BagHeight; Y++) { for (int32 X = 0; X < BagShapeAsset->BagWidth; X++) { 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 for (int32 X = 1; X < BagShapeAsset->BagWidth; X++) { 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 for (int32 Y = 1; Y < BagShapeAsset->BagHeight; Y++) { 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; } FVector2D SBagShapeGridWidget::ComputeDesiredSize(float X) const { if (!BagShapeAsset.IsValid()) { return FVector2D(200, 200); } float Scale = CellSize + SeparatorWidth; return FVector2D( BagShapeAsset->BagWidth * Scale - SeparatorWidth + 20.0f, // Add padding BagShapeAsset->BagHeight * Scale - SeparatorWidth + 20.0f ); } FVector2D SBagShapeGridWidget::GetGridCellFromPosition(const FVector2D& Position) const { if (!BagShapeAsset.IsValid()) { return FVector2D(-1, -1); } float Scale = CellSize + SeparatorWidth; float GridWidth = BagShapeAsset->BagWidth * Scale - SeparatorWidth; float GridHeight = BagShapeAsset->BagHeight * Scale - SeparatorWidth; 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 ); } bool SBagShapeGridWidget::IsValidGridPosition(int32 X, int32 Y) const { if (!BagShapeAsset.IsValid()) { return false; } return X >= 0 && X < BagShapeAsset->BagWidth && Y >= 0 && Y < BagShapeAsset->BagHeight; }