Tooltip not displayed when using FSlateHyperlinkRun::FOnGetTooltipText in SRichTextBlock
This posting is based on engine version 5.3
Symptom
- When we use SRichTextBlock
- If we designate the tooltip text by using FHyperlinkDecorator::Create()andFSlateHyperlinkRun::FOnGetTooltipText
- The tooltip is not displayed.
The detail is below:
I wanted to create an SRichTextBlock and have a simple tooltip appear when you hover the mouse over the hyperlink within it.
I made the SomeFunctionName as like this:
But nothing came out. So I started debugging.
For reference, FHyperlinkDecorator::Create() looks like this.
(I wanted to make it easier to view on the homepage, so I artificially changed the line breaks a little.)
Cause
Note
For reference, from below:
- Some content is omitted to reduce the length of exposed engine code. Please go to the GitHub link to see the exact code.
- To help you understand, there are parts where I added comments.
Circumstances of SWidget
void SWidget::SWidgetConstruct(const FSlateBaseNamedArgs& Args) has the code below.
If ToolTip is given, ToolTipText will be ignored.
Circumstances of FSlateHyperlinkRun
The FHyperlinkDecorator object created by FHyperlinkDecorator::Create() is passed to SRichTextBlock.
SRichTextBlock calls FSlateHyperlinkRun::CreateBlock() based on this in the first prepass and generates the result in the format of TSharedRef< ILayoutBlock >.
The call stack at this time is as follows.
At this time, the code of FSlateHyperlinkRun::CreateBlock() is as follows.
The problem is that TSharedPtr<IToolTip> ToolTip is not TAttribute<>.
The details are below:
- The local variable ToolTipis constructed, as the type ofTSharedPtr<IToolTip>. It is nullptr.
- In the part of constructing SRichTextHyperlink, for.ToolTip( ToolTip ),TSharedPtr<IToolTip> ToolTipthat is nullptr, is passed.
- Based on this value set, TAttribute<TSharedPtr<IToolTip>>is created and passed toSWidgetasArgs._ToolTip.
- InSWidget,Args._ToolTip.IsSet()is true. Even if its value is nullptr, anyway, the value has been set.
- So the code of SetToolTip(Args._ToolTip);is run, andSetToolTipText(Args._ToolTipText);is skipped.
- But the value is nullptr. so there is nothing to display.
Workaround
Without modifying engine, we can not use const FSlateHyperlinkRun::FOnGetTooltipText& InToolTipTextDelegate.
So I decided to use  const FSlateHyperlinkRun::FOnGenerateTooltip& InToolTipDelegate.
I changed the code about creating a delegate in the construction SRichTextBlock , like below.
And the function that the delegate will call is like below.
It was displayed well.
Things I want to be careful of in the future
My thought was like this: When creating and using a Slate widget class based on SCompoundWidget, it occurred to me that if there are many different cases that need to be considered and confusion is likely to occur, and if there is a need to pass parameters with TAttribute<>, will it be safer to keep the type of variables as TAttribute<> for the relevant items? I thought I’d make a similar mistake someday.