KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
URichText.cpp
이 파일의 문서화 페이지로 가기
1// Copyright (c) 2025 Doppleddiggong. All rights reserved. Unauthorized copying, modification, or distribution of this file, via any medium is strictly prohibited. Proprietary and confidential.
2
3
4#include "URichText.h"
5
6#include "HyperLinkPluginBPLibrary.h"
7#include "NetworkData.h"
8#include "Components/RichTextBlock.h"
9#include "Engine/DataTable.h"
10
11#define TEXT_STYLE_PATH TEXT("/Game/CustomContents/MasterData/RichTextBlock/DT_TextSet.DT_TextSet")
12
14{
15 Super::NativePreConstruct();
16
17 if (RichTxt)
18 {
19 if (auto StyleSet = LoadObject<UDataTable>(nullptr, TEXT_STYLE_PATH ))
20 RichTxt->SetTextStyleSet(StyleSet);
21 }
22
24}
25
27{
28 Super::NativeConstruct();
29
30 if (RichTxt)
31 {
32 if (UHyperLinkPluginBPLibrary* LinkDecorator = Cast<UHyperLinkPluginBPLibrary>(
33 RichTxt->GetDecoratorByClass(UHyperLinkPluginBPLibrary::StaticClass())))
34 {
35 LinkDecorator->SetNativeClickHandler(FOnClickLink::CreateUObject(this, &URichText::OnClickLink));
36 }
37 }
38}
39
40void URichText::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
41{
42 Super::NativeTick(MyGeometry, InDeltaTime);
43
44 // 텍스트가 변경되었거나 위젯 크기가 변경된 경우에만 폰트 크기 조정
45 const float CurrentWidth = MyGeometry.GetLocalSize().X;
46 if (FMath::Abs(CurrentWidth - LastWidgetWidth) > 1.0f)
47 {
48 LastWidgetWidth = CurrentWidth;
51 }
52
53 // 폰트 크기 업데이트가 필요하고 아직 안정화되지 않은 경우에만 실행
55 {
56 UpdateFontSizeToFitWidth(MyGeometry);
58
59 // 3프레임 동안 안정화 시도 후 중단
60 if (StabilizationFrames >= 3)
61 {
63 }
64 }
65}
66
67void URichText::ApplyStyleWithFontSize(int32 InFontSize, bool bPreserveText)
68{
69 if (!RichTxt)
70 return;
71
72 const FText PreviousText = RichTxt->GetText();
73
74 // 기존 폰트 정보 가져오기 (없으면 기본)
75 FSlateFontInfo NewFont = RichTxt->GetDefaultTextStyle().Font;
76 NewFont.Size = InFontSize;
77
78 // 새로운 스타일 생성
79 FTextBlockStyle NewStyle;
80 NewStyle.SetFont(NewFont);
81 NewStyle.SetColorAndOpacity(FSlateColor(TextColor));
82
83 RichTxt->SetDefaultTextStyle(NewStyle);
84
85 if (!bPreserveText && !DefaultText.IsEmpty() && PreviousText.IsEmpty())
86 {
87 RichTxt->SetText(FText::FromString(DefaultText));
88 }
89 else if (bPreserveText)
90 {
91 RichTxt->SetText(PreviousText);
92 }
93
94 // HyperLink Decorator 스타일도 함께 업데이트
95 if (UHyperLinkPluginBPLibrary* LinkDecorator = Cast<UHyperLinkPluginBPLibrary>(
96 RichTxt->GetDecoratorByClass(UHyperLinkPluginBPLibrary::StaticClass())))
97 {
98 FTextBlockStyle LinkTextStyle = LinkDecorator->Style.TextStyle;
99 LinkTextStyle.SetFont(NewFont);
100 LinkTextStyle.SetColorAndOpacity(FSlateColor(TextColor));
101 LinkDecorator->Style.SetTextStyle(LinkTextStyle);
102 }
103
104 CurrentFontSize = InFontSize;
105}
106
107void URichText::UpdateFontSizeToFitWidth(const FGeometry& MyGeometry)
108{
109 if (!bAutoFitToWidth || !RichTxt)
110 return;
111
112 const float AvailableWidth = MyGeometry.GetLocalSize().X;
113 if (AvailableWidth <= 0.0f)
114 return;
115
116 const FVector2D DesiredSize = RichTxt->GetDesiredSize();
117 const float DesiredWidth = DesiredSize.X;
118
119 int32 TargetFontSize = FontSize;
120
121 // Threshold 적용: 여유 공간을 2픽셀 정도 남겨서 미세한 변동 방지
122 const float WidthThreshold = 2.0f;
123 if (DesiredWidth > AvailableWidth + WidthThreshold && DesiredWidth > 0.0f)
124 {
125 // 약간 여유를 둔 스케일 계산 (98%만 사용)
126 const float Scale = (AvailableWidth * 0.98f) / DesiredWidth;
127 const int32 ScaledSize = FMath::FloorToInt(static_cast<float>(FontSize) * Scale);
128 TargetFontSize = FMath::Clamp(ScaledSize, MinAutoFontSize, FontSize);
129 }
130
131 // 폰트 크기 차이가 1 이상일 때만 적용 (미세한 차이 무시)
132 if (FMath::Abs(TargetFontSize - CurrentFontSize) >= 1)
133 {
134 ApplyStyleWithFontSize(TargetFontSize, true);
135 }
136}
137
138void URichText::SetText(const FWordData& WordData)
139{
140 if (!IsValid(RichTxt))
141 return;
142
144
145 FString TextString;
146 for (int32 i = 0; i < CachedPhonemeData.Num(); ++i)
147 {
148 const FPhonemeData& Phoneme = CachedPhonemeData[i];
149 TextString += Phoneme.ToRichTextString(i);
150 }
151 RichTxt->SetText(FText::FromString(TextString));
152
153 // 텍스트가 변경되었으므로 폰트 크기 재조정 필요
156}
157
158void URichText::SetText(const FString& InString)
159{
160 if (!IsValid(RichTxt))
161 return;
162
163 RichTxt->SetText(FText::FromString(InString));
164
165 // 텍스트가 변경되었으므로 폰트 크기 재조정 필요
168}
169
170void URichText::SetText(const FText& InText)
171{
172 if (!IsValid(RichTxt))
173 return;
174
175 RichTxt->SetText(InText);
176
177 // 텍스트가 변경되었으므로 폰트 크기 재조정 필요
180}
181
182void URichText::OnClickLink(const FString& LinkID, const FString& Content)
183{
184 const int32 Index = FCString::Atoi(*LinkID);
185
186 if (CachedPhonemeData.IsValidIndex(Index))
187 {
188 if (OnClickHyperLink.IsBound())
189 OnClickHyperLink.Execute(CachedPhonemeData[Index]);
190 }
191}
네트워크 요청과 응답에 사용되는 구조체 및 설정을 정의합니다.
#define TEXT_STYLE_PATH
Definition URichText.cpp:11
void OnClickLink(const FString &LinkID, const FString &Content)
float LastWidgetWidth
이전 위젯 너비 (변경 감지용)
Definition URichText.h:75
FOnClickHyperLink OnClickHyperLink
Definition URichText.h:64
virtual void NativePreConstruct() override
Definition URichText.cpp:13
void SetText(const FWordData &WordData)
virtual void NativeConstruct() override
Definition URichText.cpp:26
virtual void NativeTick(const FGeometry &MyGeometry, float InDeltaTime) override
Definition URichText.cpp:40
bool bNeedsFontSizeUpdate
폰트 크기 조정이 필요한지 여부
Definition URichText.h:69
int32 CurrentFontSize
Definition URichText.h:66
int32 FontSize
Definition URichText.h:46
int32 StabilizationFrames
안정화를 위한 프레임 카운터
Definition URichText.h:72
void UpdateFontSizeToFitWidth(const FGeometry &MyGeometry)
TArray< FPhonemeData > CachedPhonemeData
Definition URichText.h:62
bool bAutoFitToWidth
Definition URichText.h:49
void ApplyStyleWithFontSize(int32 InFontSize, bool bPreserveText)
Definition URichText.cpp:67
FLinearColor TextColor
Definition URichText.h:55
int32 MinAutoFontSize
Definition URichText.h:52
FString DefaultText
Definition URichText.h:58
TObjectPtr< class URichTextBlock > RichTxt
Definition URichText.h:42
단어 데이터 구조체입니다.
FString ToRichTextString(int32 Index) const
단어 데이터 구조체입니다.
TArray< FPhonemeData > GetPhonemeData() const