Initial code for radial rendering
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
#include "RadialMenu.h"
|
#include "RadialMenu.h"
|
||||||
|
#include "Rendering/DrawElements.h"
|
||||||
|
#include "Widgets/SLeafWidget.h"
|
||||||
|
|
||||||
|
|
||||||
void URadialMenu::Configure(int32 NItems, float ItemHeight, float InnerRadius, float MinSpoke, float Spread)
|
void URadialMenuLayout::Configure(int32 NItems, float ItemHeight, float InnerRadius, float MinSpoke, float Spread)
|
||||||
{
|
{
|
||||||
NumRight = (NItems / 2);
|
NumRight = (NItems / 2);
|
||||||
NumLeft = NItems - NumRight;
|
NumLeft = NItems - NumRight;
|
||||||
@@ -21,7 +23,7 @@ void URadialMenu::Configure(int32 NItems, float ItemHeight, float InnerRadius, f
|
|||||||
FlipHorizontal(LeftItems);
|
FlipHorizontal(LeftItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector2D URadialMenu::SpokeVector(int32 I, int32 NSide, int32 NTotal)
|
FVector2D URadialMenuLayout::SpokeVector(int32 I, int32 NSide, int32 NTotal)
|
||||||
{
|
{
|
||||||
double SpokeAngle = 1.0 / NTotal;
|
double SpokeAngle = 1.0 / NTotal;
|
||||||
double OffsetAngle = 0.5 * (0.5 - ((NSide - 1) * SpokeAngle));
|
double OffsetAngle = 0.5 * (0.5 - ((NSide - 1) * SpokeAngle));
|
||||||
@@ -30,7 +32,7 @@ FVector2D URadialMenu::SpokeVector(int32 I, int32 NSide, int32 NTotal)
|
|||||||
return FVector2D(FMath::Sin(Radians), -FMath::Cos(Radians));
|
return FVector2D(FMath::Sin(Radians), -FMath::Cos(Radians));
|
||||||
}
|
}
|
||||||
|
|
||||||
void URadialMenu::FlipHorizontal(View V)
|
void URadialMenuLayout::FlipHorizontal(View V)
|
||||||
{
|
{
|
||||||
for (FRadialMenuItem& Item : V)
|
for (FRadialMenuItem& Item : V)
|
||||||
{
|
{
|
||||||
@@ -41,7 +43,7 @@ void URadialMenu::FlipHorizontal(View V)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double URadialMenu::WidestSpoke(View V)
|
double URadialMenuLayout::WidestSpoke(View V)
|
||||||
{
|
{
|
||||||
double Result = 0.0;
|
double Result = 0.0;
|
||||||
for (const FRadialMenuItem &Item : V)
|
for (const FRadialMenuItem &Item : V)
|
||||||
@@ -51,7 +53,7 @@ double URadialMenu::WidestSpoke(View V)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void URadialMenu::CalculateSpread(View V, double Offset)
|
void URadialMenuLayout::CalculateSpread(View V, double Offset)
|
||||||
{
|
{
|
||||||
for (FRadialMenuItem &Item : V)
|
for (FRadialMenuItem &Item : V)
|
||||||
{
|
{
|
||||||
@@ -59,7 +61,7 @@ void URadialMenu::CalculateSpread(View V, double Offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void URadialMenu::CalculateSpokes(View V, float ItemHeight, float InnerRadius, float MinSpoke)
|
void URadialMenuLayout::CalculateSpokes(View V, float ItemHeight, float InnerRadius, float MinSpoke)
|
||||||
{
|
{
|
||||||
if (V.Num() == 0) return;
|
if (V.Num() == 0) return;
|
||||||
|
|
||||||
@@ -101,3 +103,98 @@ void URadialMenu::CalculateSpokes(View V, float ItemHeight, float InnerRadius, f
|
|||||||
V[Mid].Point2.X = V[Mid + 1].Point2.X;
|
V[Mid].Point2.X = V[Mid + 1].Point2.X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Slate widget that paints the radial menu's polylines.
|
||||||
|
class SRadialMenu : public SLeafWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLATE_BEGIN_ARGS(SRadialMenu) {}
|
||||||
|
SLATE_END_ARGS()
|
||||||
|
|
||||||
|
void Construct(const FArguments& InArgs, URadialMenuLayout* InLayout)
|
||||||
|
{
|
||||||
|
Layout = InLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Refresh()
|
||||||
|
{
|
||||||
|
Invalidate(EInvalidateWidgetReason::Layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual FVector2D ComputeDesiredSize(float) const override
|
||||||
|
{
|
||||||
|
if (!Layout.IsValid()) return FVector2D::ZeroVector;
|
||||||
|
FVector2D Min(0.0, 0.0);
|
||||||
|
FVector2D Max(0.0, 0.0);
|
||||||
|
for (const FRadialMenuItem &Item : Layout->GetItems())
|
||||||
|
{
|
||||||
|
for (const FVector2D &P : { Item.Point1, Item.Point2, Item.Point3 })
|
||||||
|
{
|
||||||
|
Min.X = FMath::Min(Min.X, P.X);
|
||||||
|
Min.Y = FMath::Min(Min.Y, P.Y);
|
||||||
|
Max.X = FMath::Max(Max.X, P.X);
|
||||||
|
Max.Y = FMath::Max(Max.Y, P.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Symmetric around the origin so the menu draws centered.
|
||||||
|
double HalfW = FMath::Max(FMath::Abs(Min.X), FMath::Abs(Max.X));
|
||||||
|
double HalfH = FMath::Max(FMath::Abs(Min.Y), FMath::Abs(Max.Y));
|
||||||
|
return FVector2D(HalfW * 2.0, HalfH * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
|
||||||
|
const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements,
|
||||||
|
int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override
|
||||||
|
{
|
||||||
|
if (!Layout.IsValid()) return LayerId;
|
||||||
|
|
||||||
|
const FVector2D Center = AllottedGeometry.GetLocalSize() * 0.5;
|
||||||
|
const FLinearColor Color = InWidgetStyle.GetColorAndOpacityTint();
|
||||||
|
const FPaintGeometry PaintGeom = AllottedGeometry.ToPaintGeometry();
|
||||||
|
|
||||||
|
for (const FRadialMenuItem &Item : Layout->GetItems())
|
||||||
|
{
|
||||||
|
TArray<FVector2D> Points;
|
||||||
|
Points.Add(Center + Item.Point1);
|
||||||
|
Points.Add(Center + Item.Point2);
|
||||||
|
Points.Add(Center + Item.Point3);
|
||||||
|
FSlateDrawElement::MakeLines(OutDrawElements, LayerId, PaintGeom, Points, ESlateDrawEffect::None, Color, true, 1.0f);
|
||||||
|
}
|
||||||
|
return LayerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TWeakObjectPtr<URadialMenuLayout> Layout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void URadialMenuWidget::Configure(int32 NItems, float ItemHeight, float InnerRadius, float MinSpoke, float Spread)
|
||||||
|
{
|
||||||
|
if (!Layout)
|
||||||
|
{
|
||||||
|
Layout = NewObject<URadialMenuLayout>(this);
|
||||||
|
}
|
||||||
|
Layout->Configure(NItems, ItemHeight, InnerRadius, MinSpoke, Spread);
|
||||||
|
if (MySlateWidget.IsValid())
|
||||||
|
{
|
||||||
|
MySlateWidget->Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedRef<SWidget> URadialMenuWidget::RebuildWidget()
|
||||||
|
{
|
||||||
|
if (!Layout)
|
||||||
|
{
|
||||||
|
Layout = NewObject<URadialMenuLayout>(this);
|
||||||
|
}
|
||||||
|
MySlateWidget = SNew(SRadialMenu, Layout);
|
||||||
|
return MySlateWidget.ToSharedRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
void URadialMenuWidget::ReleaseSlateResources(bool bReleaseChildren)
|
||||||
|
{
|
||||||
|
Super::ReleaseSlateResources(bReleaseChildren);
|
||||||
|
MySlateWidget.Reset();
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,8 +6,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "Components/Widget.h"
|
||||||
#include "RadialMenu.generated.h"
|
#include "RadialMenu.generated.h"
|
||||||
|
|
||||||
|
class SRadialMenu;
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct FRadialMenuItem
|
struct FRadialMenuItem
|
||||||
@@ -21,7 +24,7 @@ struct FRadialMenuItem
|
|||||||
};
|
};
|
||||||
|
|
||||||
UCLASS(BlueprintType)
|
UCLASS(BlueprintType)
|
||||||
class URadialMenu : public UObject
|
class URadialMenuLayout : public UObject
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -36,7 +39,7 @@ public:
|
|||||||
int32 RightNum() const { return NumRight; }
|
int32 RightNum() const { return NumRight; }
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
const TArray<FRadialMenuItem> GetItems() const { return Items; }
|
const TArray<FRadialMenuItem> &GetItems() const { return Items; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -75,3 +78,27 @@ private:
|
|||||||
int32 NumRight = 0;
|
int32 NumRight = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS(BlueprintType, Blueprintable)
|
||||||
|
class URadialMenuWidget : public UWidget
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void Configure(int32 NItems, float ItemHeight, float InnerRadius, float MinSpoke, float Spread);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
URadialMenuLayout* GetLayout() const { return Layout; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual TSharedRef<SWidget> RebuildWidget() override;
|
||||||
|
virtual void ReleaseSlateResources(bool bReleaseChildren) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UPROPERTY()
|
||||||
|
TObjectPtr<URadialMenuLayout> Layout;
|
||||||
|
|
||||||
|
TSharedPtr<SRadialMenu> MySlateWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
2
build.py
2
build.py
@@ -408,7 +408,7 @@ def build_clean():
|
|||||||
which resets your git repository to its pristine state.
|
which resets your git repository to its pristine state.
|
||||||
DANGER: this deletes any new source code you've created!
|
DANGER: this deletes any new source code you've created!
|
||||||
"""
|
"""
|
||||||
shell(f"{INTEGRATION}/luprex", "make clean")
|
shell(f"{INTEGRATION}", "make -f luprex/Makefile clean")
|
||||||
shell(INTEGRATION, f"{UNREALENGINE}/Engine/Build/BatchFiles/{BUILD_BAT} -waitmutex IntegrationEditor {OS} {DEBUG} {INTEGRATION}/Integration.uproject -clean")
|
shell(INTEGRATION, f"{UNREALENGINE}/Engine/Build/BatchFiles/{BUILD_BAT} -waitmutex IntegrationEditor {OS} {DEBUG} {INTEGRATION}/Integration.uproject -clean")
|
||||||
Path(f"{INTEGRATION}/.vscode/compile_commands.json").unlink(missing_ok = True)
|
Path(f"{INTEGRATION}/.vscode/compile_commands.json").unlink(missing_ok = True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user