// // This class implements the layout calculatations for a radial // menu. // #pragma once #include "CoreMinimal.h" #include "RadialMenu.generated.h" USTRUCT(BlueprintType) struct FRadialMenuItem { GENERATED_BODY() FVector2D Point1 = {0,0}; FVector2D Point2 = {0,0}; FVector2D Point3 = {0,0}; bool RightSide = false; }; UCLASS(BlueprintType) class URadialMenu : public UObject { GENERATED_BODY() public: UFUNCTION(BlueprintCallable) void Configure(int32 NItems, float ItemHeight, float InnerRadius, float MinSpoke, float Spread); UFUNCTION(BlueprintCallable) int32 LeftNum() const { return NumLeft; } UFUNCTION(BlueprintCallable) int32 RightNum() const { return NumRight; } UFUNCTION(BlueprintCallable) const TArray GetItems() const { return Items; } private: using View = TArrayView; // Give the unit vector for the selected spoke. NSide is // the number of spokes on the side of the wheel that // we're calculating, and NTotal is the total number of // spokes on both sides. The spokes on a given side are // organized top-to-bottom, and the angle between the // spokes is always equal to (1/NTotal) of the circle. FVector2D SpokeVector(int32 I, int32 NSide, int32 NTotal); // Populate Point1 and Point2, these are the // endpoints of the spoke segment. Spokes are // designed to always be long enough to make room // for MinSpoke, but also to make enough room to // keep the menu items from overlapping. void CalculateSpokes(View V, float ItemHeight, float InnerRadius, float MinSpoke); // Search for the widest spoke, and return its X coordinate. double WidestSpoke(View V); // Populate Point3, this is the endpoint of the spread // line that goes horizontal. void CalculateSpread(View V, double Offset); // Flip everything in the specified view horizontally. void FlipHorizontal(View V); // The array of items. TArray Items; // Number of items on the left, and on the right. int32 NumLeft = 0; int32 NumRight = 0; };