首
RichTextBlock使用方式参考官方文档:RichTextBlockUE
文档中描述了不同样式文字以及图片的使用,但没有具体说明超链接的实现,但库中有hyperlink结构。
因此照猫画虎实现,仿照RichImgDecorator实现。
体
- 首先在build.cs 里增加Slate引用
PrivateDependencyModuleNames.AddRange(
new string[]
{
"UMG",
"Slate",
"SlateCore",
});
- 编写SRichTextHyperlink_Ex.h文件 基于SRichTextHyperlink的拓展,增加点击回调href连接地址。
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "SlateGlobals.h"
#include "Input/Reply.h"
#include "Layout/Margin.h"
#include "Styling/SlateTypes.h"
#include "Framework/Text/SlateHyperlinkRun.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Styling/CoreStyle.h"
#include "Widgets/Input/SHyperlink.h"
class FWidgetViewModel;
enum class ETextShapingMethod : uint8;
DECLARE_DELEGATE_TwoParams(FHyperlinkDelegate,FString ,FString);
#if WITH_FANCY_TEXT
class SRichTextHyperlink_Ex : public SHyperlink
{
public:
SLATE_BEGIN_ARGS(SRichTextHyperlink_Ex)
: _Text()
, _Href()
, _Type()
, _Style(&FCoreStyle::Get().GetWidgetStyle< FHyperlinkStyle >("Hyperlink"))
, _TextStyle(nullptr)
, _UnderlineStyle(nullptr)
, _Delegate()
, _Padding()
, _OnNavigate()
, _TextShapingMethod()
, _TextFlowDirection()
{}
SLATE_ATTRIBUTE( FText, Text )
SLATE_ARGUMENT( FString , Href )
SLATE_ARGUMENT( FString , Type )
SLATE_STYLE_ARGUMENT( FHyperlinkStyle, Style )
SLATE_STYLE_ARGUMENT( FTextBlockStyle, TextStyle )
SLATE_STYLE_ARGUMENT( FButtonStyle, UnderlineStyle )
SLATE_ATTRIBUTE( FMargin, Padding )
SLATE_EVENT( FSimpleDelegate, OnNavigate )
SLATE_EVENT( FHyperlinkDelegate, Delegate )
SLATE_ARGUMENT( TOptional<ETextShapingMethod>, TextShapingMethod )
SLATE_ARGUMENT( TOptional<ETextFlowDirection>, TextFlowDirection )
SLATE_END_ARGS()
public:
void Construct( const FArguments& InArgs, const TSharedRef< FSlateHyperlinkRun::FWidgetViewModel >& InViewModel );
FReply OnClicked () const;
virtual void OnMouseEnter( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override
{
SHyperlink::OnMouseEnter( MyGeometry, MouseEvent );
ViewModel->SetIsHovered( true );
}
virtual void OnMouseLeave( const FPointerEvent& MouseEvent ) override
{
SHyperlink::OnMouseLeave( MouseEvent );
ViewModel->SetIsHovered( false );
}
virtual FReply OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override
{
FReply Reply = SHyperlink::OnMouseButtonDown( MyGeometry, MouseEvent );
ViewModel->SetIsPressed( bIsPressed );
return Reply;
}
virtual FReply OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override
{
FReply Reply = SHyperlink::OnMouseButtonUp( MyGeometry, MouseEvent );
ViewModel->SetIsPressed( bIsPressed );
return Reply;
}
virtual bool IsHovered() const override
{
return ViewModel->IsHovered();
}
virtual bool IsPressed() const override
{
return ViewModel->IsPressed();
}
private:
FHyperlinkDelegate HyperDelegate;
FString Href ;
FString Type ;
TSharedPtr< FSlateHyperlinkRun::FWidgetViewModel > ViewModel;
};
#endif //WITH_FANCY_TEXT
- UHyperlinkRichTextBlockDecorator.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "RichTextBlockDecorator.h"
#include "SRichTextHyperlink_Ex.h"
#include "HyperlinkRichTextBlockDecorator.generated.h"
USTRUCT(Blueprintable, BlueprintType)
struct CLOUDGAME_API FRichHyperlinkRow : public FTableRowBase
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(EditAnywhere, Category = Appearance)
FHyperlinkStyle HlStyle;
};
/**
*
*/
UCLASS(Abstract, Blueprintable)
class CLOUDGAME_API UHyperlinkRichTextBlockDecorator : public URichTextBlockDecorator
{
GENERATED_BODY()
public:
UHyperlinkRichTextBlockDecorator(const FObjectInitializer& ObjectInitializer);
virtual TSharedPtr<ITextDecorator> CreateDecorator(URichTextBlock* InOwner) override;
virtual const FHyperlinkStyle* FindHyperlinkStyle(FName TagOrId, bool bWarnIfMissing);
void OnClickHyperlink(FString Type,FString Href);
protected:
FRichHyperlinkRow* FindHyperlinkRow(FName TagOrId, bool bWarningIfMissing);
UPROPERTY(EditAnywhere, Category = Appearance, meta = (RequiredAssetDataTags = "RowStructure=RichHyperlinkRow"))
class UDataTable* HyperlinkSet;
};
- FHyperlinkRichTextDecorator.h
#pragma once
#include "CoreMinimal.h"
#include "HyperlinkRichTextBlockDecorator.h"
/**
*
*/
class CLOUDGAME_API FHyperlinkRichTextDecorator : public FRichTextDecorator
{
public:
FHyperlinkRichTextDecorator(URichTextBlock* InOwner, UHyperlinkRichTextBlockDecorator* InDecorator);
virtual bool Supports(const FTextRunParseResults& RunParseResult, const FString& Text) const override;
protected:
virtual TSharedPtr<SWidget> CreateDecoratorWidget(const FTextRunInfo& RunInfo, const FTextBlockStyle& TextStyle) const override;
private:
UHyperlinkRichTextBlockDecorator* Decorator;
FHyperlinkDelegate HlDelegate;
FString ParseName = FString("a");
};
- SRichTextHyperlink_Ex.cpp
#include "UMG/Hyperlink/SRichTextHyperlink_Ex.h"
void SRichTextHyperlink_Ex::Construct(const FArguments& InArgs, const TSharedRef<FSlateHyperlinkRun::FWidgetViewModel>& InViewModel)
{
ViewModel = InViewModel;
this->HyperDelegate = InArgs._Delegate;
this->Href = InArgs._Href;
this->Type = InArgs._Type;
check (InArgs._Style);
const FButtonStyle* UnderlineStyle = InArgs._UnderlineStyle != nullptr ? InArgs._UnderlineStyle : &InArgs._Style->UnderlineStyle;
const FTextBlockStyle* TextStyle = InArgs._TextStyle != nullptr ? InArgs._TextStyle : &InArgs._Style->TextStyle;
TAttribute<FMargin> Padding = InArgs._Padding.IsSet() ? InArgs._Padding : InArgs._Style->Padding;
SButton::Construct(
SButton::FArguments()
.Text( InArgs._Text )
.ContentPadding( Padding )
.ButtonStyle( UnderlineStyle )
.TextStyle( TextStyle )
.OnClicked(FOnClicked::CreateRaw(this,&SRichTextHyperlink_Ex::OnClicked))
.ForegroundColor(FSlateColor::UseForeground())
.TextShapingMethod( InArgs._TextShapingMethod )
.TextFlowDirection( InArgs._TextFlowDirection )
);
}
FReply SRichTextHyperlink_Ex::OnClicked() const
{
HyperDelegate.ExecuteIfBound(Type, Href);
return FReply::Handled();
}
- HyperlinkRichTextBlockDecorator.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Hyperlink/HyperlinkRichTextBlockDecorator.h"
#include "GEventSubsystem.h"
#include "Hyperlink/HyperlinkRichTextDecorator.h"
UHyperlinkRichTextBlockDecorator::UHyperlinkRichTextBlockDecorator(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
{
}
TSharedPtr<ITextDecorator> UHyperlinkRichTextBlockDecorator::CreateDecorator(URichTextBlock* InOwner)
{
return MakeShareable(new FHyperlinkRichTextDecorator(InOwner, this));
}
const FHyperlinkStyle* UHyperlinkRichTextBlockDecorator::FindHyperlinkStyle(FName TagOrId, bool bWarnIfMissing)
{
const FRichHyperlinkRow* HlRow = FindHyperlinkRow(TagOrId, bWarnIfMissing);
if (HlRow)
{
return &HlRow->HlStyle;
}
return nullptr;
}
void UHyperlinkRichTextBlockDecorator::OnClickHyperlink( FString Type,FString Href)
{
UE_LOG(LogTemp,Display,TEXT("OnClickHyperlink type = %s ; href = %s"),*Type,*Href)
}
FRichHyperlinkRow* UHyperlinkRichTextBlockDecorator::FindHyperlinkRow(FName TagOrId, bool bWarningIfMissing)
{
if (HyperlinkSet)
{
FString ContextString;
return HyperlinkSet->FindRow<FRichHyperlinkRow>(TagOrId, ContextString, bWarningIfMissing);
}
return nullptr;
}
- HyperlinkRichTextDecorator.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Hyperlink/HyperlinkRichTextDecorator.h"
FHyperlinkRichTextDecorator::FHyperlinkRichTextDecorator(URichTextBlock* InOwner, UHyperlinkRichTextBlockDecorator* InDecorator)
: FRichTextDecorator(InOwner),Decorator(InDecorator)
{
HlDelegate.BindUObject(Decorator,&UHyperlinkRichTextBlockDecorator::OnClickHyperlink);
}
bool FHyperlinkRichTextDecorator::Supports(const FTextRunParseResults& RunParseResult, const FString& Text) const
{
if (RunParseResult.Name == ParseName && RunParseResult.MetaData.Contains(TEXT("id")))
{
const FTextRange& IdRange = RunParseResult.MetaData[TEXT("id")];
const FString TagId = Text.Mid(IdRange.BeginIndex, IdRange.EndIndex - IdRange.BeginIndex);
const bool bWarnIfMissing = false;
return Decorator->FindHyperlinkStyle(*TagId, bWarnIfMissing) != nullptr;
}
return false;
}
TSharedPtr<SWidget> FHyperlinkRichTextDecorator::CreateDecoratorWidget(const FTextRunInfo& RunInfo,
const FTextBlockStyle& TextStyle) const
{
const bool bWarnIfMissing = false;
const FHyperlinkStyle* HlStyle = Decorator->FindHyperlinkStyle(*RunInfo.MetaData[TEXT("id")], bWarnIfMissing);
const FString* Href = RunInfo.MetaData.Find(TEXT("href"));
const FString* Type = RunInfo.MetaData.Find(TEXT("id"));
const TSharedPtr<FSlateHyperlinkRun::FWidgetViewModel> Model = MakeShareable(new FSlateHyperlinkRun::FWidgetViewModel);
TSharedPtr<SRichTextHyperlink_Ex> HlWidget = SNew(SRichTextHyperlink_Ex,Model.ToSharedRef())
.Text(RunInfo.Content)
.Style(HlStyle)
.Href(FString(*Href))
.Type(FString(*Type))
.Delegate(HlDelegate);
return HlWidget;
}
-
然后项目中引用,使用方式与richimg保持一直,创建蓝图时选择hyperlinkDecorator为父类。数据方式为:
<a id="name" href="content">点击我</>
点击ui中的点击我 会打印 onclick的数据 type为name href为 content;
尾
参考连接:
https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/UMG/UserGuide/UMGRichTextBlock/文章来源:https://www.toymoban.com/news/detail-485245.html
https://forums.unrealengine.com/t/umg-richtextblock-hyperlink-href-markup/454860文章来源地址https://www.toymoban.com/news/detail-485245.html
到了这里,关于【UE】富文本块(RichTextBlock) 增加超链接支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!