diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index d5568fd..7038ec1 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -296,7 +296,18 @@ FHyperTwistTrainingRunStepResult UHyperTwistCoachDashboardWidget::SubmitSyntheti bool UHyperTwistCoachDashboardWidget::ContinueCurrentRunFlow() { - const bool bSucceeded = StartLiveAttemptTimer(); + bool bSucceeded = false; + if (CachedRunState.Session.IsStructurallyValid() && CachedRunState.CurrentSelection.TrainingCase.IsStructurallyValid()) + { + bSucceeded = StartLiveAttemptTimer(); + } + else if (CachedCoachPanelState.bCanStartQueuedRun + || CachedCoachPanelState.bCanStartCoachFollowUpRun + || CachedCoachPanelState.bCanStartCoachRecommendedRun) + { + const FHyperTwistTrainingRunState RunState = ExecutePrimaryCoachAction(); + bSucceeded = RunState.Session.IsStructurallyValid() && RunState.ActiveDeck.IsStructurallyValid(); + } if (!bSucceeded) { UpdateDashboardPresentation(); @@ -1382,6 +1393,17 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() const bool bCanContinueCurrentRun = !bHasLiveAttemptTimer && bHasRunnableCurrentCase && !bLastStepCompletedRun; + const bool bCanLaunchCoachRun = !bHasLiveAttemptTimer + && ( + CachedCoachPanelState.bCanStartQueuedRun + || CachedCoachPanelState.bCanStartCoachFollowUpRun + || CachedCoachPanelState.bCanStartCoachRecommendedRun + ); + FString TransitionLaunchLabel = CachedCoachPanelState.PrimaryActionLabel; + if (TransitionLaunchLabel.IsEmpty()) + { + TransitionLaunchLabel = TEXT("Launch Coach Run"); + } FString TransitionStatusLine; if (bLiveInspectionPhase) { @@ -1399,10 +1421,20 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() } else if (bLastStepCompletedRun) { - TransitionStatusLine = FString::Printf( - TEXT("Transition: run completed after case %s. Clear the finished run or launch the next queued coaching item."), - LastStepResult.SessionSummary.LastCaseId.IsEmpty() ? TEXT("n/a") : *LastStepResult.SessionSummary.LastCaseId - ); + if (bCanLaunchCoachRun) + { + TransitionStatusLine = FString::Printf( + TEXT("Transition: run completed after case %s. Use the next-step action to launch the next coach-directed run, or clear the finished run."), + LastStepResult.SessionSummary.LastCaseId.IsEmpty() ? TEXT("n/a") : *LastStepResult.SessionSummary.LastCaseId + ); + } + else + { + TransitionStatusLine = FString::Printf( + TEXT("Transition: run completed after case %s. Clear the finished run or relaunch from coach guidance when another run is available."), + LastStepResult.SessionSummary.LastCaseId.IsEmpty() ? TEXT("n/a") : *LastStepResult.SessionSummary.LastCaseId + ); + } } else if (bCanContinueCurrentRun) { @@ -1437,6 +1469,13 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() TransitionStatusLine = TEXT("Transition: this run has no runnable current case. Complete, clear, or relaunch from coach guidance."); } + else if (bCanLaunchCoachRun) + { + TransitionStatusLine = FString::Printf( + TEXT("Transition: no run is active. Use the next-step action to %s."), + *TransitionLaunchLabel + ); + } else { TransitionStatusLine = @@ -1446,7 +1485,9 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() ? (bLiveInspectionPhase ? TEXT("Start Solve") : TEXT("Attempt Active")) : (bHasNextCaseFromLastStep ? TEXT("Continue Run") - : (CachedRunSummary.AttemptCount > 0 ? TEXT("Start Next Attempt") : TEXT("Start First Attempt"))); + : (bCanContinueCurrentRun + ? (CachedRunSummary.AttemptCount > 0 ? TEXT("Start Next Attempt") : TEXT("Start First Attempt")) + : TransitionLaunchLabel)); if (HeadlineTextBlock != nullptr) { @@ -1948,6 +1989,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() ContinueRunButton->SetIsEnabled( (!bHasLiveAttemptTimer && bCanContinueCurrentRun) || (bLiveInspectionPhase && bHasRunnableCurrentCase) + || bCanLaunchCoachRun ); } if (ClearRunButtonLabel != nullptr)