Files
UnrealEngine/Engine/Source/Developer/ToolWidgets/Private/Sidebar/SSidebarButtonText.cpp
2025-05-18 13:04:45 +08:00

89 lines
3.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SSidebarButtonText.h"
#include "Framework/Application/SlateApplication.h"
#include "Framework/Text/PlainTextLayoutMarshaller.h"
#include "Widgets/Text/SlateTextBlockLayout.h"
#define LOCTEXT_NAMESPACE "SSidebarButtonText"
void SSidebarButtonText::Construct(const FArguments& InArgs)
{
Text = InArgs._Text;
TextStyle = *InArgs._TextStyle;
AngleDegrees = InArgs._AngleDegrees;
TextLayoutCache = MakeUnique<FSlateTextBlockLayout>(this
, FTextBlockStyle::GetDefault()
, TOptional<ETextShapingMethod>()
, TOptional<ETextFlowDirection>()
, FCreateSlateTextLayout()
, FPlainTextLayoutMarshaller::Create()
, nullptr);
TextLayoutCache->SetTextOverflowPolicy(InArgs._OverflowPolicy.IsSet() ? InArgs._OverflowPolicy : TextStyle.OverflowPolicy);
}
int32 SSidebarButtonText::OnPaint(const FPaintArgs& InArgs, const FGeometry& InAllottedGeometry, const FSlateRect& InCullingRect
, FSlateWindowElementList& OutDrawElements, int32 InLayerId, const FWidgetStyle& InWidgetStyle, bool bInParentEnabled) const
{
// We're going to figure out the bounds of the corresponding horizontal text, and then rotate it into a vertical orientation.
const FVector2D LocalSize = InAllottedGeometry.GetLocalSize();
const FVector2D DesiredHorizontalTextSize = TextLayoutCache->GetDesiredSize();
const FVector2D ActualHorizontalTextSize(FMath::Min(DesiredHorizontalTextSize.X, LocalSize.Y), FMath::Min(DesiredHorizontalTextSize.Y, LocalSize.X));
// Now determine the center of the vertical text by rotating the dimensions of the horizontal text.
// The center should align it to the top of the widget.
const FVector2D VerticalTextSize(ActualHorizontalTextSize.Y, ActualHorizontalTextSize.X);
const FVector2D VerticalTextCenter = VerticalTextSize * 0.5f;
// Now determine where the horizontal text should be positioned so that it is centered on the vertical text:
// +-+
// |v|
// |e|
// [ horizontal ]
// |r|
// |t|
// +-+
const FVector2D HorizontalTextPosition = VerticalTextCenter - (ActualHorizontalTextSize * 0.5f);
// Define the text's geometry using the horizontal bounds, then rotate it 90/-90 degrees into place to become vertical.
const FSlateRenderTransform RotationTransform(FSlateRenderTransform(FQuat2D(FMath::DegreesToRadians(AngleDegrees.Get(0.f)))));
const FGeometry TextGeometry = InAllottedGeometry.MakeChild(ActualHorizontalTextSize
, FSlateLayoutTransform(HorizontalTextPosition), RotationTransform, FVector2D(0.5f, 0.5f));
return TextLayoutCache->OnPaint(InArgs, TextGeometry, InCullingRect, OutDrawElements, InLayerId, InWidgetStyle, ShouldBeEnabled(bInParentEnabled));
}
FVector2D SSidebarButtonText::ComputeDesiredSize(const float LayoutScaleMultiplier) const
{
// The text's desired size reflects the horizontal/untransformed text.
// Switch the dimensions for vertical text.
const FVector2D DesiredHorizontalTextSize = TextLayoutCache->ComputeDesiredSize(
FSlateTextBlockLayout::FWidgetDesiredSizeArgs(
Text.Get(),
FText(),
0.f,
false,
ETextWrappingPolicy::DefaultWrapping,
ETextTransformPolicy::None,
FMargin(),
1.f,
true,
ETextJustify::Left),
LayoutScaleMultiplier, TextStyle);
return FVector2D(DesiredHorizontalTextSize.Y, DesiredHorizontalTextSize.X);
}
void SSidebarButtonText::SetText(const TAttribute<FText>& InText)
{
Text = InText;
}
void SSidebarButtonText::SetRotation(const TAttribute<float>& InAngleDegrees)
{
AngleDegrees = InAngleDegrees;
}
#undef LOCTEXT_NAMESPACE