StateQueryComparisonCustom.cpp
1 // Copyright (C) 2025 Radaway Software LLC. All Rights Reserved. 2 3 #include "StateQueryComparisonCustom.h" 4 #include "PropertyEditing.h" 5 #include "PropertyCustomizationHelpers.h" 6 #include "Core/RpaiTypes.h" 7 8 TSharedRef<IDetailCustomization> StateQueryComparisonCustom::MakeInstance(FName RHSFieldName) 9 { 10 return MakeShareable<IDetailCustomization>(new StateQueryComparisonCustom(RHSFieldName)); 11 } 12 13 TSharedRef<IPropertyTypeCustomization> StateQueryComparisonCustom::MakePropertyInstance(FName RHSFieldName) 14 { 15 return MakeShareable<IPropertyTypeCustomization> (new StateQueryComparisonCustom(RHSFieldName)); 16 } 17 18 StateQueryComparisonCustom::StateQueryComparisonCustom(FName RHSFieldName) 19 : RHSFieldName(RHSFieldName) 20 { 21 22 } 23 24 void StateQueryComparisonCustom::CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) 25 { 26 } 27 28 void StateQueryComparisonCustom::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) 29 { 30 TSharedPtr<IPropertyHandle> QueriedState = StructPropertyHandle->GetChildHandle(FName(TEXT("QueriedState"))); 31 TSharedPtr<IPropertyHandle> ComparisonOperation = StructPropertyHandle->GetChildHandle(FName(TEXT("ComparisonOperation"))); 32 StructBuilder.GetParentCategory().GetParentLayout().HideProperty(QueriedState); 33 StructBuilder.GetParentCategory().GetParentLayout().HideProperty(ComparisonOperation); 34 35 TSharedPtr<SHorizontalBox> Box; 36 37 StructBuilder.AddCustomRow(FText::GetEmpty()) 38 .NameContent() 39 [ 40 SNew(STextBlock) 41 .Font(IDetailLayoutBuilder::GetDetailFont()) 42 .Text(NSLOCTEXT("Rpai", "ComparisonDisplayName", "Comparison")) 43 ] 44 .ValueContent() 45 .HAlign(EHorizontalAlignment::HAlign_Fill) 46 [ 47 SAssignNew(Box, SHorizontalBox) 48 + SHorizontalBox::Slot() 49 .HAlign(EHorizontalAlignment::HAlign_Fill) 50 [ 51 StructBuilder.GenerateStructValueWidget(QueriedState.ToSharedRef()) 52 ] 53 + SHorizontalBox::Slot() 54 .HAlign(EHorizontalAlignment::HAlign_Fill) 55 [ 56 ComparisonOperation->CreatePropertyValueWidget() 57 ] 58 ]; 59 60 if (RHSFieldName.IsValid()) 61 { 62 TSharedPtr<IPropertyHandle> Rhs = StructPropertyHandle->GetChildHandle(RHSFieldName); 63 check(Rhs.IsValid()); 64 StructBuilder.GetParentCategory().GetParentLayout().HideProperty(Rhs); 65 Box->AddSlot() 66 [ 67 Rhs->CreatePropertyValueWidget() 68 ]; 69 } 70 } 71 72 void StateQueryComparisonCustom::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) 73 { 74 IDetailCategoryBuilder& RpaiCategory = DetailBuilder.EditCategory("Rpai", FText::GetEmpty(), ECategoryPriority::Important); 75 76 /** 77 IDetailLayoutBuilder::GetProperty() will only return the immediate class properties found on scope. Which means parent class properties will 78 not be found. Therefore we must search for them after getting the appropriate category's default properties. 79 **/ 80 TArray<TSharedRef<IPropertyHandle>> DefaultProperties; 81 RpaiCategory.GetDefaultProperties(DefaultProperties); 82 83 const auto FindQueriedState = [](const TSharedRef<IPropertyHandle>& Handle) -> bool { return Handle->GetProperty()->GetFName().IsEqual("QueriedState"); }; 84 const auto FindComparison = [](const TSharedRef<IPropertyHandle>& Handle) -> bool { return Handle->GetProperty()->GetFName().IsEqual("ComparisonOperation"); }; 85 86 auto QueriedStateResult = DefaultProperties.FindByPredicate(FindQueriedState); 87 auto ComparisonOperationResult = DefaultProperties.FindByPredicate(FindComparison); 88 89 check(QueriedStateResult != nullptr); 90 check(ComparisonOperationResult != nullptr); 91 92 TSharedRef<IPropertyHandle> QueriedState = *QueriedStateResult; 93 TSharedRef<IPropertyHandle> ComparisonOperation = *ComparisonOperationResult; 94 95 QueriedState->MarkHiddenByCustomization(); 96 ComparisonOperation->MarkHiddenByCustomization(); 97 98 TSharedPtr<SHorizontalBox> Box; 99 100 FDetailWidgetRow& Row = RpaiCategory.AddCustomRow(FText::GetEmpty()) 101 .NameContent() 102 [ 103 SNew(STextBlock) 104 .Font(IDetailLayoutBuilder::GetDetailFont()) 105 .Text(NSLOCTEXT("Rpai", "ComparisonDisplayName", "Query Definition")) 106 ] 107 .ValueContent() 108 .HAlign(HAlign_Fill) 109 [ 110 SAssignNew(Box, SHorizontalBox) 111 + SHorizontalBox::Slot() 112 .AutoWidth() 113 [ 114 SNew(STextBlock) 115 .Font(IDetailLayoutBuilder::GetDetailFont()) 116 .Text_Lambda([QueriedState]() -> FText 117 { 118 TSharedRef<IPropertyHandle> StateNamePropertyHandle = QueriedState->GetChildHandle(GET_MEMBER_NAME_CHECKED(FStateKeyValueReference, StateKeyName)).ToSharedRef(); 119 FText StateNameText; 120 StateNamePropertyHandle->GetValueAsDisplayText(StateNameText); 121 return StateNameText; 122 }) 123 ] 124 + SHorizontalBox::Slot() 125 .AutoWidth() 126 [ 127 SNew(STextBlock) 128 .Font(IDetailLayoutBuilder::GetDetailFont()) 129 .Margin(FMargin(8., 0., 0., 0.)) 130 .Text(NSLOCTEXT("Rpai", "AsUpper", "AS")) 131 ] 132 + SHorizontalBox::Slot() 133 .AutoWidth() 134 [ 135 SNew(STextBlock) 136 .Font(IDetailLayoutBuilder::GetDetailFont()) 137 .Margin(FMargin(8., 0., 0., 0.)) 138 .Text_Lambda([QueriedState]() -> FText 139 { 140 TSharedRef<IPropertyHandle> StateTypePropertyHandle = QueriedState->GetChildHandle(GET_MEMBER_NAME_CHECKED(FStateKeyValueReference, ExpectedValueType)).ToSharedRef(); 141 FText StateTypeText; 142 StateTypePropertyHandle->GetValueAsDisplayText(StateTypeText); 143 return StateTypeText; 144 }) 145 ] 146 + SHorizontalBox::Slot() 147 .AutoWidth() 148 [ 149 SNew(STextBlock) 150 .Font(IDetailLayoutBuilder::GetDetailFont()) 151 .Margin(FMargin(8., 0., 0., 0.)) 152 .Text_Lambda([ComparisonOperation]() -> FText 153 { 154 FText OperationText; 155 ComparisonOperation->GetValueAsDisplayText(OperationText); 156 return OperationText; 157 }) 158 ] 159 ]; 160 161 RpaiCategory.AddProperty(QueriedState.ToSharedPtr()); 162 RpaiCategory.AddProperty(ComparisonOperation.ToSharedPtr()); 163 164 if (RHSFieldName.IsValid()) 165 { 166 TSharedPtr<IPropertyHandle> Rhs = DetailBuilder.GetProperty(RHSFieldName); 167 check(Rhs.IsValid()); 168 Rhs->MarkHiddenByCustomization(); 169 170 Box->AddSlot() 171 .AutoWidth() 172 [ 173 SNew(STextBlock) 174 .Font(IDetailLayoutBuilder::GetDetailFont()) 175 .Margin(FMargin(8., 0., 0., 0.)) 176 .Text_Lambda([Value = Rhs.ToSharedRef()]() -> FText 177 { 178 FText FieldNameText; 179 Value->GetValueAsDisplayText(FieldNameText); 180 return FieldNameText; 181 }) 182 ]; 183 184 RpaiCategory.AddProperty(Rhs); 185 } 186 }