Files
Naked-Desire/Source/NakedDesire/UI/RadialMenu/RadialSliceWidget.cpp
T
2026-06-03 15:16:27 +03:00

74 lines
2.7 KiB
C++

// RadialSliceWidget.cpp
#include "RadialSliceWidget.h"
#include "Components/Image.h"
#include "Components/CanvasPanelSlot.h"
#include "Materials/MaterialInstanceDynamic.h"
void URadialSliceWidget::NativeConstruct()
{
Super::NativeConstruct();
}
void URadialSliceWidget::Setup(UMaterialInterface* InSliceMaterial,
float StartAngleDeg, float AngleSizeDeg, UTexture2D* Icon, bool bEnabled)
{
bSliceEnabled = bEnabled;
if (InSliceMaterial && WedgeImage)
{
WedgeMID = UMaterialInstanceDynamic::Create(InSliceMaterial, this);
WedgeImage->SetBrushFromMaterial(WedgeMID);
// Per-slice angular span (normalized 0..1). The material draws only the
// arc between these two, so each slice is an independent wedge.
WedgeMID->SetScalarParameterValue(TEXT("StartAngle"), StartAngleDeg / 360.f);
WedgeMID->SetScalarParameterValue(TEXT("AngleSize"), AngleSizeDeg / 360.f);
WedgeMID->SetScalarParameterValue(TEXT("Highlight"), 0.f);
WedgeMID->SetScalarParameterValue(TEXT("Enabled"), bEnabled ? 1.f : 0.f);
}
if (IconImage)
{
if (Icon)
{
IconImage->SetBrushFromTexture(Icon);
}
IconImage->SetRenderOpacity(bEnabled ? 0.55f : 0.3f);
// Push the icon out along this slice's centerline so it sits inside the
// wedge rather than at the menu's center. Center angle is measured
// clockwise from 12 o'clock, matching the wedge the material draws.
const float CenterAngleDeg = StartAngleDeg + AngleSizeDeg * 0.5f;
const float CenterAngleRad = FMath::DegreesToRadians(CenterAngleDeg);
const float OffsetX = FMath::Sin(CenterAngleRad) * IconRadius;
const float OffsetY = -FMath::Cos(CenterAngleRad) * IconRadius;
if (UCanvasPanelSlot* IconSlot = Cast<UCanvasPanelSlot>(IconImage->Slot))
{
// Anchor + align to center so Position is relative to the menu's
// middle; then offset out to the slice center.
IconSlot->SetAnchors(FAnchors(0.5f, 0.5f));
IconSlot->SetAlignment(FVector2D(0.5f, 0.5f));
IconSlot->SetPosition(FVector2D(OffsetX, OffsetY));
}
}
}
void URadialSliceWidget::UpdateHighlight(bool bIsHovered, float UndilatedDelta)
{
const float Target = bIsHovered && bSliceEnabled ? 1.f : 0.f;
CurrentHighlight = FMath::FInterpTo(CurrentHighlight, Target,
UndilatedDelta, HighlightInterpSpeed);
if (WedgeMID)
{
WedgeMID->SetScalarParameterValue(TEXT("Highlight"), CurrentHighlight);
}
if (IconImage && bSliceEnabled)
{
// Icon brightens from its dim resting state up to full on hover.
IconImage->SetRenderOpacity(FMath::Lerp(0.55f, 1.0f, CurrentHighlight));
}
}