From 068810dc6104d4130f055068d8a4d67267ab1b8b Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 9 Jan 2023 13:06:04 +0000 Subject: [PATCH] Add access to run name and delegate for letter added Also tidy up some duplicated code --- .../Private/StevesUI/TypewriterTextWidget.cpp | 34 ++++++++++++------- .../Public/StevesUI/TypewriterTextWidget.h | 19 ++++++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp index 059ab5b..8857ada 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp @@ -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; } diff --git a/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h b/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h index 2abdabd..2e74f62 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h +++ b/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h @@ -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;