31. Aura HUD (plus other stuff)

- Enabled a few more plugins
- Added clang formatting straight from the GasaGen cpp.
- Setup auto-generation of the DevOptionsCache
- Messed around with generating widgettree hiearchy from template widget
This commit is contained in:
2024-04-21 09:51:51 -04:00
parent 466adc5bd9
commit 6765478a9d
64 changed files with 2757 additions and 1551 deletions

View File

@ -0,0 +1,171 @@
#include "GlobeProgressBarDetails.h"
#include "BaseWidgetBlueprint.h"
#include "BlueprintEditor.h"
#include "GasaEditorCommon.h"
#include "DetailCategoryBuilder.h"
#include "DetailLayoutBuilder.h"
#include "DetailWidgetRow.h"
#include "PropertyCustomizationHelpers.h"
#include "Blueprint/WidgetBlueprintGeneratedClass.h"
#include "Blueprint/WidgetTree.h"
#include "Components/ProgressBar.h"
#include "Gasa/UI/GlobeProgressBar.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "UI/GasaProgressBar.h"
UE_DISABLE_OPTIMIZATION
void FGlobeProgressBarDetails::CustomizeDetails(IDetailLayoutBuilder& LayoutBuilder)
{
IDetailCategoryBuilder& GlobeCategory = LayoutBuilder.EditCategory("Globe");
UObject* GlobeBar = nullptr;
UGlobeProgressBar* Globe = nullptr;
for (TWeakObjectPtr<UObject> Object : LayoutBuilder.GetSelectedObjects())
{
if ( ! Object.IsValid())
return;
Globe = Cast<UGlobeProgressBar>(Object.Get());
if (Globe)
break;
}
if (Globe && Globe->Bar)
{
auto StyleFillImage = Globe->Bar->GetWidgetStyle().FillImage.GetResourceObject();
Thumbnail = MakeShareable(new FAssetThumbnail(FAssetData(StyleFillImage), 64, 64, LayoutBuilder.GetThumbnailPool()));
}
TSharedPtr<IPropertyHandle>
ProgressBarStyle = LayoutBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UGlobeProgressBar, Bar), UGlobeProgressBar::StaticClass());
ProgressBarStyle->GetValue(GlobeBar);
if (ProgressBarStyle && ! ProgressBarStyle->IsValidHandle())
return;
// This can't be done, UE widget parenting forces the parent widget's hierarchy to be immutable at 'design time'.
// This is because a proper clone of the UWidgetBlueprintGeneratedClass parent's widget tree is not done.
// Instead... I don't even know what they are even doing with the widget tree because somehow they still have a unique widget tree
// for at least the child widget.
// All code paths related to this are not navigable in a reasonable amount of time.
// So I don't even know why this failure point exist architecturally...
#if 0
// TSharedPtr<IPropertyHandle> WidgetStyle = ProgressBarStyleHandle->GetChildHandle("WidgetStyle");
// if ( ! WidgetStyle.IsValid())
// return;
IDetailPropertyRow& ProgressBarRow = LayoutBuilder.AddPropertyToCategory(ProgressBarStyle);
FDetailWidgetRow& RowWidget = ProgressBarRow.CustomWidget();
{
FDetailWidgetDecl& RowNameWidget = RowWidget.NameContent();
{
TSharedRef<STextBlock>
TextBlock = SNew(STextBlock);
TextBlock->SetText(FText::FromString(TEXT("Bar Fill Material")));
TextBlock->SetFont(LayoutBuilder.GetDetailFont());
RowNameWidget.Widget = TextBlock;
}
FDetailWidgetDecl& RowValueWidget = RowWidget.ValueContent();
TSharedRef<SHorizontalBox> HBox = SNew(SHorizontalBox);
{
SHorizontalBox::FSlot::FSlotArguments ThumbnailSlot = SHorizontalBox::Slot();
{
TSharedRef<SBox> ThumbnailBox = SNew(SBox);
ThumbnailBox->SetWidthOverride(64);
ThumbnailBox->SetHeightOverride(64);
if ( Thumbnail.IsValid() )
ThumbnailBox->SetContent( Thumbnail->MakeThumbnailWidget());
else
ThumbnailBox->SetContent( SNullWidget::NullWidget );
ThumbnailSlot.AutoWidth();
ThumbnailSlot.AttachWidget( ThumbnailBox );
}
SHorizontalBox::FSlot::FSlotArguments DropDownSlot = SHorizontalBox::Slot();
{
TSharedRef<SObjectPropertyEntryBox> EntryBox = SNew(SObjectPropertyEntryBox);
{
SObjectPropertyEntryBox::FArguments Args;
Args.PropertyHandle(ProgressBarStyle);
Args.AllowClear(false);
// Args.OnShouldFilterAsset_Lambda( [&](FAssetData const& Asset) -> bool
// {
// FString const AssetPath = Asset.ObjectPath.ToString();
// // Add conditional filters here
// return true;
// });
Args.DisplayThumbnail(false);
Args.OnObjectChanged_Lambda( [this, Globe, &ProgressBarStyle, &LayoutBuilder](FAssetData const& Asset)
{
if ( ! Asset.IsValid() || ! Thumbnail.IsValid() || ! Globe || ! Globe->Bar )
return;
FProgressBarStyle
Style = Globe->Bar->GetWidgetStyle();
Style.FillImage.SetResourceObject(Asset.GetAsset());
// Get the Blueprint that owns this widget and mark it as modified
UBaseWidgetBlueprint* GlobeBP = Cast<UBaseWidgetBlueprint>(Globe->WidgetGeneratedBy);
if (GlobeBP != nullptr)
{
GlobeBP->Modify();
UObject* CDO = GlobeBP->GeneratedClass->GetDefaultObject();
UGlobeProgressBar* GlobeCDO = Cast<UGlobeProgressBar>(CDO);
UWidget* PossibleWidget = Cast<UBaseWidgetBlueprint>(GlobeBP)->WidgetTree->FindWidget("Bar");
if (PossibleWidget)
{
UGasaProgressBar* BarWidget = Cast<UGasaProgressBar>(PossibleWidget);
BarWidget->SetWidgetStyle(Style);
GlobeBP->MarkPackageDirty();
}
else // Its parent is it.
{
UWidgetBlueprintGeneratedClass* Parent = Cast<UWidgetBlueprintGeneratedClass>(GlobeBP->ParentClass);
UPackage* Pkg = Parent->GetOuterUPackage();
PossibleWidget = Parent->GetWidgetTreeArchetype()->FindWidget("Bar");
if (PossibleWidget)
{
GlobeCDO->Bar = GlobeCDO->WidgetTree->ConstructWidget<UGasaProgressBar>( PossibleWidget->GetClass(), "Bar" );
Globe->Bar = GlobeCDO->Bar;
GlobeCDO->Modify();
GlobeCDO->MarkPackageDirty();
}
}
}
Globe->SetBarStyle(Style);
Globe->Bar->Modify();
Globe->Modify();
Thumbnail->SetAsset(Asset);
Thumbnail->RefreshThumbnail();
});
// Args.CustomResetToDefault(FResetToDefaultOverride::Hide());
Args.DisplayBrowse(true);
EntryBox->Construct(Args);
}
DropDownSlot.AutoWidth();
DropDownSlot.AttachWidget(EntryBox);
}
SHorizontalBox::FArguments Args = SHorizontalBox::FArguments();
Args.operator+(ThumbnailSlot);
Args.operator+(DropDownSlot);
HBox->Construct(Args);
RowValueWidget.Widget = HBox;
}
}
#endif
}
bool FGlobeProgressBarDetails::CheckAsset(FAssetData const& Asset)
{
return true;
}
UE_ENABLE_OPTIMIZATION

