├── .gitattributes ├── .gitignore ├── Config ├── DefaultEditor.ini ├── DefaultEngine.ini ├── DefaultGame.ini └── HoloLens │ └── HoloLensEngine.ini ├── Content ├── Blueprints │ ├── BP_DemoGameMode.uasset │ └── BP_DemoPlayerController.uasset ├── Maps │ ├── DemoMap.umap │ └── DemoMap_BuiltData.uasset ├── RichTextStyleSet.uasset └── WBP_DemoWidget.uasset ├── InlineDecoProject.png ├── InlineDecoProject.uproject ├── LICENSE ├── Plugins └── RichTextBlockInlineDecorator │ ├── Config │ └── FilterPlugin.ini │ ├── Resources │ └── Icon128.png │ ├── RichTextBlockInlineDecorator.uplugin │ └── Source │ └── RichTextBlockInlineDecorator │ ├── Private │ ├── RichTextBlockInlineDecorator.cpp │ └── RichTextBlockInlineDecoratorModule.cpp │ ├── Public │ ├── RichTextBlockInlineDecorator.h │ └── RichTextBlockInlineDecoratorModule.h │ └── RichTextBlockInlineDecorator.Build.cs ├── README.md └── Source ├── InlineDecoProject.Target.cs ├── InlineDecoProject ├── InlineDecoProject.Build.cs ├── InlineDecoProject.cpp └── InlineDecoProject.h └── InlineDecoProjectEditor.Target.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | *.uasset filter=lfs diff=lfs merge=lfs -text 2 | *.dll filter=lfs diff=lfs merge=lfs -text 3 | *.umap filter=lfs diff=lfs merge=lfs -text 4 | *.png filter=lfs diff=lfs merge=lfs -text 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries 2 | /Binaries 3 | *.pdb 4 | *.dll 5 | 6 | # Plugin Intermediate and Binaries 7 | /Plugins/*/Intermediate 8 | /Plugins/*/Binaries 9 | !Plugins/**/ThirdParty/** 10 | 11 | # Builds 12 | Build/* 13 | 14 | # Releases 15 | Releases/* 16 | 17 | # Whitelist PakBlacklist-.txt files 18 | !Build/*/ 19 | Build/*/** 20 | !Build/*/PakBlacklist*.txt 21 | !Build/*.bat 22 | 23 | # Don't ignore platform resources 24 | !Build/XboxOne/** 25 | Build/XboxOne/Symbols/** 26 | Build/XboxOne/FileOpenOrder/** 27 | !Build/PS4/** 28 | Build/PS4/FileOpenOrder/** 29 | Build/PS4/Symbols/** 30 | Build/PS4/sce_module/** 31 | !Build/Switch/** 32 | Build/Switch/FileOpenOrder/** 33 | 34 | # Don't ignore icon files in Build 35 | !Build/**/*.ico 36 | 37 | # Generated project files 38 | /DerivedDataCache 39 | /Intermediate 40 | /Saved 41 | *.sdf 42 | *.sln 43 | *.v12.suo 44 | *.opensdf 45 | *.xcodeproj 46 | *.xcworkspace/ 47 | *.VC.opendb 48 | .vs/ 49 | 50 | # Temporary VS files 51 | /enc_temp_folder 52 | *.TMP 53 | 54 | # OS generated files 55 | Thumbs.db 56 | *.db 57 | .DS_Store 58 | 59 | # Art binary source 60 | *.fbx 61 | 62 | # Visual Studio Code files 63 | # Could unignore certain .json settings files if we need to 64 | .vscode/* 65 | 66 | # Merge files 67 | *.orig 68 | 69 | # Rider files 70 | .idea/* 71 | 72 | -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Acren/RichTextBlockInlineDecorator/370afa4ac95101790c9ce4547906201433a2afd2/Config/DefaultEditor.ini -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [URL] 2 | 3 | [/Script/HardwareTargeting.HardwareTargetingSettings] 4 | TargetedHardwareClass=Desktop 5 | AppliedTargetedHardwareClass=Desktop 6 | DefaultGraphicsPerformance=Maximum 7 | AppliedDefaultGraphicsPerformance=Maximum 8 | 9 | [/Script/EngineSettings.GameMapsSettings] 10 | EditorStartupMap=/Game/Maps/DemoMap.DemoMap 11 | LocalMapOptions= 12 | TransitionMap=None 13 | bUseSplitscreen=True 14 | TwoPlayerSplitscreenLayout=Horizontal 15 | ThreePlayerSplitscreenLayout=FavorTop 16 | bOffsetPlayerGamepadIds=False 17 | GameInstanceClass=/Script/Engine.GameInstance 18 | GameDefaultMap=/Game/Maps/DemoMap.DemoMap 19 | ServerDefaultMap=/Engine/Maps/Entry.Entry 20 | GlobalDefaultGameMode=/Game/Blueprints/BP_DemoGameMode.BP_DemoGameMode_C 21 | GlobalDefaultServerGameMode=None 22 | 23 | [/Script/Engine.PhysicsSettings] 24 | DefaultGravityZ=-980.000000 25 | DefaultTerminalVelocity=4000.000000 26 | DefaultFluidFriction=0.300000 27 | SimulateScratchMemorySize=262144 28 | RagdollAggregateThreshold=4 29 | TriangleMeshTriangleMinAreaThreshold=5.000000 30 | bEnableAsyncScene=False 31 | bEnableShapeSharing=False 32 | bEnablePCM=True 33 | bEnableStabilization=False 34 | bWarnMissingLocks=True 35 | bEnable2DPhysics=False 36 | PhysicErrorCorrection=(PingExtrapolation=0.100000,ErrorPerLinearDifference=1.000000,ErrorPerAngularDifference=1.000000,MaxRestoredStateError=1.000000,PositionLerp=0.000000,AngleLerp=0.400000,LinearVelocityCoefficient=100.000000,AngularVelocityCoefficient=10.000000,ErrorAccumulationSeconds=0.500000,ErrorAccumulationDistanceSq=15.000000,ErrorAccumulationSimilarity=100.000000) 37 | LockedAxis=Invalid 38 | DefaultDegreesOfFreedom=Full3D 39 | BounceThresholdVelocity=200.000000 40 | FrictionCombineMode=Average 41 | RestitutionCombineMode=Average 42 | MaxAngularVelocity=3600.000000 43 | MaxDepenetrationVelocity=0.000000 44 | ContactOffsetMultiplier=0.020000 45 | MinContactOffset=2.000000 46 | MaxContactOffset=8.000000 47 | bSimulateSkeletalMeshOnDedicatedServer=True 48 | DefaultShapeComplexity=CTF_UseSimpleAndComplex 49 | bDefaultHasComplexCollision=True 50 | bSuppressFaceRemapTable=False 51 | bSupportUVFromHitResults=False 52 | bDisableActiveActors=False 53 | bDisableKinematicStaticPairs=False 54 | bDisableKinematicKinematicPairs=False 55 | bDisableCCD=False 56 | bEnableEnhancedDeterminism=False 57 | MaxPhysicsDeltaTime=0.033333 58 | bSubstepping=False 59 | bSubsteppingAsync=False 60 | MaxSubstepDeltaTime=0.016667 61 | MaxSubsteps=6 62 | SyncSceneSmoothingFactor=0.000000 63 | AsyncSceneSmoothingFactor=0.990000 64 | InitialAverageFrameRate=0.016667 65 | PhysXTreeRebuildRate=10 66 | DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) 67 | 68 | [/Script/IOSRuntimeSettings.IOSRuntimeSettings] 69 | bSupportsPortraitOrientation=False 70 | bSupportsUpsideDownOrientation=False 71 | bSupportsLandscapeLeftOrientation=True 72 | PreferredLandscapeOrientation=LandscapeLeft 73 | 74 | [/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] 75 | bEnablePlugin=True 76 | bAllowNetworkConnection=True 77 | SecurityToken=A217129245A23235A849E3A88A5B3ED1 78 | bIncludeInShipping=False 79 | bAllowExternalStartInShipping=False 80 | bCompileAFSProject=False 81 | bUseCompression=False 82 | bLogFiles=False 83 | bReportStats=False 84 | ConnectionType=USBOnly 85 | bUseManualIPAddress=False 86 | ManualIPAddress= 87 | 88 | -------------------------------------------------------------------------------- /Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=3D6C2DAF433A2116D0317ABD37AC73A8 3 | ProjectName=RichTextBlockInlineDecorator Host Project 4 | CopyrightNotice=Copyright 2018 Sam Bonifacio. All Rights Reserved. 5 | CompanyName=Sam Bonifacio 6 | Description=Allows inline styling of text using tags, supporting functionality that used to exist in the engine pre-4.20 7 | 8 | -------------------------------------------------------------------------------- /Config/HoloLens/HoloLensEngine.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [/Script/HoloLensPlatformEditor.HoloLensTargetSettings] 4 | bBuildForEmulation=False 5 | bBuildForDevice=True 6 | bUseNameForLogo=True 7 | bBuildForRetailWindowsStore=False 8 | bAutoIncrementVersion=False 9 | bShouldCreateAppInstaller=False 10 | AppInstallerInstallationURL= 11 | HoursBetweenUpdateChecks=0 12 | bEnablePIXProfiling=False 13 | TileBackgroundColor=(B=64,G=0,R=0,A=255) 14 | SplashScreenBackgroundColor=(B=64,G=0,R=0,A=255) 15 | +PerCultureResources=(CultureId="",Strings=(PackageDisplayName="",PublisherDisplayName="",PackageDescription="",ApplicationDisplayName="",ApplicationDescription=""),Images=()) 16 | TargetDeviceFamily=Windows.Holographic 17 | MinimumPlatformVersion= 18 | MaximumPlatformVersionTested=10.0.18362.0 19 | MaxTrianglesPerCubicMeter=500.000000 20 | SpatialMeshingVolumeSize=20.000000 21 | CompilerVersion=Default 22 | Windows10SDKVersion=10.0.18362.0 23 | +CapabilityList=internetClientServer 24 | +CapabilityList=privateNetworkClientServer 25 | +Uap2CapabilityList=spatialPerception 26 | bSetDefaultCapabilities=False 27 | SpatializationPlugin= 28 | ReverbPlugin= 29 | OcclusionPlugin= 30 | SoundCueCookQualityIndex=-1 31 | 32 | -------------------------------------------------------------------------------- /Content/Blueprints/BP_DemoGameMode.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:42393473b42aed61f35c4ff455d4c1bde1551ac0ce7a4158731628d67de7d242 3 | size 17611 4 | -------------------------------------------------------------------------------- /Content/Blueprints/BP_DemoPlayerController.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:240099fc7d3c45a37490e2d0e128d8d1a04bd0d8cdaeb1f4048fef00c2e598a4 3 | size 23022 4 | -------------------------------------------------------------------------------- /Content/Maps/DemoMap.umap: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4e6f6252a891839bc18964a50f82dd2e388911276ebff7bdad69039831e5b7fb 3 | size 628628 4 | -------------------------------------------------------------------------------- /Content/Maps/DemoMap_BuiltData.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f226fe19ddf975c5ad3fabf958f20c2986a8e87e2e823cc6af854a05498ff040 3 | size 1134351 4 | -------------------------------------------------------------------------------- /Content/RichTextStyleSet.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:62d7cd9e6305a5dd96100cddd007856e14102c2b0cb8fdf9dc79de023981e974 3 | size 6662 4 | -------------------------------------------------------------------------------- /Content/WBP_DemoWidget.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:83037becee23f177ddb64f2c649cf83a4df1b92d38c67575927a16f6fe3be9c4 3 | size 51335 4 | -------------------------------------------------------------------------------- /InlineDecoProject.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:492ec220469003c5a68b46268ff6d1e41b929751e2c36f166bce64301f1ee0a2 3 | size 38705 4 | -------------------------------------------------------------------------------- /InlineDecoProject.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "5.0", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "InlineDecoProject", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default", 11 | "AdditionalDependencies": [ 12 | "Engine" 13 | ] 14 | } 15 | ], 16 | "Plugins": [ 17 | { 18 | "Name": "RichTextBlockInlineDecorator", 19 | "Enabled": true, 20 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/e3be7a5e9bb445eb92b54a2ab8571b07" 21 | }, 22 | { 23 | "Name": "OpenXREyeTracker", 24 | "Enabled": false, 25 | "SupportedTargetPlatforms": [ 26 | "Win32", 27 | "Win64", 28 | "Linux", 29 | "HoloLens", 30 | "Android" 31 | ] 32 | }, 33 | { 34 | "Name": "OpenXRHandTracking", 35 | "Enabled": false, 36 | "SupportedTargetPlatforms": [ 37 | "Win32", 38 | "Win64", 39 | "Linux", 40 | "HoloLens", 41 | "Android" 42 | ] 43 | }, 44 | { 45 | "Name": "OpenXR", 46 | "Enabled": false, 47 | "SupportedTargetPlatforms": [ 48 | "Win32", 49 | "Win64", 50 | "Linux", 51 | "Android", 52 | "HoloLens" 53 | ] 54 | }, 55 | { 56 | "Name": "MagicLeapMedia", 57 | "Enabled": false, 58 | "SupportedTargetPlatforms": [ 59 | "Lumin" 60 | ] 61 | }, 62 | { 63 | "Name": "MagicLeap", 64 | "Enabled": false, 65 | "SupportedTargetPlatforms": [ 66 | "Lumin", 67 | "Mac", 68 | "Win64" 69 | ] 70 | }, 71 | { 72 | "Name": "LuminPlatformFeatures", 73 | "Enabled": false, 74 | "SupportedTargetPlatforms": [ 75 | "Lumin" 76 | ] 77 | }, 78 | { 79 | "Name": "MLSDK", 80 | "Enabled": false 81 | }, 82 | { 83 | "Name": "MagicLeapPassableWorld", 84 | "Enabled": false, 85 | "SupportedTargetPlatforms": [ 86 | "Lumin", 87 | "Mac", 88 | "Win64" 89 | ] 90 | } 91 | ] 92 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sam Bonifacio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | [FilterPlugin] 2 | ; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and 3 | ; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. 4 | ; 5 | ; Examples: 6 | ; /README.txt 7 | ; /Extras/... 8 | ; /Binaries/ThirdParty/*.dll 9 | -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Resources/Icon128.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b3454a7a4bfab34fe255469f69b04bfe179cd337e41da215c72b0c8aac0acdb9 3 | size 17470 4 | -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/RichTextBlockInlineDecorator.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 9, 4 | "VersionName": "1.7", 5 | "FriendlyName": "RichTextBlock Inline Decorator", 6 | "Description": "Allows inline styling of text using tags, supporting functionality that used to exist in the engine pre-4.20", 7 | "Category": "User Interface", 8 | "CreatedBy": "Sam Bonifacio", 9 | "CreatedByURL": "https://www.unrealengine.com/marketplace/en-US/profile/Sam+Bonifacio", 10 | "DocsURL": "https://forums.unrealengine.com/community/community-content-tools-and-tutorials/1536690-inline-styling-decorator-for-rich-text-block", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/e3be7a5e9bb445eb92b54a2ab8571b07", 12 | "SupportURL": "https://forums.unrealengine.com/community/community-content-tools-and-tutorials/1536690-inline-styling-decorator-for-rich-text-block", 13 | "CanContainContent": false, 14 | "IsBetaVersion": false, 15 | "Installed": true, 16 | "Modules": [ 17 | { 18 | "Name": "RichTextBlockInlineDecorator", 19 | "Type": "Runtime", 20 | "LoadingPhase": "Default" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Source/RichTextBlockInlineDecorator/Private/RichTextBlockInlineDecorator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #include "RichTextBlockInlineDecorator.h" 4 | #include "UObject/SoftObjectPtr.h" 5 | #include "Rendering/DrawElements.h" 6 | #include "Framework/Text/SlateTextRun.h" 7 | #include "Components/RichTextBlock.h" 8 | 9 | class FDefaultRichTextDecorator : public ITextDecorator 10 | { 11 | public: 12 | FDefaultRichTextDecorator(URichTextBlockDecorator* Decorator, const FSlateFontInfo& DefaultFont, const FLinearColor& DefaultColor); 13 | 14 | virtual ~FDefaultRichTextDecorator(); 15 | 16 | virtual bool Supports(const FTextRunParseResults& RunParseResult, const FString& Text) const override; 17 | 18 | virtual TSharedRef Create(const TSharedRef& TextLayout, const FTextRunParseResults& RunParseResult, const FString& OriginalText, const TSharedRef& InOutModelText, const ISlateStyle* Style) override; 19 | 20 | protected: 21 | 22 | virtual TSharedRef CreateRun(const TSharedRef& TextLayout, const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& Style, const FTextRange& InRange); 23 | 24 | FTextBlockStyle CreateTextBlockStyle(const FRunInfo& InRunInfo) const; 25 | 26 | void ExplodeRunInfo(const FRunInfo& InRunInfo, FSlateFontInfo& OutFont, FLinearColor& OutFontColor) const; 27 | 28 | protected: 29 | 30 | FSlateFontInfo DefaultFont; 31 | FLinearColor DefaultColor; 32 | 33 | private: 34 | TWeakObjectPtr Decorator; 35 | }; 36 | 37 | #define LOCTEXT_NAMESPACE "UMG" 38 | 39 | class FDefaultRichTextRun : public FSlateTextRun 40 | { 41 | public: 42 | FDefaultRichTextRun(URichTextBlockDecorator* InDecorator, const TSharedRef& InTextLayout, const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& InStyle, const FTextRange& InRange) 43 | : FSlateTextRun(InRunInfo, InText, InStyle, InRange) 44 | , TextLayout(InTextLayout) 45 | , Decorator(InDecorator) 46 | { 47 | } 48 | 49 | virtual int32 OnPaint(const FPaintArgs& PaintArgs, const FTextArgs& TextArgs, const FGeometry& AllottedGeometry, 50 | const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, 51 | const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override 52 | { 53 | FSlateTextRun::OnPaint(PaintArgs, TextArgs, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); 54 | 55 | return LayerId; 56 | } 57 | 58 | private: 59 | const TSharedRef TextLayout; 60 | TWeakObjectPtr Decorator; 61 | }; 62 | 63 | ///////////////////////////////////////////////////// 64 | // FDefaultRichTextDecorator 65 | 66 | FDefaultRichTextDecorator::FDefaultRichTextDecorator(URichTextBlockDecorator* InDecorator, const FSlateFontInfo& InDefaultFont, const FLinearColor& InDefaultColor) 67 | : DefaultFont(InDefaultFont) 68 | , DefaultColor(InDefaultColor) 69 | , Decorator(InDecorator) 70 | { 71 | } 72 | 73 | FDefaultRichTextDecorator::~FDefaultRichTextDecorator() 74 | { 75 | } 76 | 77 | bool FDefaultRichTextDecorator::Supports(const FTextRunParseResults& RunParseResult, const FString& Text) const 78 | { 79 | return (RunParseResult.Name == TEXT("span")); 80 | } 81 | 82 | TSharedRef FDefaultRichTextDecorator::Create(const TSharedRef& TextLayout, const FTextRunParseResults& RunParseResult, const FString& OriginalText, const TSharedRef& InOutModelText, const ISlateStyle* Style) 83 | { 84 | FRunInfo RunInfo(RunParseResult.Name); 85 | for (const TPair& Pair : RunParseResult.MetaData) 86 | { 87 | RunInfo.MetaData.Add(Pair.Key, OriginalText.Mid(Pair.Value.BeginIndex, Pair.Value.EndIndex - Pair.Value.BeginIndex)); 88 | } 89 | 90 | FTextRange ModelRange; 91 | ModelRange.BeginIndex = InOutModelText->Len(); 92 | *InOutModelText += OriginalText.Mid(RunParseResult.ContentRange.BeginIndex, RunParseResult.ContentRange.EndIndex - RunParseResult.ContentRange.BeginIndex); 93 | ModelRange.EndIndex = InOutModelText->Len(); 94 | 95 | return CreateRun(TextLayout, RunInfo, InOutModelText, CreateTextBlockStyle(RunInfo), ModelRange); 96 | } 97 | 98 | TSharedRef FDefaultRichTextDecorator::CreateRun(const TSharedRef& TextLayout, const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& Style, const FTextRange& InRange) 99 | { 100 | return MakeShareable(new FDefaultRichTextRun(Decorator.Get(), TextLayout, InRunInfo, InText, Style, InRange)); 101 | } 102 | 103 | FTextBlockStyle FDefaultRichTextDecorator::CreateTextBlockStyle(const FRunInfo& InRunInfo) const 104 | { 105 | FSlateFontInfo Font; 106 | FLinearColor FontColor; 107 | ExplodeRunInfo(InRunInfo, Font, FontColor); 108 | 109 | FTextBlockStyle TextBlockStyle; 110 | TextBlockStyle.SetFont(Font); 111 | TextBlockStyle.SetColorAndOpacity(FontColor); 112 | 113 | return TextBlockStyle; 114 | } 115 | 116 | void FDefaultRichTextDecorator::ExplodeRunInfo(const FRunInfo& InRunInfo, FSlateFontInfo& OutFont, FLinearColor& OutFontColor) const 117 | { 118 | OutFont = DefaultFont; 119 | 120 | const FString* const FontFamilyString = InRunInfo.MetaData.Find(TEXT("font")); 121 | const FString* const FontSizeString = InRunInfo.MetaData.Find(TEXT("size")); 122 | const FString* const FontStyleString = InRunInfo.MetaData.Find(TEXT("style")); 123 | const FString* const FontColorString = InRunInfo.MetaData.Find(TEXT("color")); 124 | 125 | if (FontFamilyString) 126 | { 127 | FSoftObjectPath Font(**FontFamilyString); 128 | if (UObject* FontAsset = Font.TryLoad()) 129 | { 130 | OutFont.FontObject = FontAsset; 131 | } 132 | } 133 | 134 | if (FontSizeString) 135 | { 136 | OutFont.Size = static_cast(FPlatformString::Atoi(**FontSizeString)); 137 | } 138 | 139 | if (FontStyleString) 140 | { 141 | OutFont.TypefaceFontName = FName(**FontStyleString); 142 | } 143 | 144 | OutFontColor = DefaultColor; 145 | if (FontColorString) 146 | { 147 | const FString& FontColorStringRef = *FontColorString; 148 | 149 | // Is Hex color? 150 | if (!FontColorStringRef.IsEmpty() && FontColorStringRef[0] == TCHAR('#')) 151 | { 152 | OutFontColor = FLinearColor(FColor::FromHex(FontColorStringRef)); 153 | } 154 | else if (OutFontColor.InitFromString(*FontColorString)) 155 | { 156 | // Initialized 157 | } 158 | else 159 | { 160 | OutFontColor = DefaultColor; 161 | } 162 | } 163 | } 164 | 165 | ///////////////////////////////////////////////////// 166 | // UDefaultRichTextDecorator 167 | 168 | URichTextBlockInlineDecorator::URichTextBlockInlineDecorator(const FObjectInitializer& ObjectInitializer) 169 | : Super(ObjectInitializer) 170 | { 171 | } 172 | 173 | TSharedPtr URichTextBlockInlineDecorator::CreateDecorator(URichTextBlock* InOwner) 174 | { 175 | FSlateFontInfo DefaultFont = InOwner->GetCurrentDefaultTextStyle().Font; 176 | FLinearColor DefaultColor = InOwner->GetCurrentDefaultTextStyle().ColorAndOpacity.GetSpecifiedColor(); 177 | return MakeShareable(new FDefaultRichTextDecorator(this, DefaultFont, DefaultColor)); 178 | } 179 | 180 | ///////////////////////////////////////////////////// 181 | 182 | #undef LOCTEXT_NAMESPACE 183 | -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Source/RichTextBlockInlineDecorator/Private/RichTextBlockInlineDecoratorModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #include "RichTextBlockInlineDecoratorModule.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FRichTextBlockInlineDecoratorModule" 6 | 7 | void FRichTextBlockInlineDecoratorModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FRichTextBlockInlineDecoratorModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FRichTextBlockInlineDecoratorModule, RichTextBlockInlineDecorator) -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Source/RichTextBlockInlineDecorator/Public/RichTextBlockInlineDecorator.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "Components/RichTextBlockDecorator.h" 6 | #include "RichTextBlockInlineDecorator.generated.h" 7 | 8 | /** 9 | * Allows inline styling of text using tags, supporting functionality that used to exist in the engine pre-4.20 10 | */ 11 | UCLASS() 12 | class URichTextBlockInlineDecorator : public URichTextBlockDecorator 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | URichTextBlockInlineDecorator(const FObjectInitializer& ObjectInitializer); 18 | 19 | virtual TSharedPtr CreateDecorator(URichTextBlock* InOwner) override; 20 | }; -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Source/RichTextBlockInlineDecorator/Public/RichTextBlockInlineDecoratorModule.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | class FRichTextBlockInlineDecoratorModule : public IModuleInterface 9 | { 10 | public: 11 | 12 | /** IModuleInterface implementation */ 13 | virtual void StartupModule() override; 14 | virtual void ShutdownModule() override; 15 | }; 16 | -------------------------------------------------------------------------------- /Plugins/RichTextBlockInlineDecorator/Source/RichTextBlockInlineDecorator/RichTextBlockInlineDecorator.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class RichTextBlockInlineDecorator : ModuleRules 6 | { 7 | public RichTextBlockInlineDecorator(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | "UMG" 42 | // ... add private dependencies that you statically link with here ... 43 | } 44 | ); 45 | 46 | 47 | DynamicallyLoadedModuleNames.AddRange( 48 | new string[] 49 | { 50 | // ... add any modules that your module loads dynamically here ... 51 | } 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RichTextBlock Inline Decorator 2 | 3 | ## Also on the [Unreal Marketplace](https://www.unrealengine.com/marketplace/en-US/product/inline-styling-decorator-for-rich-text-block) 4 | 5 | This is a decorator for the RichTextBlock widget in Unreal Engine version 4.20 and later. 6 | 7 | ![Demo Image](https://i.imgur.com/BJFxcN9.png) 8 | 9 | Before Unreal 4.20, the RichTextBlock existed as an *experimental* class with slightly different functionality by default. 10 | Developers could add ** tags** inline around sections of text changing their font, size, color, and emphasis. 11 | 12 | As of 4.20, the new RichTextBlock functions differently by default in that developers must statically pre-define all of their styles in a data table, then use inline tags to determine which style should apply to different sections of text. 13 | This is great for defining reusable styles which can be used across a project, but not so great when the styling needs to be generated dynamically. 14 | 15 | This plugin takes Epic's original decorator from before 4.20 and exposes it to be usable with the new 4.20 RichTextBlock. Simply install the plugin and add the decorator class to any RichTextBlock widgets that you wish to use it with. 16 | 17 | This allows the RichTextBlock to process tags as it previously did, and any Projects using the old RichTextBlock that are upgrading to 4.20 can use this to re-enable the same styling behavior. 18 | -------------------------------------------------------------------------------- /Source/InlineDecoProject.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class InlineDecoProjectTarget : TargetRules 7 | { 8 | public InlineDecoProjectTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Game; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | 13 | ExtraModuleNames.AddRange( new string[] { "InlineDecoProject" } ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/InlineDecoProject/InlineDecoProject.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class InlineDecoProject : ModuleRules 6 | { 7 | public InlineDecoProject(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); 12 | 13 | PrivateDependencyModuleNames.AddRange(new string[] { }); 14 | 15 | // Uncomment if you are using Slate UI 16 | // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 17 | 18 | // Uncomment if you are using online features 19 | // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 20 | 21 | // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/InlineDecoProject/InlineDecoProject.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #include "InlineDecoProject.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, InlineDecoProject, "InlineDecoProject" ); 7 | -------------------------------------------------------------------------------- /Source/InlineDecoProject/InlineDecoProject.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | -------------------------------------------------------------------------------- /Source/InlineDecoProjectEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Sam Bonifacio. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class InlineDecoProjectEditorTarget : TargetRules 7 | { 8 | public InlineDecoProjectEditorTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | 13 | ExtraModuleNames.AddRange( new string[] { "InlineDecoProject" } ); 14 | } 15 | } 16 | --------------------------------------------------------------------------------