Files
UnrealEngineUWP/Engine/Source/Editor/EnvironmentQueryEditor/Private/DetailCustomizations/EnvQueryTestDetails.cpp

745 lines
25 KiB
C++
Raw Normal View History

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
Merging UE4-Pretest @ 2042161 to UE4 Change 1996384 by Andrew Brown: 322252 - EDITOR: Asset picker displays incorrect text when there are no filter results. Change 1996385 by Andrew Brown: 321858 - CRASH: Assertion failed: (Index >= 0) Function: STransformViewportToolBar::GetLocationGridLabel() STextBlock::CacheDesiredSize() Change 1996977 by Andrew Brown: 309685 - UE4: Adding an event/renaming an event on an event track in Matinee does not update the MatineeActor node in blueprint Change 2034873 by Jaroslaw Palczynski: More robust VS installation detection. Change 2039693 by Jaroslaw Palczynski: 327268 - RocketGDC: POSTLAUNCH: DEV: Make engine more robust against bad Visual Studio environment variables Change 1978978 by Jaroslaw Surowiec: - Removed obsolete AllowEliminatingReferences from the FArchive Change 2020326 by Maciej Mroz: pretest BP K2Node: RemovePinsFromOldPins function moved from K2Node to RemovePinsFromOldPins Change 2017608 by Maciej Mroz: pretest Some changes in SFortMissionEventSelector caused by FPinTypeTreeInfo Change 2017463 by Maciej Mroz: PinTypeSelector can lins unloaded UDStructs Change 2019979 by Maciej Mroz: pretest BP: Crash when performing Diff against Depot with blueprints containing Format Text nodes Change 2024469 by Maciej Mroz: MemberReference variable added to PinType. It's necessary for delegate's signature. Change 2024049 by Maciej Mroz: HasExternalBlueprintDependencies added to UK2Node_DynamicCast Change 2024586 by Maciej Mroz: FillSimpleMemberReference fix Change 2024472 by Maciej Mroz: workaround for delegates signature in pintype removed. Change 2023997 by Maciej Mroz: BP, UDStruc: Class UserDefinedStructEditorData added. It fixes many problems with undo/redo. Change 2021934 by Maciej Mroz: typo in a comment Change 2020355 by Maciej Mroz: Back out changelist 2020342 Change 2022178 by Maciej Mroz: CRASH: PRETEST: EDITOR: UDS: Crash when undo then redo new variable in struct that is used by blueprint Change 2021958 by Maciej Mroz: CRASH: PRETEST: EDITOR: UDS: Crash using variable of a type of copied struct in blueprint Change 1986247 by Maciej Mroz: User Defined Structures: circle dependency fixed. Early version. Change 1985107 by Maciej Mroz: UserDefinedStruct cannot have a field of a non-native type Change 1986278 by Maciej Mroz: pretest ensureMsgf in Struct::link Change 1986250 by Maciej Mroz: User Defined Struct: Non native classes are accepted types od values in structures. Change 1980955 by Maciej Mroz: Using AssetPtr and LazyPtr as UFunction parameter (intput or return) is explicitly disallowed. Change 2041215 by Maciej Mroz: ttp331249 BLOCKER: PRETEST: UI: Survive the Storm is missing the Mission HUD. Change 1984316 by Maciej Mroz: New User Defined Structure. WIP - there are still problems with circular dependencies. Change 2011616 by Maciej Mroz: UserDefinedStructures - various problems fixed. Change 2011609 by Maciej Mroz: more robust HasExternalBlueprintDependencies implementation Change 2016697 by Maciej Mroz: pretest BP: UDStruct - default value propagation in cooked build Change 2016288 by Maciej Mroz: pretest BP: UDStruct: Renaming variables wont break links from make/break nodes Change 1987637 by Maciej Mroz: CustomStruct icons placeholders Change 1987422 by Maciej Mroz: Better tooltips for variables in MyBlueprint Change 1991387 by Maciej Mroz: UDStructures fixes: Change 2029165 by Maciej Mroz: BP: better comment for incomatible pins Change 2030016 by Maciej Mroz: 8PRETEST: EDITOR: UDS: Defaults values aren't updated in struct type variables in blueprints Change 2030017 by Maciej Mroz: Unused UDStructure code removed (PPF_UseDefaultsForUDStructures) Change 2028856 by Maciej Mroz: BP: Pins with PC_Struct type are compatible only with exactly the same structure. (No derived structures are not handled as compatible). Change 2026701 by Maciej Mroz: k2: odd error on an add item node within a function (see attached image in details) Change 2028160 by Maciej Mroz: PRETEST: EDITOR: UDS: When deleting structures just after creating there is always some references in the memory Change 2028165 by Maciej Mroz: BP: BreakHitResult function has proper icon. Change 2033340 by Maciej Mroz: ttp330786 PRETEST: EDITOR: UDS: Changes of default values aren't apllied to breeak nodes for text type of variables Change 2034255 by Maciej Mroz: EDITOR: UDS: Changes of default values aren't apllied to make nodes for text type of variables ttp#330620 Change 2037682 by Maciej Mroz: ttp331309 BLOCKER: PRETEST: CRASH: EDITOR: Crash occurs when performing Diff Against Depot on any Blueprint Change 2033142 by Maciej Mroz: CreateDelegate Node uses internally FMemberReference. Refactor. Change 2032329 by Maciej Mroz: ttp330608 CRASH: PRETEST: EDITOR: UDS: Crash when trying to use struct named 'Color' in blueprint Change 2032420 by Maciej Mroz: ttp330620 PRETEST: EDITOR: UDS: Changes of default values aren't apllied to make nodes for text type of variables Change 2033139 by Maciej Mroz: Functions generated from CustomEvents can be also identified by GUID Change 2026631 by Maciej Mroz: BP. UDStruct: Invalid structs are handled better. Change 2025344 by Maciej Mroz: UDStruct enabled by default Change 2026672 by Maciej Mroz: EDITOR: BP: Can't easily remove 'pass-by-reference' pins on ReturnNodes Change 2026411 by Maciej Mroz: ExposeOnSpawn updated, it supports UDStructs, custom native Structs, and it throws compiler error. Change 2025342 by Maciej Mroz: GenerateBlueprintSkeleton moved from BLueprint::Serialize to RegenerateBlueprintClass, because SkeletonClass compilation requires all external dependencies to be loaded and linked. Change 2025570 by Steve Robb: Moved dependency processing to its own function. Change 2033235 by Steve Robb: String improvements Change 2035830 by Steve Robb: Workaround for FriendsAndChat crash in Fortnite. Change 2035115 by Steve Robb: UBT build time regression fixes. Change 2034162 by Steve Robb: 312775: UObject improvement: Ensure that *.generated.inl is included somewhere Change 2034181 by Steve Robb: Removal of any references to .generated.inl Change 2020165 by Steve Robb: BuildPublicAndPrivateUObjectHeaders factored out into its own function. Change 2020187 by Steve Robb: CreateModuleCompileEnvironment function factored out. Change 2020055 by Steve Robb: Refactoring of Unity.cs to remove complex and duplicate iteration. Change 2020083 by Steve Robb: Another use of dictionary utilities. Change 2031049 by Steve Robb: 312775: UObject improvement: Ensure that *.generated.inl is included somewhere Change 2025728 by Steve Robb: Refactored the application of a shared PCH file to multiple file into a single ApplySharedPCH function. Change 2020068 by Steve Robb: A couple of helpful utility functions for populating dictionaries. Change 2032307 by Steve Robb: 312775: UObject improvement: Ensure that *.generated.inl is included somewhere [CL 2054495 by Robert Manuszewski in Main branch]
2014-04-23 20:18:55 -04:00
#include "EnvironmentQueryEditorPrivatePCH.h"
#include "EnvQueryTestDetails.h"
#include "EnvironmentQuery/EnvQueryTypes.h"
#include "EnvironmentQuery/EnvQueryTest.h"
#define LOCTEXT_NAMESPACE "EnvQueryTestDetails"
TSharedRef<IDetailCustomization> FEnvQueryTestDetails::MakeInstance()
{
return MakeShareable( new FEnvQueryTestDetails );
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void FEnvQueryTestDetails::CustomizeDetails( IDetailLayoutBuilder& DetailLayout )
{
AllowWriting = false;
TArray<TWeakObjectPtr<UObject> > EditedObjects;
DetailLayout.GetObjectsBeingCustomized(EditedObjects);
for (int32 i = 0; i < EditedObjects.Num(); i++)
{
const UEnvQueryTest* EditedTest = Cast<const UEnvQueryTest>(EditedObjects[i].Get());
if (EditedTest)
{
MyTest = EditedTest;
break;
}
}
// Initialize all handles
FilterTypeHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, FilterType));
ScoreEquationHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ScoringEquation));
TestPurposeHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, TestPurpose));
ScoreHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ScoringFactor));
ClampMinTypeHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ClampMinType));
ClampMaxTypeHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ClampMaxType));
ScoreClampMinHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ScoreClampMin));
FloatValueMinHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, FloatValueMin));
ScoreClampMaxHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ScoreClampMax));
FloatValueMaxHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, FloatValueMax));
// Build combo box data values
BuildFilterTestValues();
BuildScoreEquationValues();
BuildScoreClampingTypeValues(true, ClampMinTypeValues);
BuildScoreClampingTypeValues(false, ClampMaxTypeValues);
IDetailCategoryBuilder& TestCategory = DetailLayout.EditCategory("Test");
IDetailPropertyRow& TestPurposeRow = TestCategory.AddProperty(TestPurposeHandle);
IDetailCategoryBuilder& FilterCategory = DetailLayout.EditCategory("Filter");
IDetailPropertyRow& FilterTypeRow = FilterCategory.AddProperty(FilterTypeHandle);
FilterTypeRow.CustomWidget()
.NameContent()
[
FilterTypeHandle->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SComboButton)
.OnGetMenuContent(this, &FEnvQueryTestDetails::OnGetFilterTestContent)
.ContentPadding(FMargin( 2.0f, 2.0f ))
.ButtonContent()
[
SNew(STextBlock)
.Text(this, &FEnvQueryTestDetails::GetCurrentFilterTestDesc)
.Font(IDetailLayoutBuilder::GetDetailFont())
]
];
FilterTypeRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetFloatFilterVisibility)));
// filters
IDetailPropertyRow& FloatValueMinRow = FilterCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, FloatValueMin)));
FloatValueMinRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfFloatValueMin)));
IDetailPropertyRow& FloatValueMaxRow = FilterCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, FloatValueMax)));
FloatValueMaxRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfFloatValueMax)));
IDetailPropertyRow& BoolValueRow = FilterCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, BoolValue)));
BoolValueRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetBoolValueVisibility)));
// required when it's created for "scoring only" tests
IDetailGroup& HackToEnsureFilterCategoryIsVisible = FilterCategory.AddGroup("HackForVisibility", FText::GetEmpty());
HackToEnsureFilterCategoryIsVisible.HeaderRow().Visibility(EVisibility::Hidden);
// Scoring
IDetailCategoryBuilder& ScoreCategory = DetailLayout.EditCategory("Score");
//----------------------------
// BEGIN Scoring: Clamping
IDetailGroup& ClampingGroup = ScoreCategory.AddGroup("Clamping", LOCTEXT("ClampingLabel", "Clamping"));
ClampingGroup.HeaderRow()
[
SNew(STextBlock)
.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetClampingVisibility)))
.Text(FText::FromString("Clamping"))
.Font(IDetailLayoutBuilder::GetDetailFont())
];
// Drop-downs for setting type of lower and upper bound normalization
IDetailPropertyRow& ClampMinTypeRow = ClampingGroup.AddPropertyRow(ClampMinTypeHandle.ToSharedRef());
ClampMinTypeRow.CustomWidget()
.NameContent()
[
ClampMinTypeHandle->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SComboButton)
.OnGetMenuContent(this, &FEnvQueryTestDetails::OnGetClampMinTypeContent)
.ContentPadding(FMargin( 2.0f, 2.0f ))
.ButtonContent()
[
SNew(STextBlock)
.Text(this, &FEnvQueryTestDetails::GetClampMinTypeDesc)
.Font(IDetailLayoutBuilder::GetDetailFont())
]
];
ClampMinTypeRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetFloatScoreVisibility)));
// Lower Bound for normalization of score if specified independently of filtering.
IDetailPropertyRow& ScoreClampMinRow = ClampingGroup.AddPropertyRow(ScoreClampMinHandle.ToSharedRef());
ScoreClampMinRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfScoreClampMinimum)));
// Lower Bound for scoring when tied to filter minimum.
if (FloatValueMinHandle->IsValidHandle())
{
IDetailPropertyRow& FloatValueMinForClampingRow = ClampingGroup.AddPropertyRow(FloatValueMinHandle.ToSharedRef());
FloatValueMinForClampingRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfValueMinForScoreClamping)));
FloatValueMinForClampingRow.ToolTip(LOCTEXT("FloatFilterMinForClampingRowToolTip", "See Filter Thresholds under the Filter tab. Values lower than this (before clamping) cause the item to be thrown out as invalid. Values are normalized with this value as the minimum, so items with this value will have a normalized score of 0."));
FloatValueMinForClampingRow.EditCondition(TAttribute<bool>(this, &FEnvQueryTestDetails::AllowWritingToFiltersFromScore), NULL);
}
if (ClampMaxTypeHandle->IsValidHandle())
{
IDetailPropertyRow& ClampMaxTypeRow = ClampingGroup.AddPropertyRow(ClampMaxTypeHandle.ToSharedRef());
ClampMaxTypeRow.CustomWidget()
.NameContent()
[
ClampMaxTypeHandle->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SComboButton)
.OnGetMenuContent(this, &FEnvQueryTestDetails::OnGetClampMaxTypeContent)
.ContentPadding(FMargin( 2.0f, 2.0f ))
.ButtonContent()
[
SNew(STextBlock)
.Text(this, &FEnvQueryTestDetails::GetClampMaxTypeDesc)
.Font(IDetailLayoutBuilder::GetDetailFont())
]
];
ClampMaxTypeRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetFloatScoreVisibility)));
}
// Upper Bound for normalization of score if specified independently of filtering.
if (ScoreClampMaxHandle->IsValidHandle())
{
IDetailPropertyRow& ScoreClampMaxRow = ClampingGroup.AddPropertyRow(ScoreClampMaxHandle.ToSharedRef());
ScoreClampMaxRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfScoreClampMaximum)));
}
if (FloatValueMaxHandle->IsValidHandle())
{
// Upper Bound for scoring when tied to filter maximum.
IDetailPropertyRow& FloatValueMaxForClampingRow = ClampingGroup.AddPropertyRow(FloatValueMaxHandle.ToSharedRef());
FloatValueMaxForClampingRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetVisibilityOfValueMaxForScoreClamping)));
FloatValueMaxForClampingRow.ToolTip(LOCTEXT("FloatFilterMaxForClampingRowToolTip", "See Filter Thresholds under the Filter tab. Values higher than this (before normalization) cause the item to be thrown out as invalid. Values are normalized with this value as the maximum, so items with this value will have a normalized score of 1."));
FloatValueMaxForClampingRow.EditCondition(TAttribute<bool>(this, &FEnvQueryTestDetails::AllowWritingToFiltersFromScore), NULL);
}
// END Scoring: Clamping, continue Scoring
//----------------------------
IDetailPropertyRow& BoolScoreTestRow = ScoreCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, BoolValue)));
BoolScoreTestRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetBoolValueVisibilityForScoring)));
BoolScoreTestRow.DisplayName(LOCTEXT("BoolMatchLabel", "Bool Match"));
BoolScoreTestRow.ToolTip(LOCTEXT("BoolMatchToolTip", "Boolean value to match in order to grant score of 'ScoringFactor'. Not matching this value will not change score."));
// IDetailPropertyRow& ScoreMirrorNormalizedScoreRow = ScoreCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, bMirrorNormalizedScore)));
// ScoreMirrorNormalizedScoreRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetFloatScoreVisibility)));
IDetailPropertyRow& ScoreEquationTypeRow = ScoreCategory.AddProperty(ScoreEquationHandle);
ScoreEquationTypeRow.CustomWidget()
.NameContent()
.VAlign(VAlign_Top)
[
ScoreEquationHandle->CreatePropertyNameWidget()
]
.ValueContent().MaxDesiredWidth(600)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Left)
[
SNew(SComboButton)
.OnGetMenuContent(this, &FEnvQueryTestDetails::OnGetEquationValuesContent)
.ContentPadding(FMargin( 2.0f, 2.0f ))
.ButtonContent()
[
SNew(STextBlock)
.Text(this, &FEnvQueryTestDetails::GetEquationValuesDesc)
.Font(IDetailLayoutBuilder::GetDetailFont())
]
]
+SVerticalBox::Slot()
.Padding(0, 2, 0, 0)
.AutoHeight()
[
SNew(STextBlock)
.IsEnabled(false)
.Text(this, &FEnvQueryTestDetails::GetScoreEquationInfo)
.Font( IDetailLayoutBuilder::GetDetailFont() )
]
];
ScoreEquationTypeRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetFloatScoreVisibility)));
IDetailPropertyRow& ScoreFactorRow = ScoreCategory.AddProperty(DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(UEnvQueryTest, ScoringFactor)));
ScoreFactorRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FEnvQueryTestDetails::GetScoreVisibility)));
// scoring & filter function preview
IDetailCategoryBuilder& PreviewCategory = DetailLayout.EditCategory("Preview");
PreviewCategory.AddCustomRow(LOCTEXT("Preview", "Preview")).WholeRowWidget
[
SAssignNew(PreviewWidget, STestFunctionWidget)
];
PreviewWidget->DrawTestOb = Cast<UEnvQueryTest>(MyTest.Get());
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void FEnvQueryTestDetails::BuildFilterTestValues()
{
UEnum* TestConditionEnum = FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnvTestFilterType"));
check(TestConditionEnum);
FilterTestValues.Reset();
const UEnvQueryTest* EditedTest = Cast<const UEnvQueryTest>(MyTest.Get());
if (EditedTest)
{
if (EditedTest->GetWorkOnFloatValues())
{
FilterTestValues.Add(FTextIntPair(TestConditionEnum->GetEnumText(EEnvTestFilterType::Minimum), EEnvTestFilterType::Minimum));
FilterTestValues.Add(FTextIntPair(TestConditionEnum->GetEnumText(EEnvTestFilterType::Maximum), EEnvTestFilterType::Maximum));
FilterTestValues.Add(FTextIntPair(TestConditionEnum->GetEnumText(EEnvTestFilterType::Range), EEnvTestFilterType::Range));
}
else
{
FilterTestValues.Add(FTextIntPair(TestConditionEnum->GetEnumText(EEnvTestFilterType::Match), EEnvTestFilterType::Match));
}
}
}
void FEnvQueryTestDetails::BuildScoreEquationValues()
{
UEnum* TestScoreEquationEnum = FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnvTestScoreEquation"));
check(TestScoreEquationEnum);
ScoreEquationValues.Reset();
// Const scoring is always valid. But other equations are only valid if the score values can be other than boolean values.
ScoreEquationValues.Add(FTextIntPair(TestScoreEquationEnum->GetEnumText(EEnvTestScoreEquation::Constant), EEnvTestScoreEquation::Constant));
const UEnvQueryTest* EditedTest = Cast<const UEnvQueryTest>(MyTest.Get());
if (EditedTest)
{
if (EditedTest->GetWorkOnFloatValues())
{
ScoreEquationValues.Add(FTextIntPair(TestScoreEquationEnum->GetEnumText(EEnvTestScoreEquation::Linear), EEnvTestScoreEquation::Linear));
ScoreEquationValues.Add(FTextIntPair(TestScoreEquationEnum->GetEnumText(EEnvTestScoreEquation::Square), EEnvTestScoreEquation::Square));
ScoreEquationValues.Add(FTextIntPair(TestScoreEquationEnum->GetEnumText(EEnvTestScoreEquation::InverseLinear), EEnvTestScoreEquation::InverseLinear));
}
}
}
void FEnvQueryTestDetails::OnFilterTestChange(int32 Index)
{
uint8 EnumValue = Index;
FilterTypeHandle->SetValue(EnumValue);
}
void FEnvQueryTestDetails::OnScoreEquationChange(int32 Index)
{
uint8 EnumValue = Index;
ScoreEquationHandle->SetValue(EnumValue);
}
void FEnvQueryTestDetails::BuildScoreClampingTypeValues(bool bBuildMinValues, TArray<FTextIntPair>& ClampTypeValues) const
{
UEnum* ScoringNormalizationEnum = FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnvQueryTestClamping"));
check(ScoringNormalizationEnum);
ClampTypeValues.Reset();
ClampTypeValues.Add(FTextIntPair(ScoringNormalizationEnum->GetEnumText(EEnvQueryTestClamping::None), EEnvQueryTestClamping::None));
ClampTypeValues.Add(FTextIntPair(ScoringNormalizationEnum->GetEnumText(EEnvQueryTestClamping::SpecifiedValue), EEnvQueryTestClamping::SpecifiedValue));
if (IsFiltering())
{
bool bSupportFilterThreshold = false;
if (bBuildMinValues)
{
if (UsesFilterMin())
{
bSupportFilterThreshold = true;
}
}
else if (UsesFilterMax())
{
bSupportFilterThreshold = true;
}
if (bSupportFilterThreshold)
{
ClampTypeValues.Add(FTextIntPair(ScoringNormalizationEnum->GetEnumText(EEnvQueryTestClamping::FilterThreshold), EEnvQueryTestClamping::FilterThreshold));
}
}
}
void FEnvQueryTestDetails::OnClampMinTestChange(int32 Index)
{
check(ClampMinTypeHandle.IsValid());
uint8 EnumValue = Index;
ClampMinTypeHandle->SetValue(EnumValue);
}
void FEnvQueryTestDetails::OnClampMaxTestChange(int32 Index)
{
check(ClampMaxTypeHandle.IsValid());
uint8 EnumValue = Index;
ClampMaxTypeHandle->SetValue(EnumValue);
}
TSharedRef<SWidget> FEnvQueryTestDetails::OnGetClampMinTypeContent()
{
BuildScoreClampingTypeValues(true, ClampMinTypeValues);
FMenuBuilder MenuBuilder(true, NULL);
for (int32 i = 0; i < ClampMinTypeValues.Num(); i++)
{
FUIAction ItemAction(FExecuteAction::CreateSP(this, &FEnvQueryTestDetails::OnClampMinTestChange, ClampMinTypeValues[i].Int));
MenuBuilder.AddMenuEntry(ClampMinTypeValues[i].Text, TAttribute<FText>(), FSlateIcon(), ItemAction);
}
return MenuBuilder.MakeWidget();
}
TSharedRef<SWidget> FEnvQueryTestDetails::OnGetClampMaxTypeContent()
{
BuildScoreClampingTypeValues(false, ClampMaxTypeValues);
FMenuBuilder MenuBuilder(true, NULL);
for (int32 i = 0; i < ClampMaxTypeValues.Num(); i++)
{
FUIAction ItemAction(FExecuteAction::CreateSP(this, &FEnvQueryTestDetails::OnClampMaxTestChange, ClampMaxTypeValues[i].Int));
MenuBuilder.AddMenuEntry(ClampMaxTypeValues[i].Text, TAttribute<FText>(), FSlateIcon(), ItemAction);
}
return MenuBuilder.MakeWidget();
}
FText FEnvQueryTestDetails::GetClampMinTypeDesc() const
{
check(ClampMinTypeHandle.IsValid());
uint8 EnumValue;
ClampMinTypeHandle->GetValue(EnumValue);
for (int32 i = 0; i < ClampMinTypeValues.Num(); i++)
{
if (ClampMinTypeValues[i].Int == EnumValue)
{
return ClampMinTypeValues[i].Text;
}
}
return FText::GetEmpty();
}
FText FEnvQueryTestDetails::GetClampMaxTypeDesc() const
{
check(ClampMaxTypeHandle.IsValid());
uint8 EnumValue;
ClampMaxTypeHandle->GetValue(EnumValue);
for (int32 i = 0; i < ClampMaxTypeValues.Num(); i++)
{
if (ClampMaxTypeValues[i].Int == EnumValue)
{
return ClampMaxTypeValues[i].Text;
}
}
return FText::GetEmpty();
}
FText FEnvQueryTestDetails::GetEquationValuesDesc() const
{
check(ScoreEquationHandle.IsValid());
uint8 EnumValue;
ScoreEquationHandle->GetValue(EnumValue);
for (int32 i = 0; i < ScoreEquationValues.Num(); i++)
{
if (ScoreEquationValues[i].Int == EnumValue)
{
return ScoreEquationValues[i].Text;
}
}
return FText::GetEmpty();
}
TSharedRef<SWidget> FEnvQueryTestDetails::OnGetFilterTestContent()
{
BuildFilterTestValues();
FMenuBuilder MenuBuilder(true, NULL);
for (int32 i = 0; i < FilterTestValues.Num(); i++)
{
FUIAction ItemAction(FExecuteAction::CreateSP(this, &FEnvQueryTestDetails::OnFilterTestChange, FilterTestValues[i].Int));
MenuBuilder.AddMenuEntry(FilterTestValues[i].Text, TAttribute<FText>(), FSlateIcon(), ItemAction);
}
return MenuBuilder.MakeWidget();
}
FText FEnvQueryTestDetails::GetCurrentFilterTestDesc() const
{
uint8 EnumValue;
FilterTypeHandle->GetValue(EnumValue);
for (int32 i = 0; i < FilterTestValues.Num(); i++)
{
if (FilterTestValues[i].Int == EnumValue)
{
return FilterTestValues[i].Text;
}
}
return FText::GetEmpty();
}
TSharedRef<SWidget> FEnvQueryTestDetails::OnGetEquationValuesContent()
{
BuildScoreEquationValues();
FMenuBuilder MenuBuilder(true, NULL);
for (int32 i = 0; i < ScoreEquationValues.Num(); i++)
{
FUIAction ItemAction(FExecuteAction::CreateSP(this, &FEnvQueryTestDetails::OnScoreEquationChange, ScoreEquationValues[i].Int));
MenuBuilder.AddMenuEntry(ScoreEquationValues[i].Text, TAttribute<FText>(), FSlateIcon(), ItemAction);
}
return MenuBuilder.MakeWidget();
}
FText FEnvQueryTestDetails::GetScoreEquationInfo() const
{
uint8 EnumValue;
ScoreEquationHandle->GetValue(EnumValue);
switch (EnumValue)
{
case EEnvTestScoreEquation::Linear:
return LOCTEXT("Linear","Final score = ScoringFactor * NormalizedItemValue");
case EEnvTestScoreEquation::Square:
return LOCTEXT("Square","Final score = ScoringFactor * (NormalizedItemValue * NormalizedItemValue)\nBias towards items with big values.");
case EEnvTestScoreEquation::InverseLinear:
return LOCTEXT("Inverse","Final score = ScoringFactor * (1.0 - NormalizedItemValue)\nBias towards items with values close to zero. (Linear, but flipped from 1 to 0 rather than 0 to 1.");
case EEnvTestScoreEquation::Constant:
return LOCTEXT("Constant", "Final score (for values that 'pass') = ScoringFactor\nNOTE: In this case, the score is normally EITHER the ScoringFactor value or zero.\nThe score will be zero if the Normalized Test Value is zero (or if the test value is false for a boolean query).\nOtherwise, score will be the ScoringFactor.");
default:
break;
}
return FText::GetEmpty();
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfValueMinForScoreClamping() const
{
if (GetFloatScoreVisibility() == EVisibility::Visible)
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && (MyTestOb->ClampMinType == EEnvQueryTestClamping::FilterThreshold))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfValueMaxForScoreClamping() const
{
if (GetFloatScoreVisibility() == EVisibility::Visible)
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && (MyTestOb->ClampMaxType == EEnvQueryTestClamping::FilterThreshold))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfScoreClampMinimum() const
{
if (GetFloatScoreVisibility() == EVisibility::Visible)
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && (MyTestOb->ClampMinType == EEnvQueryTestClamping::SpecifiedValue))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfScoreClampMaximum() const
{
if (GetFloatScoreVisibility() == EVisibility::Visible)
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && (MyTestOb->ClampMaxType == EEnvQueryTestClamping::SpecifiedValue))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetFloatTestVisibility() const
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && MyTestOb->GetWorkOnFloatValues())
{
return EVisibility::Visible;
}
return EVisibility::Collapsed;
}
bool FEnvQueryTestDetails::IsFiltering() const
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb == NULL)
{
return false;
}
return MyTestOb->IsFiltering();
}
bool FEnvQueryTestDetails::IsScoring() const
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb == NULL)
{
return false;
}
return MyTestOb->IsScoring();
}
EVisibility FEnvQueryTestDetails::GetFloatFilterVisibility() const
{
if (IsFiltering())
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && MyTestOb->GetWorkOnFloatValues())
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetScoreVisibility() const
{
if (IsScoring())
{
return EVisibility::Visible;
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetClampingVisibility() const
{
if (IsScoring())
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && MyTestOb->GetWorkOnFloatValues())
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetFloatScoreVisibility() const
{
if (IsScoring())
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && MyTestOb->GetWorkOnFloatValues())
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
bool FEnvQueryTestDetails::UsesFilterMin() const
{
uint8 EnumValue;
check(FilterTypeHandle.IsValid());
FilterTypeHandle->GetValue(EnumValue);
return ((EnumValue == EEnvTestFilterType::Minimum) || (EnumValue == EEnvTestFilterType::Range));
}
bool FEnvQueryTestDetails::UsesFilterMax() const
{
uint8 EnumValue;
check(FilterTypeHandle.IsValid());
FilterTypeHandle->GetValue(EnumValue);
return ((EnumValue == EEnvTestFilterType::Maximum) || (EnumValue == EEnvTestFilterType::Range));
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfFloatValueMin() const
{
if (IsFiltering())
{
uint8 EnumValue;
FilterTypeHandle->GetValue(EnumValue);
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && MyTestOb->GetWorkOnFloatValues() &&
((EnumValue == EEnvTestFilterType::Minimum) || (EnumValue == EEnvTestFilterType::Range)))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetVisibilityOfFloatValueMax() const
{
if (IsFiltering())
{
uint8 EnumValue;
FilterTypeHandle->GetValue(EnumValue);
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && MyTestOb->GetWorkOnFloatValues() &&
((EnumValue == EEnvTestFilterType::Maximum) || (EnumValue == EEnvTestFilterType::Range)))
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
bool FEnvQueryTestDetails::IsMatchingBoolValue() const
{
// TODO: Decide whether this complex function needs to be so complex! At the moment, if it's not working on floats,
// it must be working on bools, in which case it MUST be using a Match test. So probably it could stop much earlier!
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if (MyTestOb && !MyTestOb->GetWorkOnFloatValues())
{
if (FilterTypeHandle.IsValid())
{
uint8 EnumValue;
FilterTypeHandle->GetValue(EnumValue);
if (EnumValue == EEnvTestFilterType::Match)
{
return true;
}
}
}
return false;
}
EVisibility FEnvQueryTestDetails::GetBoolValueVisibilityForScoring() const
{
if (!IsFiltering())
{
if (IsMatchingBoolValue())
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetBoolValueVisibility() const
{
if (IsFiltering())
{
if (IsMatchingBoolValue())
{
return EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
EVisibility FEnvQueryTestDetails::GetTestPreviewVisibility() const
{
const UEnvQueryTest* MyTestOb = Cast<const UEnvQueryTest>(MyTest.Get());
if ((MyTestOb != NULL) && MyTestOb->GetWorkOnFloatValues())
{
return EVisibility::Visible;
}
return EVisibility::Collapsed;
}
#undef LOCTEXT_NAMESPACE