View File

@ -0,0 +1,14 @@
#pragma once
#include "IDetailCustomization.h"
class FGlobeProgressBarDetails : public IDetailCustomization
{
public:
static TSharedRef<IDetailCustomization> MakeInstance() { return MakeShareable(new FGlobeProgressBarDetails); }
void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
static bool CheckAsset(FAssetData const& Asset);
TSharedPtr<FAssetThumbnail> Thumbnail;
};

View File

@ -8,12 +8,22 @@ public class GasaEditor : ModuleRules
#region Engine
PrivateIncludePathModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
});
PrivateDependencyModuleNames.AddRange(new string[] {
"Core",
"Core",
"Engine",
"CoreUObject",
"PropertyEditor",
"SlateCore",
"Slate",
"UMG",
"UnrealEd",
});
#endregion Engine
PublicIncludePathModuleNames.Add("Gasa");
PublicIncludePaths.Add("GasaEditor");
PrivateDependencyModuleNames.Add("Gasa");
}
}

View File

@ -0,0 +1,3 @@
#include "GasaEditorCommon.h"
DEFINE_LOG_CATEGORY(LogGasaEditor);

View File

@ -0,0 +1,68 @@

#pragma once
#include "CoreMinimal.h"
#include "Gasa/GasaCommon.h"
#pragma region Engine Forwards
#pragma endregion Engine Forwards
#pragma region Engine Plugin Forwards
#pragma endregion Engine Plugin Forwards
// Gasa Editor
#pragma region Forwards
#pragma endregion Forwards
#pragma region Logging
DECLARE_LOG_CATEGORY_EXTERN(LogGasaEditor, Log, All);
namespace Gasa
{
using ELogV = EGasaVerbosity;
//◞ ‸ ◟//
// Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now)
inline
void LogEditor( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log
, FLogCategoryBase& Category = LogGasaEditor
, bool DumpStack = false
, int32 Line = __builtin_LINE()
, const ANSICHAR* File = __builtin_FILE()
, const ANSICHAR* Func = __builtin_FUNCTION() )
{
#if !UE_BUILD_SHIPPING && !NO_LOGGING
ELogVerbosity::Type EngineVerbosity = (ELogVerbosity::Type) Verbosity;
static UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic;
static UE::Logging::Private::FStaticBasicLogRecord
LOG_Static(TEXT("%80s -- %hs %hs(%d)"), File, Line, EngineVerbosity, LOG_Dynamic);
if ((EngineVerbosity & ELogVerbosity::VerbosityMask) <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY)
{
if ((EngineVerbosity & ELogVerbosity::VerbosityMask) <= Category.GetVerbosity())
{
if ( ! Category.IsSuppressed(EngineVerbosity))
{
if (DumpStack)
FDebug::DumpStackTraceToLog(EngineVerbosity);
BasicLog(Category, &LOG_Static, *Message, File, Func, Line);
}
}
}
#endif
}
}
#define GasaEd_Fatal(Message) UE_LOG( LogGasaEditor, Fatal, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_FILE(), __func__, __builtin_LINE() );
#define GasaEd_Error(Message) UE_LOG( LogGasaEditor, Error, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#define GasaEd_Warning(Message) UE_LOG( LogGasaEditor, Warning, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#define GasaEd_Display(Message) UE_LOG( LogGasaEditor, Display, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#define GasaEd_Log(Message) UE_LOG( LogGasaEditor, Log, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#define GasaEd_Verbose(Message) UE_LOG( LogGasaEditor, Verbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#define GasaEd_VeryVerbose(Message) UE_LOG( LogGasaEditor, VeryVerbose, TEXT("%s -- %hs %hs(%d)"), *Message, __builtin_File(), __func__, __builtin_LINE() );
#pragma endregion Logging
#pragma region Timing
#pragma endregion Timing

View File

@ -1,14 +1,25 @@
#include "GasaEditorModule.h"
#include "EditorDetails/GlobeProgressBarDetails.h"
#include "UI/GlobeProgressBar.h"
IMPLEMENT_PRIMARY_GAME_MODULE(FGasaEditorModule, GasaEditor, GasaEditor);
void FGasaEditorModule::StartupModule()
{
FPropertyEditorModule& PropertyEditor = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyEditor.RegisterCustomClassLayout( UGlobeProgressBar::StaticClass()->GetFName()
, FOnGetDetailCustomizationInstance::CreateStatic(& FGlobeProgressBarDetails::MakeInstance)
);
}
void FGasaEditorModule::ShutdownModule()
{
if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
{
FPropertyEditorModule& PropertyEditor = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyEditor.UnregisterCustomClassLayout(UGlobeProgressBar::StaticClass()->GetFName());
}
}