diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 3566f83..5684b61 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -365,6 +365,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt() WidgetTree, RootLayout, TEXT("CoachLastAttempt"), + 2 + ); + CurrentCaseHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow( + WidgetTree, + RootLayout, + TEXT("CoachCurrentCaseHeader"), + 2 + ); + CurrentCasePromptTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow( + WidgetTree, + RootLayout, + TEXT("CoachCurrentCasePrompt"), + 2 + ); + CurrentCaseNotationTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow( + WidgetTree, + RootLayout, + TEXT("CoachCurrentCaseNotation"), 8 ); FollowUpTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow( @@ -701,6 +719,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() { const bool bHasActiveRun = CachedRunState.Session.IsStructurallyValid() && CachedRunState.ActiveDeck.IsStructurallyValid(); + const FHyperTwistTrainingCase& CurrentTrainingCase = CachedRunState.CurrentSelection.TrainingCase; const FString ActiveCaseId = CachedRunState.CurrentSelection.TrainingCase.CaseId.IsEmpty() ? TEXT("n/a") : CachedRunState.CurrentSelection.TrainingCase.CaseId; @@ -783,6 +802,52 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() )); } } + if (CurrentCaseHeaderTextBlock != nullptr) + { + CurrentCaseHeaderTextBlock->SetText(FText::FromString(TEXT("[Current Case]"))); + } + if (CurrentCasePromptTextBlock != nullptr) + { + if (bHasRunnableCurrentCase) + { + CurrentCasePromptTextBlock->SetText(FText::FromString(FString::Printf( + TEXT("Prompt: %s | Kind: %s | Subset: %s | Target: %d ms | Attempts on selection: %d | Successes on selection: %d"), + CurrentTrainingCase.PromptLabel.IsEmpty() ? TEXT("n/a") : *CurrentTrainingCase.PromptLabel, + *HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(CurrentTrainingCase.PromptKind), + CurrentTrainingCase.SubsetId.IsEmpty() ? TEXT("n/a") : *CurrentTrainingCase.SubsetId, + CurrentTrainingCase.TimeTargetMs, + CachedRunState.CurrentSelection.AttemptCount, + CachedRunState.CurrentSelection.SuccessCount + ))); + } + else + { + CurrentCasePromptTextBlock->SetText(FText::FromString( + TEXT("Prompt: no active current case is loaded.") + )); + } + } + if (CurrentCaseNotationTextBlock != nullptr) + { + if (bHasRunnableCurrentCase) + { + const FString TagLine = CurrentTrainingCase.Tags.Num() > 0 + ? FString::Join(CurrentTrainingCase.Tags, TEXT(", ")) + : TEXT("n/a"); + CurrentCaseNotationTextBlock->SetText(FText::FromString(FString::Printf( + TEXT("Scramble: %s\nCanonical: %s\nTags: %s"), + CurrentTrainingCase.ScrambleNotation.IsEmpty() ? TEXT("n/a") : *CurrentTrainingCase.ScrambleNotation, + CurrentTrainingCase.CanonicalNotation.IsEmpty() ? TEXT("n/a") : *CurrentTrainingCase.CanonicalNotation, + *TagLine + ))); + } + else + { + CurrentCaseNotationTextBlock->SetText(FText::FromString( + TEXT("Scramble / notation: unavailable until a run is active.") + )); + } + } if (FollowUpTextBlock != nullptr) { const FString FollowUpLine = diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index 06d04da..3a56c98 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -83,6 +83,15 @@ protected: UPROPERTY(Transient) TObjectPtr LastAttemptTextBlock = nullptr; + UPROPERTY(Transient) + TObjectPtr CurrentCaseHeaderTextBlock = nullptr; + + UPROPERTY(Transient) + TObjectPtr CurrentCasePromptTextBlock = nullptr; + + UPROPERTY(Transient) + TObjectPtr CurrentCaseNotationTextBlock = nullptr; + UPROPERTY(Transient) TObjectPtr QueueStatusTextBlock = nullptr;