Add access to run name and delegate for letter added

Also tidy up some duplicated code
This commit is contained in:
Steve Streeting 2023-01-09 13:06:04 +00:00
parent cb8a830d54
commit 068810dc61
2 changed files with 39 additions and 14 deletions

View File

@ -76,6 +76,7 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
TimerManager.ClearTimer(LetterTimer);
CurrentLine = InLine;
CurrentRunName = "";
CurrentLetterIndex = 0;
CachedLetterIndex = 0;
CurrentSegmentIndex = 0;
@ -128,7 +129,7 @@ void UTypewriterTextWidget::SkipToLineEnd()
CurrentLetterIndex = MaxLetterIndex - 1;
if (IsValid(LineText))
{
LineText->SetText(FText::FromString(CalculateSegments()));
LineText->SetText(FText::FromString(CalculateSegments(nullptr)));
}
bHasFinishedPlaying = true;
@ -146,26 +147,21 @@ void UTypewriterTextWidget::PlayNextLetter()
return;
}
FString WrappedString = CalculateSegments();
FString WrappedString = CalculateSegments(&CurrentRunName);
if (IsValid(LineText))
{
LineText->SetText(FText::FromString(WrappedString));
}
// TODO: How do we keep indexing of text i18n-friendly?
if (CurrentLetterIndex < MaxLetterIndex)
{
if (IsValid(LineText))
{
LineText->SetText(FText::FromString(WrappedString));
}
OnPlayLetter();
OnTypewriterLetterAdded.Broadcast(this);
++CurrentLetterIndex;
}
else
{
if (IsValid(LineText))
{
LineText->SetText(FText::FromString(CalculateSegments()));
}
FTimerManager& TimerManager = GetWorld()->GetTimerManager();
TimerManager.ClearTimer(LetterTimer);
@ -272,7 +268,7 @@ void UTypewriterTextWidget::CalculateWrappedString()
}
FString UTypewriterTextWidget::CalculateSegments()
FString UTypewriterTextWidget::CalculateSegments(FString* OutCurrentRunName)
{
FString Result = CachedSegmentText;
@ -341,6 +337,18 @@ FString UTypewriterTextWidget::CalculateSegments()
}
}
if (OutCurrentRunName)
{
if (CurrentSegmentIndex < Segments.Num())
{
*OutCurrentRunName = Segments[CurrentSegmentIndex].RunInfo.Name;
}
else
{
*OutCurrentRunName = "";
}
}
return Result;
}

View File

@ -17,6 +17,7 @@
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTypewriterLineFinished, class UTypewriterTextWidget*, Widget);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTypewriterLetterAdded, class UTypewriterTextWidget*, Widget);
/**
* A text block that exposes more information about text layout for typewriter widget.
*/
@ -58,6 +59,10 @@ public:
UPROPERTY(BlueprintAssignable)
FOnTypewriterLineFinished OnTypewriterLineFinished;
/// Event called when one or more new letters have been displayed
UPROPERTY(BlueprintAssignable)
FOnTypewriterLetterAdded OnTypewriterLetterAdded;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
URichTextBlockForTypewriter* LineText;
@ -95,23 +100,35 @@ public:
UFUNCTION(BlueprintCallable, Category = "Typewriter")
void SkipToLineEnd();
/// Get the name of the current rich text run, if any
const FString& GetCurrentRunName() const { return CurrentRunName; }
protected:
/// Called when on or more letters are added, if subclasses want to override
UFUNCTION(BlueprintImplementableEvent, Category = "Typewriter")
void OnPlayLetter();
UFUNCTION(BlueprintImplementableEvent, Category = "Typewriter")
void OnLineFinishedPlaying();
/// Name of the current rich text run, if any
/// Can be used to identify the style of the most recently played letter
UPROPERTY(BlueprintReadOnly, Category = "Typewriter")
FString CurrentRunName;
private:
void PlayNextLetter();
static bool IsSentenceTerminator(TCHAR Letter);
void CalculateWrappedString();
FString CalculateSegments();
FString CalculateSegments(FString* OutCurrentRunName);
UPROPERTY()
FText CurrentLine;
struct FTypewriterTextSegment
{
FString Text;