107 lines
4.4 KiB
C++
107 lines
4.4 KiB
C++
// RadialMenuWidget.h
|
|
// Container for the radial menu, now a CommonUI activatable widget. It owns the
|
|
// CommonUI input bindings (Confirm / Back) and routes them to the controller,
|
|
// which still owns all state (time dilation, hover, Entries). The widget also
|
|
// spawns one URadialSliceWidget per entry at runtime (variable slice count).
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "CommonActivatableWidget.h"
|
|
#include "Engine/DataTable.h" // FDataTableRowHandle
|
|
#include "RadialMenuController.h" // for FRadialMenuEntry
|
|
#include "RadialMenuWidget.generated.h"
|
|
|
|
class UCanvasPanel;
|
|
class URadialSliceWidget;
|
|
struct FUIActionBindingHandle;
|
|
|
|
UCLASS(Abstract)
|
|
class URadialMenuWidget : public UCommonActivatableWidget
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// Called by the controller after CreateWidget, before activation. Stores the
|
|
// owning controller so action handlers can route back to it, then builds the
|
|
// slices.
|
|
void InitializeFromController(URadialMenuController* InController,
|
|
const TArray<FRadialMenuEntry>& InEntries);
|
|
|
|
// Called when the hovered slice changes. Stored and applied each tick.
|
|
void SetHoveredSegment(int32 Index);
|
|
|
|
protected:
|
|
virtual void NativeOnActivated() override;
|
|
virtual void NativeOnDeactivated() override;
|
|
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
|
|
|
|
// Left-click confirm. Handled directly here rather than as a CommonUI action
|
|
// binding, because CommonUI routes left mouse through its Default Click Action
|
|
// system (separate from RegisterUIActionBinding), so a click-mapped action
|
|
// never reaches a normal binding. Intercepting the pointer event sidesteps that.
|
|
virtual FReply NativeOnMouseButtonDown(const FGeometry& InGeometry,
|
|
const FPointerEvent& InMouseEvent) override;
|
|
|
|
// Gamepad slice selection. When this widget is the active CommonUI node, the
|
|
// analog sticks are routed here (NOT to the PlayerController), which is why
|
|
// GetInputAnalogStickState returns 0 from the controller while a menu is up.
|
|
// We read the right stick from the analog event and drive hover directly.
|
|
virtual FReply NativeOnAnalogValueChanged(const FGeometry& InGeometry,
|
|
const FAnalogInputEvent& InAnalogEvent) override;
|
|
|
|
// CommonUI focus: returning the root keeps gamepad/keyboard focus on us so
|
|
// the bound actions fire while the wheel is open.
|
|
virtual UWidget* NativeGetDesiredFocusTarget() const override;
|
|
|
|
// --- CommonUI input action assets (assign in the widget BP defaults) ------
|
|
// CommonUI input action rows. These are FDataTableRowHandle pointing at your
|
|
// CommonInputActionDataTable rows (the same rows your other screens use for
|
|
// accept/back), so the on-screen action bar and key mapping stay consistent.
|
|
UPROPERTY(EditDefaultsOnly, Category = "Radial Menu|Input",
|
|
meta = (RowType = "/Script/CommonUI.CommonInputActionDataBase"))
|
|
FDataTableRowHandle ConfirmAction;
|
|
|
|
// Bound explicitly so our cancel path runs (restore time, broadcast -1)
|
|
// rather than CommonUI just popping the widget on Back.
|
|
UPROPERTY(EditDefaultsOnly, Category = "Radial Menu|Input",
|
|
meta = (RowType = "/Script/CommonUI.CommonInputActionDataBase"))
|
|
FDataTableRowHandle BackAction;
|
|
|
|
// Root canvas the slices are spawned into.
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UCanvasPanel> SliceCanvas = nullptr;
|
|
|
|
UPROPERTY(EditDefaultsOnly, Category = "Radial Menu")
|
|
TSubclassOf<URadialSliceWidget> SliceWidgetClass;
|
|
|
|
UPROPERTY(EditDefaultsOnly, Category = "Radial Menu")
|
|
TObjectPtr<UMaterialInterface> SliceMaterial = nullptr;
|
|
|
|
UPROPERTY(EditDefaultsOnly, Category = "Radial Menu")
|
|
float MenuDiameter = 420.f;
|
|
|
|
private:
|
|
// Action handlers, bound in NativeOnActivated.
|
|
void HandleConfirm();
|
|
void HandleBack();
|
|
|
|
void BuildSlices(const TArray<FRadialMenuEntry>& InEntries);
|
|
|
|
UPROPERTY(Transient)
|
|
TWeakObjectPtr<URadialMenuController> OwningController;
|
|
|
|
UPROPERTY(Transient)
|
|
TArray<TObjectPtr<URadialSliceWidget>> Slices;
|
|
|
|
// Handles kept so we can unregister on deactivation.
|
|
FUIActionBindingHandle ConfirmHandle;
|
|
FUIActionBindingHandle BackHandle;
|
|
|
|
int32 HoveredIndex = -1;
|
|
|
|
// Latest right-stick axis values, cached across single-axis analog events so
|
|
// we can recompute the full 2D direction whenever either axis updates.
|
|
float RightStickX = 0.f;
|
|
float RightStickY = 0.f;
|
|
}; |