221 lines
8.4 KiB
C++
221 lines
8.4 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "FontFaceDetailsCustomization.h"
|
|
|
|
#include "DesktopPlatformModule.h"
|
|
#include "DetailCategoryBuilder.h"
|
|
#include "DetailLayoutBuilder.h"
|
|
#include "DetailWidgetRow.h"
|
|
#include "EditorDirectories.h"
|
|
#include "EditorFontGlyphs.h"
|
|
#include "Engine/FontFace.h"
|
|
#include "Fonts/CompositeFont.h"
|
|
#include "Fonts/FontCache.h"
|
|
#include "Fonts/SlateFontInfo.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "HAL/Platform.h"
|
|
#include "IDesktopPlatform.h"
|
|
#include "IDetailGroup.h"
|
|
#include "Internationalization/Internationalization.h"
|
|
#include "Layout/Margin.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "Misc/Attribute.h"
|
|
#include "Misc/FileHelper.h"
|
|
#include "Misc/Optional.h"
|
|
#include "Misc/Paths.h"
|
|
#include "PropertyHandle.h"
|
|
#include "Rendering/SlateRenderer.h"
|
|
#include "ScopedTransaction.h"
|
|
#include "SlotBase.h"
|
|
#include "Styling/AppStyle.h"
|
|
#include "Styling/ISlateStyle.h"
|
|
#include "Styling/SlateColor.h"
|
|
#include "Templates/Casts.h"
|
|
#include "Templates/UnrealTemplate.h"
|
|
#include "Types/SlateEnums.h"
|
|
#include "UObject/Object.h"
|
|
#include "UObject/WeakObjectPtr.h"
|
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
|
#include "Widgets/Input/SButton.h"
|
|
#include "Widgets/SBoxPanel.h"
|
|
#include "Widgets/Text/STextBlock.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "FontFaceDetailsCustomization"
|
|
|
|
void FFontFaceDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
|
|
{
|
|
DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingEdited);
|
|
|
|
TSharedPtr<IPropertyHandle> SourceFilenamePropertyHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, SourceFilename));
|
|
SourceFilenamePropertyHandle->MarkHiddenByCustomization();
|
|
|
|
IDetailCategoryBuilder& FontFaceCategory = DetailBuilder.EditCategory("FontFace");
|
|
|
|
// Source Filename
|
|
{
|
|
FontFaceCategory.AddCustomRow(SourceFilenamePropertyHandle->GetPropertyDisplayName())
|
|
.NameContent()
|
|
[
|
|
SourceFilenamePropertyHandle->CreatePropertyNameWidget()
|
|
]
|
|
.ValueContent()
|
|
.VAlign(VAlign_Center)
|
|
.MinDesiredWidth(TOptional<float>())
|
|
.MaxDesiredWidth(TOptional<float>())
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
+SHorizontalBox::Slot()
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(STextBlock)
|
|
.Font(DetailBuilder.GetDetailFont())
|
|
.Text(this, &FFontFaceDetailsCustomization::GetFontDisplayName)
|
|
.ToolTipText(this, &FFontFaceDetailsCustomization::GetFontDisplayToolTip)
|
|
]
|
|
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(4.0f, 0.0f, 0.0f, 0.0f)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FAppStyle::Get(), "HoverHintOnly")
|
|
.ToolTipText(LOCTEXT("FontFilePathPickerToolTip", "Choose a font file from this computer"))
|
|
.OnClicked(this, &FFontFaceDetailsCustomization::OnBrowseFontPath)
|
|
.ContentPadding(2.0f)
|
|
.ForegroundColor(FSlateColor::UseForeground())
|
|
.IsFocusable(false)
|
|
[
|
|
SNew(STextBlock)
|
|
.Font(FAppStyle::Get().GetFontStyle("FontAwesome.10"))
|
|
.Text(FEditorFontGlyphs::Folder_Open)
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
// Distance field properties
|
|
if (IsSlateSdfTextFeatureEnabled())
|
|
{
|
|
bool bShowDistanceFieldGroups = true;
|
|
if (ObjectsBeingEdited.Num() == 1)
|
|
{
|
|
const UFontFace* FontFace = Cast<UFontFace>(ObjectsBeingEdited[0].Get());
|
|
if (FontFace && !FontFace->bEnableDistanceFieldRendering)
|
|
{
|
|
bShowDistanceFieldGroups = false;
|
|
}
|
|
}
|
|
if (bShowDistanceFieldGroups)
|
|
{
|
|
IDetailCategoryBuilder& DistanceFieldModeCategory = DetailBuilder.EditCategory("DistanceFieldMode");
|
|
// Make sure that bEnableDistanceFieldRendering is listed first
|
|
DistanceFieldModeCategory.AddProperty(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, bEnableDistanceFieldRendering)));
|
|
// Single-channel distance field resolution group
|
|
IDetailGroup& SingleChannelResolutionGroup = DistanceFieldModeCategory.AddGroup(FName(TEXT("SingleChannelDistanceFieldResolution")), LOCTEXT("FontFaceSingleChannelDistanceFieldResolutionGroup", "Single-Channel Distance Field Resolution (px/em)"), false, true);
|
|
SingleChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MinDistanceFieldPpem)));
|
|
SingleChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MidDistanceFieldPpem)));
|
|
SingleChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MaxDistanceFieldPpem)));
|
|
// Multi-channel distance field resolution group
|
|
IDetailGroup& MultiChannelResolutionGroup = DistanceFieldModeCategory.AddGroup(FName(TEXT("MultiChannelDistanceFieldResolution")), LOCTEXT("FontFaceMultiChannelDistanceFieldResolutionGroup", "Multi-Channel Distance Field Resolution (px/em)"), false, true);
|
|
MultiChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MinMultiDistanceFieldPpem)));
|
|
MultiChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MidMultiDistanceFieldPpem)));
|
|
MultiChannelResolutionGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MaxMultiDistanceFieldPpem)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Hide distance field settings if disabled by CVar
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, bEnableDistanceFieldRendering))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MinDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MidDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MaxDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MinMultiDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MidMultiDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, MaxMultiDistanceFieldPpem))->MarkHiddenByCustomization();
|
|
DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFontFace, PlatformRasterizationModeOverrides))->MarkHiddenByCustomization();
|
|
}
|
|
}
|
|
|
|
FText FFontFaceDetailsCustomization::GetFontDisplayName() const
|
|
{
|
|
if (ObjectsBeingEdited.Num() == 1)
|
|
{
|
|
const UFontFace* FontFace = Cast<UFontFace>(ObjectsBeingEdited[0].Get());
|
|
if (FontFace && !FontFace->SourceFilename.IsEmpty())
|
|
{
|
|
return FText::FromString(FPaths::GetCleanFilename(FontFace->SourceFilename));
|
|
}
|
|
}
|
|
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
FText FFontFaceDetailsCustomization::GetFontDisplayToolTip() const
|
|
{
|
|
if (ObjectsBeingEdited.Num() == 1)
|
|
{
|
|
const UFontFace* FontFace = Cast<UFontFace>(ObjectsBeingEdited[0].Get());
|
|
if (FontFace && !FontFace->SourceFilename.IsEmpty())
|
|
{
|
|
return FText::FromString(FontFace->SourceFilename);
|
|
}
|
|
}
|
|
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
FReply FFontFaceDetailsCustomization::OnBrowseFontPath()
|
|
{
|
|
IDesktopPlatform* const DesktopPlatform = FDesktopPlatformModule::Get();
|
|
|
|
if (DesktopPlatform)
|
|
{
|
|
const FString DefaultPath = FEditorDirectories::Get().GetLastDirectory(ELastDirectory::GENERIC_OPEN);
|
|
|
|
TArray<FString> OutFiles;
|
|
if (DesktopPlatform->OpenFileDialog(
|
|
nullptr,
|
|
LOCTEXT("FontPickerTitle", "Choose a font file...").ToString(),
|
|
DefaultPath,
|
|
TEXT(""),
|
|
TEXT("All Font Files (*.ttf, *.ttc, *.otf, *.otc)|*.ttf;*.ttc;*.otf;*.otc|TrueType fonts (*.ttf, *.ttc)|*.ttf;*.ttc|OpenType fonts (*.otf, *.otc)|*.otf;*.otc"),
|
|
EFileDialogFlags::None,
|
|
OutFiles
|
|
))
|
|
{
|
|
OnFontPathPicked(OutFiles[0]);
|
|
}
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
void FFontFaceDetailsCustomization::OnFontPathPicked(const FString& InNewFontFilename)
|
|
{
|
|
TArray<uint8> FontData;
|
|
FFileHelper::LoadFileToArray(FontData, *InNewFontFilename);
|
|
|
|
const FScopedTransaction Transaction(LOCTEXT("SetFontFile", "Set Font File"));
|
|
|
|
for (const TWeakObjectPtr<UObject>& ObjectBeingEdited : ObjectsBeingEdited)
|
|
{
|
|
UFontFace* FontFace = Cast<UFontFace>(ObjectBeingEdited.Get());
|
|
if (FontFace)
|
|
{
|
|
FontFace->Modify();
|
|
FontFace->SourceFilename = InNewFontFilename;
|
|
FontFace->FontFaceData = FFontFaceData::MakeFontFaceData(MoveTemp(FontData)); // Make a new instance as the existing one may be being used by the font cache
|
|
FontFace->CacheSubFaces();
|
|
FontFace->PostEditChange();
|
|
}
|
|
}
|
|
|
|
FEditorDirectories::Get().SetLastDirectory(ELastDirectory::GENERIC_OPEN, FPaths::GetPath(InNewFontFilename));
|
|
|
|
FSlateApplication::Get().GetRenderer()->FlushFontCache(TEXT("FFontFaceDetailsCustomization::OnFontPathPicked"));
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|