// Fill out your copyright notice in the Description page of Project Settings. #include "ProjectFishEditor/Public/Thumbnail/ShapeAssetThumbnailRenderer.h" #include "CanvasItem.h" #include "CanvasTypes.h" #include "ProjectFish/DataAsset/ShapeAsset.h" bool UShapeAssetThumbnailRenderer::CanVisualizeAsset(UObject* Object) { return Cast(Object) != nullptr; } void UShapeAssetThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas, bool bAdditionalViewFamily) { UShapeAsset* BagShapeAsset = Cast(Object); if (!BagShapeAsset || !Canvas) { return; } DrawBagShape(BagShapeAsset, Canvas, X, Y, Width, Height); } void UShapeAssetThumbnailRenderer::DrawBagShape(UShapeAsset* BagShapeAsset, FCanvas* Canvas, int32 X, int32 Y, uint32 Width, uint32 Height) { if (!BagShapeAsset || !Canvas) { return; } // Clear the background FCanvasBoxItem BackgroundBox(FVector2D(X, Y), FVector2D(Width, Height)); BackgroundBox.SetColor(FLinearColor(0.1f, 0.1f, 0.1f, 1.0f)); Canvas->DrawItem(BackgroundBox); // Calculate the best fit scale with spacing for separators float SeparatorWidth = 2.0f; // White separator width float Scale = GetBestFitScale(BagShapeAsset->ShapeWidth, BagShapeAsset->ShapeHeight, Width, Height); float CellSize = Scale - SeparatorWidth; // Reduce cell size to make room for separators // Calculate starting position to center the grid (including separators) float GridWidth = BagShapeAsset->ShapeWidth * Scale - SeparatorWidth; float GridHeight = BagShapeAsset->ShapeHeight * Scale - SeparatorWidth; float StartX = X + (Width - GridWidth) * 0.5f; float StartY = Y + (Height - GridHeight) * 0.5f; // Draw the bag slots (background) with separators for (int32 GridY = 0; GridY < BagShapeAsset->ShapeHeight; GridY++) { for (int32 GridX = 0; GridX < BagShapeAsset->ShapeWidth; GridX++) { float CellStartX = StartX + GridX * Scale; float CellStartY = StartY + GridY * Scale; bool bIsActive = BagShapeAsset->IsSlotActive(GridX, GridY); // Draw filled cell (smaller to leave space for separators) FCanvasTileItem CellTile(FVector2D(CellStartX, CellStartY), FVector2D(CellSize, CellSize), bIsActive ? FLinearColor(0.2f, 0.8f, 0.2f, 1.0f) : FLinearColor(0.15f, 0.15f, 0.15f, 1.0f)); CellTile.BlendMode = SE_BLEND_Opaque; Canvas->DrawItem(CellTile); } } // // Draw white separators // // Vertical separators // for (int32 GridX = 1; GridX < BagShapeAsset->BagWidth; GridX++) // { // float SeparatorX = StartX + GridX * Scale - SeparatorWidth; // FCanvasTileItem VerticalSeparator(FVector2D(SeparatorX, StartY), FVector2D(SeparatorWidth, GridHeight), FLinearColor::White); // VerticalSeparator.BlendMode = SE_BLEND_Opaque; // Canvas->DrawItem(VerticalSeparator); // } // // Horizontal separators // for (int32 GridY = 1; GridY < BagShapeAsset->BagHeight; GridY++) // { // float SeparatorY = StartY + GridY * Scale - SeparatorWidth; // FCanvasTileItem HorizontalSeparator(FVector2D(StartX, SeparatorY), FVector2D(GridWidth, SeparatorWidth), FLinearColor::White); // HorizontalSeparator.BlendMode = SE_BLEND_Opaque; // Canvas->DrawItem(HorizontalSeparator); // } // // Draw outer border // FCanvasBoxItem OuterBorder(FVector2D(StartX, StartY), FVector2D(GridWidth, GridHeight)); // OuterBorder.SetColor(FLinearColor::White); // OuterBorder.LineThickness = 5.0f; // Canvas->DrawItem(OuterBorder); } float UShapeAssetThumbnailRenderer::GetBestFitScale(int32 BagWidth, int32 BagHeight, uint32 CanvasWidth, uint32 CanvasHeight) const { if (BagWidth == 0 || BagHeight == 0) { return 1.0f; } // Leave some padding float PaddedWidth = CanvasWidth * 0.9f; float PaddedHeight = CanvasHeight * 0.9f; float ScaleX = PaddedWidth / BagWidth; float ScaleY = PaddedHeight / BagHeight; // Use the smaller scale to ensure everything fits float Scale = FMath::Min(ScaleX, ScaleY); // Ensure minimum cell size for visibility Scale = FMath::Max(Scale, 4.0f); return Scale; }