237 lines
6.9 KiB
C++
237 lines
6.9 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#include "DTFluxModelAssetDetailCustomization.h"
|
|
#include "DetailLayoutBuilder.h"
|
|
#include "DetailCategoryBuilder.h"
|
|
#include "DetailWidgetRow.h"
|
|
#include "Widgets/Layout/SBox.h"
|
|
#include "Assets/DTFluxModelAsset.h"
|
|
|
|
|
|
TSharedRef<IDetailCustomization> FDTFluxModelAssetCustomization::MakeInstance()
|
|
{
|
|
return MakeShareable(new FDTFluxModelAssetCustomization);
|
|
}
|
|
|
|
EActiveTimerReturnType SDTFluxAssetModelDetailsWidget::ForceInitialLayout(double InCurrentTime, float InDeltaTime)
|
|
{
|
|
// Forcer la mise à jour des TreeViews
|
|
if (ContestTreeView.IsValid())
|
|
{
|
|
ContestTreeView->RequestTreeRefresh();
|
|
}
|
|
|
|
if (ParticipantTreeView.IsValid())
|
|
{
|
|
ParticipantTreeView->RequestTreeRefresh();
|
|
}
|
|
|
|
// Forcer l'invalidation du layout
|
|
Invalidate(EInvalidateWidget::Layout);
|
|
|
|
UE_LOG(LogTemp, Log, TEXT("Forced initial layout refresh"));
|
|
|
|
// Arrêter le timer (exécution unique)
|
|
return EActiveTimerReturnType::Stop;
|
|
}
|
|
|
|
void FDTFluxModelAssetCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
|
|
{
|
|
CustomizeDetailsWithRawDataAccess(DetailBuilder);
|
|
}
|
|
|
|
void FDTFluxModelAssetCustomization::CustomizeDetailsWithoutRawDataAsset(IDetailLayoutBuilder& DetailBuilder)
|
|
{
|
|
// Edit object
|
|
TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized;
|
|
DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingCustomized);
|
|
|
|
if (ObjectsBeingCustomized.Num() > 0)
|
|
{
|
|
ModelAsset = Cast<UDTFluxModelAsset>(ObjectsBeingCustomized[0].Get());
|
|
}
|
|
|
|
if (!ModelAsset.IsValid())
|
|
{
|
|
UE_LOG(LogTemp, Error, TEXT("No valid DTFluxModelAsset found"));
|
|
return;
|
|
}
|
|
|
|
// ===== Hiding Categories/Props =====
|
|
DetailBuilder.HideCategory("General");
|
|
DetailBuilder.HideCategory("Default");
|
|
DetailBuilder.HideCategory("Transform");
|
|
DetailBuilder.HideCategory("Rendering");
|
|
DetailBuilder.HideCategory("Input");
|
|
DetailBuilder.HideCategory("Actor");
|
|
DetailBuilder.HideCategory("Advanced");
|
|
// Hide individual Props
|
|
DetailBuilder.HideProperty("EventName");
|
|
DetailBuilder.HideProperty("Persons");
|
|
DetailBuilder.HideProperty("Participants");
|
|
DetailBuilder.HideProperty("Contests");
|
|
DetailBuilder.HideProperty("ContestRankings");
|
|
DetailBuilder.HideProperty("StageRankings");
|
|
DetailBuilder.HideProperty("SplitRankings");
|
|
|
|
IDetailCategoryBuilder& MainCategory = DetailBuilder.EditCategory(
|
|
"DTFlux Model Explorer",
|
|
FText::FromString("DTFlux Model Explorer"),
|
|
ECategoryPriority::Important
|
|
);
|
|
|
|
// Créer le widget hiérarchique
|
|
DetailsWidget = SNew(SDTFluxAssetModelDetailsWidget)
|
|
.ModelAsset(ModelAsset.Get());
|
|
|
|
MainCategory.AddCustomRow(FText::FromString("Data Explorer"))
|
|
.WholeRowContent()
|
|
[
|
|
SNew(SBox)
|
|
.MinDesiredHeight(800.0f)
|
|
[
|
|
DetailsWidget.ToSharedRef()
|
|
]
|
|
];
|
|
|
|
UE_LOG(LogTemp, Log, TEXT("DTFluxModelAsset custom-only interface applied"));
|
|
}
|
|
|
|
|
|
void FDTFluxModelAssetCustomization::CustomizeDetailsWithRawDataAccess(IDetailLayoutBuilder& DetailBuilder)
|
|
{
|
|
// Edit object
|
|
TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized;
|
|
DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingCustomized);
|
|
|
|
if (ObjectsBeingCustomized.Num() > 0)
|
|
{
|
|
ModelAsset = Cast<UDTFluxModelAsset>(ObjectsBeingCustomized[0].Get());
|
|
}
|
|
|
|
if (!ModelAsset.IsValid())
|
|
{
|
|
UE_LOG(LogTemp, Error, TEXT("No valid DTFluxModelAsset found"));
|
|
return;
|
|
}
|
|
// ===== WIDGET PRINCIPAL =====
|
|
IDetailCategoryBuilder& MainCategory = DetailBuilder.EditCategory(
|
|
"DTFlux Model Explorer",
|
|
FText::FromString("DTFlux Model Explorer"),
|
|
ECategoryPriority::Important
|
|
);
|
|
|
|
DetailsWidget = SNew(SDTFluxAssetModelDetailsWidget)
|
|
.ModelAsset(ModelAsset.Get());
|
|
|
|
MainCategory.AddCustomRow(FText::FromString("Data Explorer"))
|
|
.WholeRowContent()
|
|
[
|
|
SNew(SBox)
|
|
.MinDesiredHeight(650.0f)
|
|
|
|
[
|
|
DetailsWidget.ToSharedRef()
|
|
]
|
|
];
|
|
IDetailCategoryBuilder& QuickActionsCategory = DetailBuilder.EditCategory(
|
|
"Quick Actions",
|
|
FText::FromString("Quick Actions"),
|
|
ECategoryPriority::Default
|
|
);
|
|
|
|
QuickActionsCategory.AddCustomRow(FText::FromString("Raw Data Access"))
|
|
.NameContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString("Raw Data Access"))
|
|
.Font(FAppStyle::GetFontStyle("NormalText"))
|
|
]
|
|
.ValueContent()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(0, 0, 5, 0)
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FAppStyle::Get(), "Button")
|
|
.Text(FText::FromString("Edit Raw Properties"))
|
|
.ToolTipText(FText::FromString("Temporarily show standard properties for advanced editing"))
|
|
.OnClicked_Lambda([this, &DetailBuilder]() -> FReply
|
|
{
|
|
// Forcer le rafraîchissement du DetailsPanel pour montrer les propriétés standard
|
|
DetailBuilder.ForceRefreshDetails();
|
|
UE_LOG(LogTemp, Warning,
|
|
TEXT(
|
|
"Tip: To edit raw data, right-click the asset and choose 'Edit' or use the Content Browser"
|
|
));
|
|
return FReply::Handled();
|
|
})
|
|
]
|
|
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(0, 0, 5, 0)
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FAppStyle::Get(), "Button")
|
|
.Text(FText::FromString("Log All Data"))
|
|
.ToolTipText(FText::FromString("Print all data to Output Log"))
|
|
.OnClicked_Lambda([this]() -> FReply
|
|
{
|
|
if (ModelAsset.IsValid())
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("=== DTFLUX MODEL DUMP ==="));
|
|
UE_LOG(LogTemp, Warning, TEXT("Event: %s"), *ModelAsset->EventName);
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("--- CONTESTS (%d) ---"), ModelAsset->Contests.Num());
|
|
for (const auto& Contest : ModelAsset->Contests)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Contest '%s' (ID: %d) - %d stages, %d participants"),
|
|
*Contest.Key, Contest.Value.ContestId,
|
|
Contest.Value.Stages.Num(), Contest.Value.ParticipantsBib.Num());
|
|
}
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("--- PARTICIPANTS (%d) ---"), ModelAsset->Participants.Num());
|
|
for (const auto& Participant : ModelAsset->Participants)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Bib %d: %s (%s) - %d teammates"),
|
|
Participant.Value.Bib, *Participant.Value.Team,
|
|
*Participant.Value.Category, Participant.Value.GetTeammate().Num());
|
|
}
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("--- PERSONS (%d) ---"), ModelAsset->Persons.Num());
|
|
for (int32 i = 0; i < ModelAsset->Persons.Num(); ++i)
|
|
{
|
|
const auto& Person = ModelAsset->Persons[i];
|
|
UE_LOG(LogTemp, Warning, TEXT("Person %d: %s %s (%s)"),
|
|
i, *Person.FirstName, *Person.LastName, *Person.Gender);
|
|
}
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("======================="));
|
|
}
|
|
return FReply::Handled();
|
|
})
|
|
]
|
|
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FAppStyle::Get(), "PrimaryButton")
|
|
.Text(FText::FromString("Refresh"))
|
|
.ToolTipText(FText::FromString("Refresh the hierarchy view"))
|
|
.OnClicked_Lambda([this]() -> FReply
|
|
{
|
|
if (DetailsWidget.IsValid())
|
|
{
|
|
DetailsWidget->RefreshData();
|
|
}
|
|
return FReply::Handled();
|
|
})
|
|
]
|
|
];
|
|
}
|