2025-08-31 15:36:48 +08:00
|
|
|
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "Widgets/BagConfigGridWidget.h"
|
|
|
|
|
|
2025-08-31 15:49:07 +08:00
|
|
|
#include "ProjectFish/DataAsset/BagShapeAsset.h"
|
2025-08-31 15:36:48 +08:00
|
|
|
|
2025-08-31 15:49:07 +08:00
|
|
|
const float SBagConfigGridWidget::CellSize = 32.0f;
|
|
|
|
|
const float SBagConfigGridWidget::CellSpacing = 2.0f;
|
2025-08-31 15:36:48 +08:00
|
|
|
|
|
|
|
|
void SBagConfigGridWidget::Construct(const FArguments& InArgs)
|
|
|
|
|
{
|
2025-08-31 15:49:07 +08:00
|
|
|
BagConfig = InArgs._BagConfig;
|
|
|
|
|
OnGridCellClicked = InArgs._OnGridCellClicked;
|
|
|
|
|
PreviewSkill = nullptr;
|
|
|
|
|
PreviewX = -1;
|
|
|
|
|
PreviewY = -1;
|
|
|
|
|
|
|
|
|
|
ChildSlot
|
|
|
|
|
[
|
|
|
|
|
SNew(SOverlay)
|
|
|
|
|
];
|
2025-08-31 15:36:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SBagConfigGridWidget::RefreshGrid()
|
|
|
|
|
{
|
2025-08-31 15:49:07 +08:00
|
|
|
// 强制重绘
|
|
|
|
|
Invalidate(EInvalidateWidget::Paint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FReply SBagConfigGridWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
|
|
|
{
|
|
|
|
|
if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && BagConfig.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))
|
|
|
|
|
{
|
|
|
|
|
OnGridCellClicked.ExecuteIfBound(GridX, GridY);
|
|
|
|
|
return FReply::Handled();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FReply::Unhandled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FReply SBagConfigGridWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
|
|
|
{
|
|
|
|
|
return FReply::Unhandled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32 SBagConfigGridWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
|
|
|
|
|
const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,
|
|
|
|
|
const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
|
|
|
|
|
{
|
|
|
|
|
if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset)
|
|
|
|
|
{
|
|
|
|
|
return LayerId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UBagShapeAsset* BagShapeAsset = BagConfig->BagShapeAsset;
|
|
|
|
|
|
|
|
|
|
// 绘制背包格子
|
|
|
|
|
for (int32 Y = 0; Y < BagShapeAsset->BagHeight; Y++)
|
|
|
|
|
{
|
|
|
|
|
for (int32 X = 0; X < BagShapeAsset->BagWidth; X++)
|
|
|
|
|
{
|
|
|
|
|
FVector2D CellPos = GetCellPosition(X, Y);
|
|
|
|
|
FVector2D CellSizeVec(CellSize, CellSize);
|
|
|
|
|
|
|
|
|
|
// 获取格子颜色
|
|
|
|
|
FLinearColor CellColor = GetCellColor(X, Y);
|
|
|
|
|
|
|
|
|
|
// 绘制格子背景
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(CellSizeVec, FSlateLayoutTransform(CellPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("WhiteBrush"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
CellColor
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 绘制格子边框
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 1,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(CellSizeVec, FSlateLayoutTransform(CellPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("Border"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
FLinearColor::Black
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绘制已放置的技能
|
|
|
|
|
for (int32 i = 0; i < BagConfig->PlacedSkills.Num(); i++)
|
|
|
|
|
{
|
|
|
|
|
const FPlacedSkillInfo& PlacedSkill = BagConfig->PlacedSkills[i];
|
|
|
|
|
FVector2D SkillPos = GetCellPosition(PlacedSkill.PositionX, PlacedSkill.PositionY);
|
|
|
|
|
|
|
|
|
|
FVector2D SkillSizeVec(GetSkillSizeValue(PlacedSkill.SkillAsset->SkillSize).X * (CellSize + CellSpacing) - CellSpacing,
|
|
|
|
|
GetSkillSizeValue(PlacedSkill.SkillAsset->SkillSize).Y* (CellSize + CellSpacing) - CellSpacing);
|
|
|
|
|
|
|
|
|
|
// 绘制技能背景
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 2,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("WhiteBrush"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
FLinearColor::Blue
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 绘制技能边框
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 3,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("Border"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
FLinearColor::White
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 绘制技能名称
|
|
|
|
|
if (!PlacedSkill.SkillAsset->SkillName.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
FSlateDrawElement::MakeText(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 4,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos + FVector2D(4, 4))),
|
|
|
|
|
PlacedSkill.SkillAsset->SkillName,
|
|
|
|
|
FCoreStyle::GetDefaultFontStyle("Regular", 10),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
FLinearColor::White
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绘制预览技能
|
|
|
|
|
if (PreviewSkill.IsValid() && PreviewX >= 0 && PreviewY >= 0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
FVector2D PreviewPos = GetCellPosition(PreviewX, PreviewY);
|
|
|
|
|
FVector2D PreviewSizeVec(GetSkillSizeValue(PreviewSkill->SkillSize).X * (CellSize + CellSpacing) - CellSpacing,
|
|
|
|
|
GetSkillSizeValue(PreviewSkill->SkillSize).Y * (CellSize + CellSpacing) - CellSpacing);
|
|
|
|
|
|
|
|
|
|
FLinearColor PreviewColor = FLinearColor::Blue;
|
|
|
|
|
PreviewColor.A = 0.5f; // 半透明
|
|
|
|
|
|
|
|
|
|
// 绘制预览背景
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 5,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(PreviewSizeVec, FSlateLayoutTransform(PreviewPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("WhiteBrush"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
PreviewColor
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 绘制预览边框(虚线效果)
|
|
|
|
|
FSlateDrawElement::MakeBox(
|
|
|
|
|
OutDrawElements,
|
|
|
|
|
LayerId + 6,
|
|
|
|
|
AllottedGeometry.ToPaintGeometry(PreviewSizeVec, FSlateLayoutTransform(PreviewPos)),
|
|
|
|
|
FCoreStyle::Get().GetBrush("Border"),
|
|
|
|
|
ESlateDrawEffect::None,
|
|
|
|
|
FLinearColor::Yellow
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LayerId + 7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FVector2D SBagConfigGridWidget::ComputeDesiredSize(float X) const
|
|
|
|
|
{
|
|
|
|
|
if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset)
|
|
|
|
|
{
|
|
|
|
|
return FVector2D(100, 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UBagShapeAsset* BagShapeAsset = BagConfig->BagShapeAsset;
|
|
|
|
|
return FVector2D(
|
|
|
|
|
BagShapeAsset->BagWidth * (CellSize + CellSpacing) - CellSpacing,
|
|
|
|
|
BagShapeAsset->BagHeight * (CellSize + CellSpacing) - CellSpacing
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FVector2D SBagConfigGridWidget::GetGridCellFromPosition(const FVector2D& Position) const
|
|
|
|
|
{
|
|
|
|
|
return FVector2D(
|
|
|
|
|
Position.X / (CellSize + CellSpacing),
|
|
|
|
|
Position.Y / (CellSize + CellSpacing)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SBagConfigGridWidget::IsValidGridPosition(int32 X, int32 Y) const
|
|
|
|
|
{
|
|
|
|
|
if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return X >= 0 && X < BagConfig->BagShapeAsset->BagWidth &&
|
|
|
|
|
Y >= 0 && Y < BagConfig->BagShapeAsset->BagHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLinearColor SBagConfigGridWidget::GetCellColor(int32 X, int32 Y) const
|
|
|
|
|
{
|
|
|
|
|
if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset)
|
|
|
|
|
{
|
|
|
|
|
return FLinearColor::Gray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查格子是否激活
|
|
|
|
|
if (!BagConfig->BagShapeAsset->IsSlotActive(X, Y))
|
|
|
|
|
{
|
|
|
|
|
return FLinearColor(0.2f, 0.2f, 0.2f, 1.0f); // 非激活格子为深灰色
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否被技能占用
|
|
|
|
|
int32 SkillIndex = BagConfig->GetSkillAtPosition(X, Y);
|
|
|
|
|
if (SkillIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
return FLinearColor(0, 0, 1, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 空闲格子为浅灰色
|
|
|
|
|
return FLinearColor(0.7f, 0.7f, 0.7f, 1.0f);
|
2025-08-31 15:36:48 +08:00
|
|
|
}
|