October3d55/M/LGUI/Source/LGUIEditor/Private/DetailCustomization/UITextCustomization.cpp

374 lines
15 KiB
C++

// Copyright 2019-Present LexLiu. All Rights Reserved.
#include "DetailCustomization/UITextCustomization.h"
#include "HAL/PlatformApplicationMisc.h"
#include "Core/ActorComponent/UIText.h"
#include "LGUIEditorModule.h"
#include "DetailLayoutBuilder.h"
#include "DetailCategoryBuilder.h"
#include "IDetailGroup.h"
#define LOCTEXT_NAMESPACE "UITextCustomization"
FUITextCustomization::FUITextCustomization()
{
}
FUITextCustomization::~FUITextCustomization()
{
}
TSharedRef<IDetailCustomization> FUITextCustomization::MakeInstance()
{
return MakeShareable(new FUITextCustomization);
}
void FUITextCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
TArray<TWeakObjectPtr<UObject>> targetObjects;
DetailBuilder.GetObjectsBeingCustomized(targetObjects);
TargetScriptPtr = Cast<UUIText>(targetObjects[0].Get());
if (TargetScriptPtr == nullptr)
{
UE_LOG(LGUIEditor, Log, TEXT("[UITextCustomization]Get TargetScript is null"));
return;
}
IDetailCategoryBuilder& category = DetailBuilder.EditCategory("LGUI");
category.AddProperty(GET_MEMBER_NAME_CHECKED(UUIText, font));
category.AddProperty(GET_MEMBER_NAME_CHECKED(UUIText, text));
category.AddProperty(GET_MEMBER_NAME_CHECKED(UUIText, size));
category.AddProperty(GET_MEMBER_NAME_CHECKED(UUIText, space));
//text alignment
{
DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UUIText, hAlign));
DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(UUIText, vAlign));
const FMargin OuterPadding(2, 0);
const FMargin ContentPadding(2);
auto hAlignPropertyHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, hAlign));
auto vAlignPropertyHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, vAlign));
category.AddCustomRow(LOCTEXT("Alignment", "Alignment"))
.PropertyHandleList({ hAlignPropertyHandle, vAlignPropertyHandle })
.CopyAction(FUIAction(
FExecuteAction::CreateSP(this, &FUITextCustomization::OnCopyAlignment)
))
.PasteAction(FUIAction(
FExecuteAction::CreateSP(this, &FUITextCustomization::OnPasteAlignment, hAlignPropertyHandle, vAlignPropertyHandle),
FCanExecuteAction::CreateSP(this, &FUITextCustomization::OnCanPasteAlignment)
))
.NameContent()
[
SNew(STextBlock)
.Text(LOCTEXT("Alignment", "Alignment"))
.Font(IDetailLayoutBuilder::GetDetailFont())
]
.ValueContent()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew( SCheckBox )
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("AlignTextLeft", "Align Text Left"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleHorizontalAlignmentCheckStateChanged, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Left)
.IsChecked(this, &FUITextCustomization::GetHorizontalAlignmentCheckState, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Left)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("HorizontalAlignment_Left"))
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew(SCheckBox)
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("AlignTextCenter", "Align Text Center"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleHorizontalAlignmentCheckStateChanged, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Center)
.IsChecked(this, &FUITextCustomization::GetHorizontalAlignmentCheckState, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Center)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("HorizontalAlignment_Center"))
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew(SCheckBox)
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("AlignTextRight", "Align Text Right"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleHorizontalAlignmentCheckStateChanged, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Right)
.IsChecked(this, &FUITextCustomization::GetHorizontalAlignmentCheckState, hAlignPropertyHandle, EUITextParagraphHorizontalAlign::Right)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("HorizontalAlignment_Right"))
]
]
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(FMargin(2, 0))
[
SNew(SBox)
.WidthOverride(1)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("PropertyEditor.VerticalDottedLine"))
.ColorAndOpacity(FLinearColor(1, 1, 1, 0.2f))
]
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew( SCheckBox )
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("VAlignTop", "Vertically Align Top"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleVerticalAlignmentCheckStateChanged, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Top)
.IsChecked(this, &FUITextCustomization::GetVerticalAlignmentCheckState, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Top)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("VerticalAlignment_Top"))
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew(SCheckBox)
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("VAlignMiddle", "Vertically Align Middle"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleVerticalAlignmentCheckStateChanged, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Middle)
.IsChecked(this, &FUITextCustomization::GetVerticalAlignmentCheckState, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Middle)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("VerticalAlignment_Center"))
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(OuterPadding)
[
SNew(SCheckBox)
.Style(FAppStyle::Get(), "ToggleButtonCheckbox")
.ToolTipText(LOCTEXT("VAlignBottom", "Vertically Align Bottom"))
.Padding(ContentPadding)
.OnCheckStateChanged(this, &FUITextCustomization::HandleVerticalAlignmentCheckStateChanged, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Bottom)
.IsChecked(this, &FUITextCustomization::GetVerticalAlignmentCheckState, vAlignPropertyHandle, EUITextParagraphVerticalAlign::Bottom)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("VerticalAlignment_Bottom"))
]
]
]
]
.OverrideResetToDefault(FResetToDefaultOverride::Create(
TAttribute<bool>::CreateLambda([=]
{
return hAlignPropertyHandle->CanResetToDefault() || vAlignPropertyHandle->CanResetToDefault();
}),
FSimpleDelegate::CreateLambda([=]()
{
hAlignPropertyHandle->ResetToDefault(); vAlignPropertyHandle->ResetToDefault();
})
))
;
}
auto OverflowTypeHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, overflowType));
OverflowTypeHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateSP(this, &FUITextCustomization::ForceRefresh, &DetailBuilder));
auto AdjustWidthHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidth));
AdjustWidthHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateSP(this, &FUITextCustomization::ForceRefresh, &DetailBuilder));
auto AdjustHeightHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeight));
AdjustHeightHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateSP(this, &FUITextCustomization::ForceRefresh, &DetailBuilder));
EUITextOverflowType OverflowType;
OverflowTypeHandle->GetValue(*(uint8*)&OverflowType);
TArray<FName> needToHidePropertyName;
if (OverflowType == EUITextOverflowType::HorizontalOverflow)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeight));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeightRange));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, maxHorizontalWidth));
bool AdjustWidth;
AdjustWidthHandle->GetValue(AdjustWidth);
if (!AdjustWidth)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidthRange));
}
}
else if (OverflowType == EUITextOverflowType::VerticalOverflow)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidth));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidthRange));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, maxHorizontalWidth));
bool AdjustHeight;
AdjustHeightHandle->GetValue(AdjustHeight);
if (!AdjustHeight)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeightRange));
}
}
else if (OverflowType == EUITextOverflowType::HorizontalAndVerticalOverflow)
{
bool AdjustWidth;
AdjustWidthHandle->GetValue(AdjustWidth);
if (!AdjustWidth)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidthRange));
}
bool AdjustHeight;
AdjustHeightHandle->GetValue(AdjustHeight);
if (!AdjustHeight)
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeightRange));
}
}
else
{
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeight));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidth));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustHeightRange));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, adjustWidthRange));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, maxHorizontalWidth));
}
auto RichTextHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richText));
RichTextHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateSP(this, &FUITextCustomization::ForceRefresh, &DetailBuilder));
bool richText = false;
RichTextHandle->GetValue(richText);
if (richText)
{
IDetailGroup& RichTextGroup = category.AddGroup(FName("RichText"), RichTextHandle->GetPropertyDisplayName());
RichTextGroup.HeaderProperty(RichTextHandle);
RichTextGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richTextTagFilterFlags)));
RichTextGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richTextCustomStyleData)));
RichTextGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richTextImageData)));
RichTextGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, listRichTextImageObjectInOutliner)));
RichTextGroup.AddPropertyRow(DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, createdRichTextImageObjectArray)));
}
else
{
category.AddProperty(RichTextHandle);
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, richTextCustomStyleData));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, richTextImageData));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, listRichTextImageObjectInOutliner));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, createdRichTextImageObjectArray));
needToHidePropertyName.Add(GET_MEMBER_NAME_CHECKED(UUIText, richTextTagFilterFlags));
}
for (auto item : needToHidePropertyName)
{
DetailBuilder.HideProperty(item);
}
auto fontHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, font));
fontHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateLambda([=, this] {
TargetScriptPtr->OnPostChangeFontProperty();
}));
fontHandle->SetOnPropertyValuePreChange(FSimpleDelegate::CreateLambda([=, this]{
TargetScriptPtr->OnPreChangeFontProperty();
}));
auto richTextImageDataHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richTextImageData));
richTextImageDataHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateLambda([=, this] {
TargetScriptPtr->OnPostChangeRichTextImageDataProperty();
}));
richTextImageDataHandle->SetOnPropertyValuePreChange(FSimpleDelegate::CreateLambda([=, this] {
TargetScriptPtr->OnPreChangeRichTextImageDataProperty();
}));
auto richTextCustomStyleDataHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UUIText, richTextCustomStyleData));
richTextCustomStyleDataHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateLambda([=, this] {
TargetScriptPtr->OnPostChangeRichTextCustomStyleDataProperty();
}));
richTextCustomStyleDataHandle->SetOnPropertyValuePreChange(FSimpleDelegate::CreateLambda([=, this] {
TargetScriptPtr->OnPreChangeRichTextCustomStyleDataProperty();
}));
}
void FUITextCustomization::ForceRefresh(IDetailLayoutBuilder* DetailBuilder)
{
if (auto Script = TargetScriptPtr.Get())
{
DetailBuilder->ForceRefreshDetails();
}
}
void FUITextCustomization::HandleHorizontalAlignmentCheckStateChanged(ECheckBoxState InCheckboxState, TSharedRef<IPropertyHandle> PropertyHandle, EUITextParagraphHorizontalAlign ToAlignment)
{
PropertyHandle->SetValue((uint8)ToAlignment);
}
void FUITextCustomization::HandleVerticalAlignmentCheckStateChanged(ECheckBoxState InCheckboxState, TSharedRef<IPropertyHandle> PropertyHandle, EUITextParagraphVerticalAlign ToAlignment)
{
PropertyHandle->SetValue((uint8)ToAlignment);
}
ECheckBoxState FUITextCustomization::GetHorizontalAlignmentCheckState(TSharedRef<IPropertyHandle> PropertyHandle, EUITextParagraphHorizontalAlign ForAlignment) const
{
uint8 Value;
if (PropertyHandle->GetValue(Value) == FPropertyAccess::Result::Success)
{
return Value == (uint8)ForAlignment ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
}
return ECheckBoxState::Unchecked;
}
ECheckBoxState FUITextCustomization::GetVerticalAlignmentCheckState(TSharedRef<IPropertyHandle> PropertyHandle, EUITextParagraphVerticalAlign ForAlignment) const
{
uint8 Value;
if (PropertyHandle->GetValue(Value) == FPropertyAccess::Result::Success)
{
return Value == (uint8)ForAlignment ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
}
return ECheckBoxState::Unchecked;
}
#define BEGIN_ALIGNMENT_CLIPBOARD TEXT("Begin LGUI UIWidget")
void FUITextCustomization::OnCopyAlignment()
{
if (TargetScriptPtr.IsValid())
{
FString CopiedText = FString::Printf(TEXT("%s, hAlign=%d, vAlign=%d"), BEGIN_ALIGNMENT_CLIPBOARD, (int)TargetScriptPtr->hAlign, (int)TargetScriptPtr->vAlign);
FPlatformApplicationMisc::ClipboardCopy(*CopiedText);
}
}
void FUITextCustomization::OnPasteAlignment(TSharedRef<IPropertyHandle> HAlignPropertyHandle, TSharedRef<IPropertyHandle> VAlignPropertyHandle)
{
FString PastedText;
FPlatformApplicationMisc::ClipboardPaste(PastedText);
if (PastedText.StartsWith(BEGIN_ALIGNMENT_CLIPBOARD))
{
uint8 tempUInt8;
FParse::Value(*PastedText, TEXT("hAlign="), tempUInt8);
HAlignPropertyHandle->SetValue(tempUInt8);
FParse::Value(*PastedText, TEXT("vAlign="), tempUInt8);
VAlignPropertyHandle->SetValue(tempUInt8);
}
}
bool FUITextCustomization::OnCanPasteAlignment()const
{
FString PastedText;
FPlatformApplicationMisc::ClipboardPaste(PastedText);
return PastedText.StartsWith(BEGIN_ALIGNMENT_CLIPBOARD);
}
#undef LOCTEXT_NAMESPACE