Add guidance preview to coach dashboard
This commit is contained in:
parent
d3658f490d
commit
12c675d211
2 changed files with 203 additions and 0 deletions
|
|
@ -303,6 +303,20 @@ bool UHyperTwistCoachDashboardWidget::SelectNextAttemptReview()
|
|||
return true;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::PreviewRecommendedCoachDeck()
|
||||
{
|
||||
const FHyperTwistTrainingDeck Deck = BuildActiveCoachRecommendedDeck(DefaultCoachMaxCases);
|
||||
UpdateDashboardPresentation();
|
||||
return Deck;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::PreviewFollowUpCoachDeck()
|
||||
{
|
||||
const FHyperTwistTrainingDeck Deck = BuildActiveCoachFollowUpDeck(DefaultCoachMaxCases);
|
||||
UpdateDashboardPresentation();
|
||||
return Deck;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistCoachDashboardWidget::RestartRetainedRunRecapDeck()
|
||||
{
|
||||
if (!RetainedRunRecapDeck.IsStructurallyValid())
|
||||
|
|
@ -630,6 +644,16 @@ void UHyperTwistCoachDashboardWidget::HandleStartRecommendedRunClicked()
|
|||
UpdateDashboardPresentation();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandlePreviewRecommendedClicked()
|
||||
{
|
||||
PreviewRecommendedCoachDeck();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandlePreviewFollowUpClicked()
|
||||
{
|
||||
PreviewFollowUpCoachDeck();
|
||||
}
|
||||
|
||||
void UHyperTwistCoachDashboardWidget::HandleCompleteRunClicked()
|
||||
{
|
||||
CompleteActiveTrainingRun(false);
|
||||
|
|
@ -873,6 +897,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
TEXT("CoachHandoffStatus"),
|
||||
2
|
||||
);
|
||||
GuidanceReviewHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceReviewHeader"),
|
||||
2
|
||||
);
|
||||
RecommendedDeckPreviewTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachRecommendedDeckPreview"),
|
||||
2
|
||||
);
|
||||
FollowUpDeckPreviewTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachFollowUpDeckPreview"),
|
||||
2
|
||||
);
|
||||
UHorizontalBox* RunRecapActionRow = WidgetTree->ConstructWidget<UHorizontalBox>(
|
||||
UHorizontalBox::StaticClass(),
|
||||
TEXT("CoachDashboardRunRecapActions")
|
||||
|
|
@ -950,6 +992,39 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
);
|
||||
StartRecommendedRunButtonLabel = StartRecommendedRunLabelRaw;
|
||||
}
|
||||
UHorizontalBox* GuidancePreviewActionRow = WidgetTree->ConstructWidget<UHorizontalBox>(
|
||||
UHorizontalBox::StaticClass(),
|
||||
TEXT("CoachDashboardGuidancePreviewActions")
|
||||
);
|
||||
if (GuidancePreviewActionRow != nullptr)
|
||||
{
|
||||
if (UVerticalBoxSlot* GuidancePreviewActionRowSlot = RootLayout->AddChildToVerticalBox(GuidancePreviewActionRow))
|
||||
{
|
||||
GuidancePreviewActionRowSlot->SetPadding(FMargin(0.0f, 4.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
UTextBlock* PreviewRecommendedLabelRaw = nullptr;
|
||||
PreviewRecommendedButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
GuidancePreviewActionRow,
|
||||
TEXT("PreviewRecommendedButton"),
|
||||
TEXT("PreviewRecommendedButtonLabel"),
|
||||
TEXT("Preview Recommended"),
|
||||
PreviewRecommendedLabelRaw
|
||||
);
|
||||
PreviewRecommendedButtonLabel = PreviewRecommendedLabelRaw;
|
||||
|
||||
UTextBlock* PreviewFollowUpLabelRaw = nullptr;
|
||||
PreviewFollowUpButton = HyperTwistCoachDashboardWidgetInternal::AddButton(
|
||||
WidgetTree,
|
||||
GuidancePreviewActionRow,
|
||||
TEXT("PreviewFollowUpButton"),
|
||||
TEXT("PreviewFollowUpButtonLabel"),
|
||||
TEXT("Preview Follow-Up"),
|
||||
PreviewFollowUpLabelRaw
|
||||
);
|
||||
PreviewFollowUpButtonLabel = PreviewFollowUpLabelRaw;
|
||||
}
|
||||
LastAttemptTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
|
|
@ -1479,6 +1554,14 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
{
|
||||
StartRecommendedRunButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleStartRecommendedRunClicked);
|
||||
}
|
||||
if (PreviewRecommendedButton != nullptr)
|
||||
{
|
||||
PreviewRecommendedButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandlePreviewRecommendedClicked);
|
||||
}
|
||||
if (PreviewFollowUpButton != nullptr)
|
||||
{
|
||||
PreviewFollowUpButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandlePreviewFollowUpClicked);
|
||||
}
|
||||
if (CompleteRunButton != nullptr)
|
||||
{
|
||||
CompleteRunButton->OnClicked.AddDynamic(this, &UHyperTwistCoachDashboardWidget::HandleCompleteRunClicked);
|
||||
|
|
@ -1917,6 +2000,59 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FString RecommendedRunLabel = CachedCoachBrief.PrimaryActionLabel.IsEmpty()
|
||||
? TEXT("Start Recommended")
|
||||
: CachedCoachBrief.PrimaryActionLabel;
|
||||
const auto BuildDeckPreviewLine = [](const FHyperTwistTrainingDeck& Deck, const FHyperTwistCoachBrief& Brief, const TCHAR* EmptyPrefix)
|
||||
{
|
||||
if (Deck.IsStructurallyValid())
|
||||
{
|
||||
TArray<FString> PreviewCaseParts;
|
||||
const int32 PreviewCaseCount = FMath::Min(Deck.Cases.Num(), 3);
|
||||
for (int32 CaseIndex = 0; CaseIndex < PreviewCaseCount; ++CaseIndex)
|
||||
{
|
||||
const FHyperTwistTrainingCase& PreviewCase = Deck.Cases[CaseIndex];
|
||||
PreviewCaseParts.Add(
|
||||
PreviewCase.PromptLabel.IsEmpty() ? PreviewCase.CaseId : PreviewCase.PromptLabel
|
||||
);
|
||||
}
|
||||
const FString PreviewCases = PreviewCaseParts.Num() > 0
|
||||
? FString::Join(PreviewCaseParts, TEXT(" | "))
|
||||
: TEXT("none");
|
||||
return FString::Printf(
|
||||
TEXT("Deck preview: %s | Deck: %s | Cases: %d | Selection: %s | Difficulty: %s | Subset: %s | Preview: %s"),
|
||||
Deck.Title.IsEmpty() ? TEXT("n/a") : *Deck.Title,
|
||||
Deck.DeckId.IsEmpty() ? TEXT("n/a") : *Deck.DeckId,
|
||||
Deck.Cases.Num(),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(Deck.SelectionPolicy),
|
||||
Deck.DifficultyBand.IsEmpty() ? TEXT("n/a") : *Deck.DifficultyBand,
|
||||
Deck.SubsetId.IsEmpty() ? TEXT("n/a") : *Deck.SubsetId,
|
||||
*PreviewCases
|
||||
);
|
||||
}
|
||||
|
||||
if (!Brief.UserId.IsEmpty() && !Brief.Headline.IsEmpty())
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("%s: %s | Deck: %s | Method: %s | Focus cases: %d | Action: %s"),
|
||||
EmptyPrefix,
|
||||
*Brief.Headline,
|
||||
Brief.FocusDeckId.IsEmpty() ? TEXT("n/a") : *Brief.FocusDeckId,
|
||||
Brief.FocusMethodSegmentId.IsEmpty() ? TEXT("n/a") : *Brief.FocusMethodSegmentId,
|
||||
Brief.FocusCaseIds.Num(),
|
||||
Brief.PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *Brief.PrimaryActionLabel
|
||||
);
|
||||
}
|
||||
|
||||
return FString::Printf(TEXT("%s: no guidance available"), EmptyPrefix);
|
||||
};
|
||||
const FString RecommendedDeckPreviewLine = BuildDeckPreviewLine(
|
||||
CachedCoachRecommendedDeck,
|
||||
CachedCoachBrief,
|
||||
TEXT("Recommended guidance")
|
||||
);
|
||||
const FString FollowUpDeckPreviewLine = BuildDeckPreviewLine(
|
||||
CachedCoachFollowUpDeck,
|
||||
CachedCoachFollowUpBrief,
|
||||
TEXT("Follow-up guidance")
|
||||
);
|
||||
|
||||
if (HeadlineTextBlock != nullptr)
|
||||
{
|
||||
|
|
@ -2054,6 +2190,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
CoachHandoffStatusTextBlock->SetText(FText::FromString(CoachHandoffStatusLine));
|
||||
}
|
||||
if (GuidanceReviewHeaderTextBlock != nullptr)
|
||||
{
|
||||
GuidanceReviewHeaderTextBlock->SetText(FText::FromString(TEXT("[Guidance Review]")));
|
||||
}
|
||||
if (RecommendedDeckPreviewTextBlock != nullptr)
|
||||
{
|
||||
RecommendedDeckPreviewTextBlock->SetText(FText::FromString(RecommendedDeckPreviewLine));
|
||||
}
|
||||
if (FollowUpDeckPreviewTextBlock != nullptr)
|
||||
{
|
||||
FollowUpDeckPreviewTextBlock->SetText(FText::FromString(FollowUpDeckPreviewLine));
|
||||
}
|
||||
if (StartQueuedRunButtonLabel != nullptr)
|
||||
{
|
||||
StartQueuedRunButtonLabel->SetText(FText::FromString(QueuedRunLabel));
|
||||
|
|
@ -2084,6 +2232,28 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
bCanUseCoachHandoff && CachedCoachPanelState.bCanStartCoachRecommendedRun
|
||||
);
|
||||
}
|
||||
if (PreviewRecommendedButtonLabel != nullptr)
|
||||
{
|
||||
PreviewRecommendedButtonLabel->SetText(FText::FromString(TEXT("Preview Recommended")));
|
||||
}
|
||||
if (PreviewRecommendedButton != nullptr)
|
||||
{
|
||||
PreviewRecommendedButton->SetIsEnabled(
|
||||
!bHasLiveAttemptTimer && CachedCoachPanelState.bCanStartCoachRecommendedRun
|
||||
);
|
||||
}
|
||||
if (PreviewFollowUpButtonLabel != nullptr)
|
||||
{
|
||||
PreviewFollowUpButtonLabel->SetText(FText::FromString(TEXT("Preview Follow-Up")));
|
||||
}
|
||||
if (PreviewFollowUpButton != nullptr)
|
||||
{
|
||||
PreviewFollowUpButton->SetIsEnabled(
|
||||
!bHasLiveAttemptTimer
|
||||
&& CachedCoachPanelState.bCanStartCoachFollowUpRun
|
||||
&& CachedCoachPanelState.bHasFollowUpGuidance
|
||||
);
|
||||
}
|
||||
if (LastAttemptTextBlock != nullptr)
|
||||
{
|
||||
if (ReviewedAttempt != nullptr)
|
||||
|
|
|
|||
|
|
@ -97,6 +97,12 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
bool SelectNextAttemptReview();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingDeck PreviewRecommendedCoachDeck();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingDeck PreviewFollowUpCoachDeck();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach|Dashboard")
|
||||
FHyperTwistTrainingRunState RestartRetainedRunRecapDeck();
|
||||
|
||||
|
|
@ -169,6 +175,15 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> CoachHandoffStatusTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceReviewHeaderTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> RecommendedDeckPreviewTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> FollowUpDeckPreviewTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> RepeatRunButton = nullptr;
|
||||
|
||||
|
|
@ -199,6 +214,18 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> StartRecommendedRunButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> PreviewRecommendedButton = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> PreviewRecommendedButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UButton> PreviewFollowUpButton = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> PreviewFollowUpButtonLabel = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> LastAttemptTextBlock = nullptr;
|
||||
|
||||
|
|
@ -439,6 +466,12 @@ protected:
|
|||
UFUNCTION()
|
||||
void HandleStartRecommendedRunClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandlePreviewRecommendedClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandlePreviewFollowUpClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleCompleteRunClicked();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue