文本框套了缩放框,换行逻辑与预期不符问题

缩放框的逻辑是缩放下方控件大小从而满足可以放入父级空间内;会导致已经换行的文本框需要被塞入父级空间时,变成整体缩放;最终结果就是换行后的文本框的文字换行位置与预期不符,我们需要原生的文本控件支持固定大小区域内,满足换行需求且同时支持如果区域内放置不下时可以缩小文本大小的功能,不知道5.6版本的引擎是否支持,不支持的话是否有其他方法可以实现。

[Attachment Removed]

您好。首先这个应该是ScaleBox缩放的时候,但是文本框的Auto Wrap Text的计算仍然是缩放前导致的。我想进一步了解你最终想要的效果,能否举个例子来表述下你最终想要的效果,然后我看下怎么改比较合适。理论上可以通过TextBox的ForceLayoutPrepass()这个函数来达到目的。但是我需要更详细的了解下您这边的需求。

[Attachment Removed]

大概的代码是现在ETextOverflowPolicy枚举里加一个新类型,选择这个类型时就是匹配Font大小。

UENUM(BlueprintType)
enum class ETextOverflowPolicy : uint8
{
	/** Overflowing text will be clipped */
	Clip = 0,
 
	/** Overflowing text will be replaced with an ellipsis */
	Ellipsis,
 
	/** Overflowing text will be replaced with an ellipsis. A partially clipped line on the vertical axis will be totally clipped, and ellipsis displayed on previous line */
	MultilineEllipsis,
 
	/** Overflowing text will be replaced with an ellipsis starting from the center\n
	 * Current Limits:
	 * - Multiline is not supported
	 * - RichText is not fully supported
	 * - Highlight text is not supported
	 * - Arabic mix with western character is not supported
	 */
	MiddleEllipsis,
 
	AutoFit
};

然后在FSlateTextLayout::OnPaint里,if (bIsMultiline)之后处理overflowPolicy的时候加上

// ========== AutoScale 处理 ==========
if (OverflowPolicy == ETextOverflowPolicy::AutoFit)
{
	const float AvailableWidth = AllottedGeometry.GetLocalSize().X - Margin.GetTotalSpaceAlong<Orient_Horizontal>();
	const float CurrentScale = GetScale();
 
	// 检查是否需要缩放
	if (GetWrappedDrawSize().X > AvailableWidth && AvailableWidth > 0)
	{
		float NewScale = (AvailableWidth / GetWrappedDrawSize().X);
		NewScale = FMath::Clamp(NewScale, 0.5f, 1.0f);
 
		if (!FMath::IsNearlyEqual(CurrentScale, NewScale, 0.001f))
		{
			FSlateTextLayout* TextLayout = const_cast<FSlateTextLayout*>(this);
			TextLayout->SetScale(NewScale);
			TextLayout->DirtyLayout();
			TextLayout->UpdateIfNeeded();
		}
	}
}
// ========== AutoScale 结束 ==========

应该就能实现需要的功能,但是细节还需要你们自己打磨下。

[Attachment Removed]