You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
This was causing issues when an SEnumCombo was embedded into a menu builder, because the top-level menu was keeping the SEnumCombo alive, causing the OnEnumSelectionChangedDelegate to never fire. Reported from UDN: https://epicgames.lightning.force.com/lightning/r/Case/5004z00001eEsHSAA0/view #review-20322055 @lauren.barnes, @mikko.mononen #preflight 628b9e7d573a7de2c4272968 [CL 20328054 by sebastian nordgren in ue5-main branch]
203 lines
5.2 KiB
C++
203 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SEnumCombo.h"
|
|
#include "Styling/AppStyle.h"
|
|
#include "Types/SlateEnums.h"
|
|
#include "Widgets/SToolTip.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "EditorWidgets"
|
|
|
|
void SEnumComboBox::Construct(const FArguments& InArgs, const UEnum* InEnum)
|
|
{
|
|
static const FName UseEnumValuesAsMaskValuesInEditorName(TEXT("UseEnumValuesAsMaskValuesInEditor"));
|
|
|
|
Enum = InEnum;
|
|
CurrentValue = InArgs._CurrentValue;
|
|
check(CurrentValue.IsBound());
|
|
OnEnumSelectionChangedDelegate = InArgs._OnEnumSelectionChanged;
|
|
OnGetToolTipForValue = InArgs._OnGetToolTipForValue;
|
|
Font = InArgs._Font;
|
|
bUpdatingSelectionInternally = false;
|
|
bIsBitflagsEnum = Enum->HasMetaData(TEXT("Bitflags"));
|
|
|
|
if (bIsBitflagsEnum)
|
|
{
|
|
const bool bUseEnumValuesAsMaskValues = Enum->GetBoolMetaData(UseEnumValuesAsMaskValuesInEditorName);
|
|
const int32 BitmaskBitCount = sizeof(int32) << 3;
|
|
|
|
for (int32 i = 0; i < Enum->NumEnums() - 1; i++)
|
|
{
|
|
// Note: SEnumComboBox API prior to bitflags only supports 32 bit values, truncating the value here to keep the old API.
|
|
int32 Value = Enum->GetValueByIndex(i);
|
|
const bool bIsHidden = Enum->HasMetaData(TEXT("Hidden"), i);
|
|
if (Value >= 0 && !bIsHidden)
|
|
{
|
|
if (bUseEnumValuesAsMaskValues)
|
|
{
|
|
if (Value >= MAX_int32 || !FMath::IsPowerOfTwo(Value))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Value >= BitmaskBitCount)
|
|
{
|
|
continue;
|
|
}
|
|
Value = 1 << Value;
|
|
}
|
|
|
|
FText DisplayName = Enum->GetDisplayNameTextByIndex(i);
|
|
FText TooltipText = Enum->GetToolTipTextByIndex(i);
|
|
if (TooltipText.IsEmpty())
|
|
{
|
|
TooltipText = FText::Format(LOCTEXT("BitmaskDefaultFlagToolTipText", "Toggle {0} on/off"), DisplayName);
|
|
}
|
|
|
|
VisibleEnums.Emplace(i, Value, DisplayName, TooltipText);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 i = 0; i < Enum->NumEnums() - 1; i++)
|
|
{
|
|
if (Enum->HasMetaData(TEXT("Hidden"), i) == false)
|
|
{
|
|
VisibleEnums.Emplace(i, Enum->GetValueByIndex(i), Enum->GetDisplayNameTextByIndex(i), Enum->GetToolTipTextByIndex(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
SComboButton::Construct(SComboButton::FArguments()
|
|
.ButtonStyle(InArgs._ButtonStyle)
|
|
.ContentPadding(InArgs._ContentPadding)
|
|
.OnGetMenuContent(this, &SEnumComboBox::OnGetMenuContent)
|
|
.ButtonContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.Font(Font)
|
|
.Text(this, &SEnumComboBox::GetCurrentValueText)
|
|
.ToolTipText(this, &SEnumComboBox::GetCurrentValueTooltip)
|
|
]);
|
|
}
|
|
|
|
|
|
FText SEnumComboBox::GetCurrentValueText() const
|
|
{
|
|
if (bIsBitflagsEnum)
|
|
{
|
|
if (CurrentValue.IsSet())
|
|
{
|
|
const int32 BitmaskValue = CurrentValue.Get();
|
|
if (BitmaskValue != 0)
|
|
{
|
|
TArray<FText> SetFlags;
|
|
SetFlags.Reserve(VisibleEnums.Num());
|
|
|
|
for (const FEnumInfo& FlagInfo : VisibleEnums)
|
|
{
|
|
if ((BitmaskValue & FlagInfo.Value) != 0)
|
|
{
|
|
SetFlags.Add(FlagInfo.DisplayName);
|
|
}
|
|
}
|
|
if (SetFlags.Num() > 3)
|
|
{
|
|
SetFlags.SetNum(3);
|
|
SetFlags.Add(FText::FromString("..."));
|
|
}
|
|
|
|
return FText::Join(FText::FromString(" | "), SetFlags);
|
|
}
|
|
return LOCTEXT("BitmaskButtonContentNoFlagsSet", "(No Flags Set)");
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
const int32 ValueNameIndex = Enum->GetIndexByValue(CurrentValue.Get());
|
|
return Enum->GetDisplayNameTextByIndex(ValueNameIndex);
|
|
}
|
|
|
|
FText SEnumComboBox::GetCurrentValueTooltip() const
|
|
{
|
|
if (bIsBitflagsEnum)
|
|
{
|
|
const int32 BitmaskValue = CurrentValue.Get();
|
|
if (BitmaskValue != 0)
|
|
{
|
|
TArray<FText> SetFlags;
|
|
SetFlags.Reserve(VisibleEnums.Num());
|
|
|
|
for (const FEnumInfo& FlagInfo : VisibleEnums)
|
|
{
|
|
if ((BitmaskValue & FlagInfo.Value) != 0)
|
|
{
|
|
if (OnGetToolTipForValue.IsBound())
|
|
{
|
|
SetFlags.Add(OnGetToolTipForValue.Execute(FlagInfo.Index));
|
|
}
|
|
else
|
|
{
|
|
SetFlags.Add(FlagInfo.DisplayName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return FText::Join(FText::FromString(" | "), SetFlags);
|
|
}
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
const int32 ValueNameIndex = Enum->GetIndexByValue(CurrentValue.Get());
|
|
if (OnGetToolTipForValue.IsBound())
|
|
{
|
|
return OnGetToolTipForValue.Execute(ValueNameIndex);
|
|
}
|
|
return Enum->GetToolTipTextByIndex(ValueNameIndex);
|
|
}
|
|
|
|
TSharedRef<SWidget> SEnumComboBox::OnGetMenuContent()
|
|
{
|
|
const bool bCloseAfterSelection = !bIsBitflagsEnum;
|
|
FMenuBuilder MenuBuilder(bCloseAfterSelection, nullptr, nullptr, true);
|
|
|
|
for (const FEnumInfo& FlagInfo : VisibleEnums)
|
|
{
|
|
MenuBuilder.AddMenuEntry(
|
|
FlagInfo.DisplayName,
|
|
FlagInfo.TooltipText,
|
|
FSlateIcon(),
|
|
FUIAction
|
|
(
|
|
FExecuteAction::CreateLambda([this, FlagInfo]()
|
|
{
|
|
if (bIsBitflagsEnum)
|
|
{
|
|
// Toggle value
|
|
const int32 Value = CurrentValue.Get() ^ FlagInfo.Value;
|
|
OnEnumSelectionChangedDelegate.ExecuteIfBound(Value, ESelectInfo::Direct);
|
|
}
|
|
else
|
|
{
|
|
// Set value
|
|
OnEnumSelectionChangedDelegate.ExecuteIfBound(FlagInfo.Value, ESelectInfo::OnMouseClick);
|
|
}
|
|
}),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateLambda([this, FlagInfo]() -> bool
|
|
{
|
|
return (CurrentValue.Get() & FlagInfo.Value) != 0;
|
|
})
|
|
),
|
|
NAME_None,
|
|
bIsBitflagsEnum ? EUserInterfaceActionType::Check : EUserInterfaceActionType::None);
|
|
}
|
|
|
|
return MenuBuilder.MakeWidget();
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|