/ Source / ReasonablePlanningAIEditor / Private / StateQueryComparisonCustom.cpp
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  }