SRichTextBlock 에서 하이퍼링크에 FOnGetTooltipText 를 사용시 툴팁이 표시되지 않음
이 포스팅은 엔진 버전 5.3을 기준으로 작성되었습니다.
증상
SRichTextBlock
사용시FHyperlinkDecorator::Create()
와FSlateHyperlinkRun::FOnGetTooltipText
를 사용하여 툴팁의 텍스트를 지정하려고 하면- 툴팁이 표시되지 않습니다.
자세한 사연은 이랬습니다.
SRichTextBlock
를 생성해서, 그 안의 하이퍼링크에 마우스를 가져가면 간단한 툴팁이 나오게 하고 싶었습니다.
SomeFunctionName
는 이렇게 동작하게 했습니다.
하지만 아무것도 안 나오더라구요. 그래서 디버깅을 시작했지요.
참고로, FHyperlinkDecorator::Create()
는 이렇게 생겼습니다.
(홈페이지에서 보기 편하게 하고 싶어서, 제가 인위적으로 줄바꿈을 조금 변경했습니다.)
원인
참고
참고로, 아래에서부터는,
- 노출되는 엔진 코드 길이를 줄이기 위해 일부 내용을 생략하습니다. 정확한 코드는 GitHub 링크로 이동해서 보시기 바랍니다.
- 이해를 돕기 위해, 제가 임의로 주석을 추가한 부분이 있습니다.
SWidget 의 사정
void SWidget::SWidgetConstruct(const FSlateBaseNamedArgs& Args)
에는 아래와 같은 코드가 있습니다.
ToolTip 이 주어졌다면, ToolTipText 는 무시됩니다.
FSlateHyperlinkRun 의 사정
FHyperlinkDecorator::Create()
가 만드는 FHyperlinkDecorator
객체는 SRichTextBlock
에게 전달됩니다.
SRichTextBlock
는 첫 Prepass에서 이를 기반으로 FSlateHyperlinkRun::CreateBlock()
를 호출하고, 결과물을 TSharedRef< ILayoutBlock >
의 형식으로 생성합니다.
이 때의 콜스택은 아래와 같습니다.
이 때, FSlateHyperlinkRun::CreateBlock()
의 코드는 아래와 같습니다.
GitHub 링크
TSharedPtr<IToolTip> ToolTip
이 TAttribute<>
가 아니라는 게 문제입니다.
TSharedPtr<IToolTip>
인ToolTip
이 지역변수로 만들어집니다. nullptr 이죠.- 위의
SRichTextHyperlink
생성 부분에서.ToolTip( ToolTip )
에 nullptr 인TSharedPtr<IToolTip> ToolTip
이 전달됩니다. - 이 설정된 값을 기반으로
TAttribute<TSharedPtr<IToolTip>>
이 만들어지고,SWidget
에게Args._ToolTip
로 전달됩니다. SWidget
에서Args._ToolTip.IsSet()
는 true 가 됩니다. 그 내용물이 nullptr 이지만, 값이 설정되기는 했습니다.- 그래서
SetToolTip(Args._ToolTip);
부분의 코드가 실행되고,SetToolTipText(Args._ToolTipText);
부분은 건너 뛰게 됩니다. - 하지만 내용물이 nullptr 이니까 아무것도 나오지 않습니다.
해결안
const FSlateHyperlinkRun::FOnGetTooltipText& InToolTipTextDelegate
는 엔진을 수정하지 않는 한 사용이 불가능합니다.
그래서 그냥 const FSlateHyperlinkRun::FOnGenerateTooltip& InToolTipDelegate
를 쓰기로 했습니다.
일단 SRichTextBlock
생성시 델리게이트 생성 부분을 아래와 같이 바꿨습니다.
그리고 델리게이트가 호출하는 함수는 아래처럼 했습니다.
잘 나왔습니다.
앞으로 조심하고 싶은 점
SCompoundWidget
기반으로 Slate 위젯 클래스를 만들어 사용할 때, 여러 가지 경우의 수를 고려해야 하는 상황이어서 혼동이 발생할 가능성이 높다면, 그리고 TAttribute<>
관련 파라메터들를 전달할 필요가 있다면, 관련된 항목은 TAttribute<>
타입을 유지하는 것이 안전하지 않을까 하는 생각이 들었습니다. 저도 분명 유사한 실수를 할 것 같아서요.