Files
DTFluxAPI/Source/DTFluxAssetsEditor/Private/DTFluxModelAssetDetailCustomization.cpp

218 lines
6.4 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)
{
// 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)
{
// ===== 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();
})
]
];
}