Explain coach guidance on dashboard
This commit is contained in:
parent
e6322c0088
commit
f3339e8ff4
2 changed files with 136 additions and 0 deletions
|
|
@ -1029,6 +1029,24 @@ void UHyperTwistCoachDashboardWidget::EnsureDefaultDashboardBuilt()
|
|||
TEXT("CoachGuidanceReviewHeader"),
|
||||
2
|
||||
);
|
||||
GuidanceRationaleHeaderTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceRationaleHeader"),
|
||||
2
|
||||
);
|
||||
GuidanceRationaleStatusTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceRationaleStatus"),
|
||||
2
|
||||
);
|
||||
GuidanceRationaleDetailTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
TEXT("CoachGuidanceRationaleDetail"),
|
||||
8
|
||||
);
|
||||
GuidancePreviewSelectionTextBlock = HyperTwistCoachDashboardWidgetInternal::AddTextRow(
|
||||
WidgetTree,
|
||||
RootLayout,
|
||||
|
|
@ -1957,6 +1975,23 @@ const FHyperTwistTrainingDeck* UHyperTwistCoachDashboardWidget::GetActiveGuidanc
|
|||
}
|
||||
}
|
||||
|
||||
const FHyperTwistCoachBrief* UHyperTwistCoachDashboardWidget::GetActiveGuidancePreviewBrief() const
|
||||
{
|
||||
switch (ActiveGuidancePreviewLane)
|
||||
{
|
||||
case EHyperTwistCoachDashboardGuidancePreviewLane::Recommended:
|
||||
return CachedCoachBrief.Headline.IsEmpty() && CachedCoachBrief.PrimaryActionLabel.IsEmpty()
|
||||
? nullptr
|
||||
: &CachedCoachBrief;
|
||||
case EHyperTwistCoachDashboardGuidancePreviewLane::FollowUp:
|
||||
return CachedCoachFollowUpBrief.Headline.IsEmpty() && CachedCoachFollowUpBrief.PrimaryActionLabel.IsEmpty()
|
||||
? nullptr
|
||||
: &CachedCoachFollowUpBrief;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck UHyperTwistCoachDashboardWidget::BuildSelectedGuidancePreviewCaseDeck() const
|
||||
{
|
||||
const FHyperTwistTrainingDeck* Deck = GetActiveGuidancePreviewDeck();
|
||||
|
|
@ -2313,6 +2348,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
&& SelectedGuidancePreviewCaseIndex < ActivePreviewDeck->Cases.Num()
|
||||
? &ActivePreviewDeck->Cases[SelectedGuidancePreviewCaseIndex]
|
||||
: nullptr;
|
||||
const FHyperTwistCoachBrief* ActivePreviewBrief = GetActiveGuidancePreviewBrief();
|
||||
const FString ActivePreviewLaneLabel =
|
||||
ActiveGuidancePreviewLane == EHyperTwistCoachDashboardGuidancePreviewLane::Recommended
|
||||
? TEXT("recommended")
|
||||
|
|
@ -2342,6 +2378,84 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
SelectedGuidancePreviewCase->CanonicalNotation.IsEmpty() ? TEXT("n/a") : *SelectedGuidancePreviewCase->CanonicalNotation
|
||||
)
|
||||
: TEXT("Preview case: none selected yet.");
|
||||
bool bSelectedPreviewCaseIsExplicitFocus = false;
|
||||
int32 SelectedPreviewCaseSignalCount = 0;
|
||||
FString SelectedPreviewCaseSignalLine = TEXT("none");
|
||||
FString SignalSummaryLine = TEXT("none");
|
||||
if (ActivePreviewBrief != nullptr)
|
||||
{
|
||||
if (SelectedGuidancePreviewCase != nullptr)
|
||||
{
|
||||
bSelectedPreviewCaseIsExplicitFocus =
|
||||
ActivePreviewBrief->FocusCaseIds.Contains(SelectedGuidancePreviewCase->CaseId);
|
||||
}
|
||||
|
||||
TArray<FString> SignalSummaryParts;
|
||||
SignalSummaryParts.Reserve(FMath::Min(ActivePreviewBrief->Signals.Num(), 2));
|
||||
for (const FHyperTwistCoachSignal& Signal : ActivePreviewBrief->Signals)
|
||||
{
|
||||
if (SelectedGuidancePreviewCase != nullptr
|
||||
&& Signal.SuggestedCaseIds.Contains(SelectedGuidancePreviewCase->CaseId))
|
||||
{
|
||||
++SelectedPreviewCaseSignalCount;
|
||||
if (SelectedPreviewCaseSignalLine == TEXT("none"))
|
||||
{
|
||||
SelectedPreviewCaseSignalLine = FString::Printf(
|
||||
TEXT("%s | %s"),
|
||||
Signal.Headline.IsEmpty() ? TEXT("signal") : *Signal.Headline,
|
||||
Signal.Detail.IsEmpty() ? TEXT("no detail") : *Signal.Detail
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (SignalSummaryParts.Num() < 2)
|
||||
{
|
||||
SignalSummaryParts.Add(FString::Printf(
|
||||
TEXT("%s (%.2f)"),
|
||||
Signal.Headline.IsEmpty() ? TEXT("signal") : *Signal.Headline,
|
||||
Signal.Score
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (SignalSummaryParts.Num() > 0)
|
||||
{
|
||||
SignalSummaryLine = FString::Join(SignalSummaryParts, TEXT(" | "));
|
||||
}
|
||||
}
|
||||
const FString GuidanceRationaleStatusLine =
|
||||
ActivePreviewBrief != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Rationale: %s lane | Priority: %s (%.2f) | Focus: %s | Mode: %s | Selection: %s"),
|
||||
*ActivePreviewLaneLabel,
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(ActivePreviewBrief->Priority),
|
||||
ActivePreviewBrief->PriorityScore,
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(ActivePreviewBrief->FocusLane),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(ActivePreviewBrief->SuggestedMode),
|
||||
*HyperTwistCoachDashboardWidgetInternal::EnumDisplayName(ActivePreviewBrief->SuggestedSelectionPolicy)
|
||||
)
|
||||
: FString::Printf(
|
||||
TEXT("Rationale: %s lane | build a recommended or follow-up preview to inspect the coach rationale"),
|
||||
*ActivePreviewLaneLabel
|
||||
);
|
||||
const FString GuidanceRationaleDetailLine =
|
||||
ActivePreviewBrief != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"),
|
||||
ActivePreviewBrief->Headline.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->Headline,
|
||||
ActivePreviewBrief->PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->PrimaryActionLabel,
|
||||
ActivePreviewBrief->FocusDeckId.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->FocusDeckId,
|
||||
ActivePreviewBrief->FocusMethodSegmentId.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->FocusMethodSegmentId,
|
||||
ActivePreviewBrief->FocusCaseIds.Num(),
|
||||
ActivePreviewBrief->bNeedsCoachReview ? TEXT("yes") : TEXT("no"),
|
||||
ActivePreviewBrief->bNeedsCadenceRecovery ? TEXT("yes") : TEXT("no"),
|
||||
ActivePreviewBrief->bNeedsVarietyRotation ? TEXT("yes") : TEXT("no"),
|
||||
bSelectedPreviewCaseIsExplicitFocus ? TEXT("yes") : TEXT("no"),
|
||||
SelectedPreviewCaseSignalCount,
|
||||
*SelectedPreviewCaseSignalLine,
|
||||
*SignalSummaryLine
|
||||
)
|
||||
: TEXT("Rationale detail: unavailable until a guidance preview lane is active.");
|
||||
const bool bCanStartPreviewDeck =
|
||||
!bHasLiveAttemptTimer && !bHasActiveRun && ActivePreviewDeck != nullptr && ActivePreviewDeck->IsStructurallyValid();
|
||||
const bool bCanStartPreviewCase = bCanStartPreviewDeck && SelectedGuidancePreviewCase != nullptr;
|
||||
|
|
@ -2486,6 +2600,18 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
{
|
||||
GuidanceReviewHeaderTextBlock->SetText(FText::FromString(TEXT("[Guidance Review]")));
|
||||
}
|
||||
if (GuidanceRationaleHeaderTextBlock != nullptr)
|
||||
{
|
||||
GuidanceRationaleHeaderTextBlock->SetText(FText::FromString(TEXT("[Guidance Rationale]")));
|
||||
}
|
||||
if (GuidanceRationaleStatusTextBlock != nullptr)
|
||||
{
|
||||
GuidanceRationaleStatusTextBlock->SetText(FText::FromString(GuidanceRationaleStatusLine));
|
||||
}
|
||||
if (GuidanceRationaleDetailTextBlock != nullptr)
|
||||
{
|
||||
GuidanceRationaleDetailTextBlock->SetText(FText::FromString(GuidanceRationaleDetailLine));
|
||||
}
|
||||
if (GuidancePreviewSelectionTextBlock != nullptr)
|
||||
{
|
||||
GuidancePreviewSelectionTextBlock->SetText(FText::FromString(GuidancePreviewSelectionLine));
|
||||
|
|
|
|||
|
|
@ -197,6 +197,15 @@ protected:
|
|||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceReviewHeaderTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceRationaleHeaderTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceRationaleStatusTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidanceRationaleDetailTextBlock = nullptr;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UTextBlock> GuidancePreviewSelectionTextBlock = nullptr;
|
||||
|
||||
|
|
@ -603,6 +612,7 @@ private:
|
|||
const FHyperTwistTrainingCoachSessionQueueStateEntry* FindSelectedQueueEntry() const;
|
||||
const FHyperTwistTrainingTimingPolicy* FindActiveTimingPolicy() const;
|
||||
const FHyperTwistTrainingDeck* GetActiveGuidancePreviewDeck() const;
|
||||
const FHyperTwistCoachBrief* GetActiveGuidancePreviewBrief() const;
|
||||
FHyperTwistTrainingDeck BuildSelectedGuidancePreviewCaseDeck() const;
|
||||
bool IsLiveAttemptInspectionPhase() const;
|
||||
int32 GetMaxManualSplitCaptureCount() const;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue