Started radial menu setup
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
// RadialMenuWidget.cpp
|
||||
|
||||
#include "RadialMenuWidget.h"
|
||||
#include "RadialSliceWidget.h"
|
||||
#include "Components/CanvasPanel.h"
|
||||
#include "Components/CanvasPanelSlot.h"
|
||||
#include "Input/CommonUIInputTypes.h" // FBindUIActionArgs
|
||||
|
||||
void URadialMenuWidget::InitializeFromController(
|
||||
URadialMenuController* InController, const TArray<FRadialMenuEntry>& InEntries)
|
||||
{
|
||||
OwningController = InController;
|
||||
BuildSlices(InEntries);
|
||||
}
|
||||
|
||||
void URadialMenuWidget::NativeOnActivated()
|
||||
{
|
||||
Super::NativeOnActivated();
|
||||
|
||||
SetIsFocusable(true);
|
||||
|
||||
// Bind Confirm. FBindUIActionArgs accepts the row handle directly.
|
||||
if (!ConfirmAction.IsNull())
|
||||
{
|
||||
FBindUIActionArgs ConfirmArgs(
|
||||
ConfirmAction,
|
||||
FSimpleDelegate::CreateUObject(this, &URadialMenuWidget::HandleConfirm));
|
||||
// Show in the on-screen action bar so the player sees the prompt.
|
||||
ConfirmArgs.bDisplayInActionBar = true;
|
||||
ConfirmHandle = RegisterUIActionBinding(ConfirmArgs);
|
||||
}
|
||||
|
||||
if (!BackAction.IsNull())
|
||||
{
|
||||
FBindUIActionArgs BackArgs(
|
||||
BackAction,
|
||||
FSimpleDelegate::CreateUObject(this, &URadialMenuWidget::HandleBack));
|
||||
BackArgs.bDisplayInActionBar = true;
|
||||
BackHandle = RegisterUIActionBinding(BackArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void URadialMenuWidget::NativeOnDeactivated()
|
||||
{
|
||||
// Clean up bindings so they don't linger if the widget is pooled/reused.
|
||||
if (ConfirmHandle.IsValid())
|
||||
{
|
||||
ConfirmHandle.Unregister();
|
||||
}
|
||||
if (BackHandle.IsValid())
|
||||
{
|
||||
BackHandle.Unregister();
|
||||
}
|
||||
|
||||
Super::NativeOnDeactivated();
|
||||
}
|
||||
|
||||
UWidget* URadialMenuWidget::NativeGetDesiredFocusTarget() const
|
||||
{
|
||||
// Keep focus on the menu root so the bound actions receive input.
|
||||
return const_cast<URadialMenuWidget*>(this);
|
||||
}
|
||||
|
||||
void URadialMenuWidget::HandleConfirm()
|
||||
{
|
||||
// Route to the controller, which owns the state, time dilation, and the
|
||||
// OnSelectionConfirmed broadcast. The controller also tears down the widget.
|
||||
if (OwningController.IsValid())
|
||||
{
|
||||
OwningController->CloseAndConfirm();
|
||||
}
|
||||
}
|
||||
|
||||
void URadialMenuWidget::HandleBack()
|
||||
{
|
||||
if (OwningController.IsValid())
|
||||
{
|
||||
OwningController->CloseAndCancel();
|
||||
}
|
||||
}
|
||||
|
||||
void URadialMenuWidget::BuildSlices(const TArray<FRadialMenuEntry>& InEntries)
|
||||
{
|
||||
if (!SliceCanvas || !SliceWidgetClass)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SliceCanvas->ClearChildren();
|
||||
Slices.Reset();
|
||||
HoveredIndex = -1;
|
||||
|
||||
const int32 Count = InEntries.Num();
|
||||
if (Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float AngleSize = 360.f / Count;
|
||||
|
||||
for (int32 i = 0; i < Count; ++i)
|
||||
{
|
||||
URadialSliceWidget* Slice =
|
||||
CreateWidget<URadialSliceWidget>(GetOwningPlayer(), SliceWidgetClass);
|
||||
if (!Slice)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const float StartAngle = i * AngleSize - AngleSize * 0.5f;
|
||||
Slice->Setup(SliceMaterial, StartAngle, AngleSize,
|
||||
InEntries[i].Icon, InEntries[i].bEnabled);
|
||||
|
||||
SliceCanvas->AddChild(Slice);
|
||||
if (UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(Slice->Slot))
|
||||
{
|
||||
CanvasSlot->SetAnchors(FAnchors(0.5f, 0.5f));
|
||||
CanvasSlot->SetAlignment(FVector2D(0.5f, 0.5f));
|
||||
CanvasSlot->SetPosition(FVector2D::ZeroVector);
|
||||
CanvasSlot->SetSize(FVector2D(MenuDiameter, MenuDiameter));
|
||||
}
|
||||
|
||||
Slices.Add(Slice);
|
||||
}
|
||||
}
|
||||
|
||||
void URadialMenuWidget::SetHoveredSegment(int32 Index)
|
||||
{
|
||||
HoveredIndex = Index;
|
||||
}
|
||||
|
||||
void URadialMenuWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
|
||||
{
|
||||
Super::NativeTick(MyGeometry, InDeltaTime);
|
||||
|
||||
const float RealDelta = FApp::GetDeltaTime(); // undilated
|
||||
|
||||
for (int32 i = 0; i < Slices.Num(); ++i)
|
||||
{
|
||||
if (Slices[i])
|
||||
{
|
||||
Slices[i]->UpdateHighlight(i == HoveredIndex, RealDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user