// Copyright Epic Games, Inc. All Rights Reserved. #include "MuCOE/CustomizableObjectNodeObjectGroupDetails.h" #include "DetailLayoutBuilder.h" #include "IDetailsView.h" #include "Misc/Attribute.h" #include "MuCOE/CustomizableObjectEditor.h" #include "MuCOE/CustomizableObjectGraph.h" #include "MuCOE/CustomizableObjectMacroLibrary/CustomizableObjectMacroLibrary.h" #include "MuCOE/GraphTraversal.h" #include "MuCOE/Nodes/CustomizableObjectNodeObject.h" #include "MuCOE/Nodes/CustomizableObjectNodeObjectGroup.h" #include "PropertyCustomizationHelpers.h" #include "Widgets/Input/STextComboBox.h" #define LOCTEXT_NAMESPACE "CustomizableObjectGroupDetails" TSharedRef FCustomizableObjectNodeObjectGroupDetails::MakeInstance() { return MakeShareable(new FCustomizableObjectNodeObjectGroupDetails); } void FCustomizableObjectNodeObjectGroupDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) { FCustomizableObjectNodeDetails::CustomizeDetails(DetailBuilder); TSharedPtr DetailsView = DetailBuilder.GetDetailsViewSharedPtr(); if (DetailsView && DetailsView->GetSelectedObjects().Num()) { if (DetailsView->GetSelectedObjects()[0].Get()->IsA(UCustomizableObjectNodeObjectGroup::StaticClass())) { NodeGroup = Cast(DetailsView->GetSelectedObjects()[0].Get()); } } if (NodeGroup) { DetailBuilder.HideProperty("DefaultValue"); IDetailCategoryBuilder& GroupInfoCategory = DetailBuilder.EditCategory("GroupInfo"); // Forcing property order { DetailBuilder.HideProperty("GroupName"); GroupInfoCategory.AddProperty("GroupType"); } // Getting group node children names GenerateChildrenObjectNames(); GroupInfoCategory.AddCustomRow(LOCTEXT("NodeObjectGroupDetails_ComboBox", "Default Value Selector")) .Visibility(TAttribute(this, &FCustomizableObjectNodeObjectGroupDetails::DefaultValueSelectorVisibility)) .NameContent() [ SNew(STextBlock) .Text(LOCTEXT("NodeObjectGroupDetails_ComboBox_Text", "Default Value")) .ToolTipText(LOCTEXT("NodeObjectGroupDetails_ComboBox_Tooltip", "Select the default value of the group.")) .Font(DetailBuilder.GetDetailFont()) ] .ValueContent() .HAlign(EHorizontalAlignment::HAlign_Left) [ SAssignNew(DefaultValueSelector, STextComboBox) .InitiallySelectedItem(InitialNameOption) .OptionsSource(&ChildrenNameOptions) .OnComboBoxOpening(this, &FCustomizableObjectNodeObjectGroupDetails::GenerateChildrenObjectNames) .OnSelectionChanged(this, &FCustomizableObjectNodeObjectGroupDetails::OnSetDefaultValue) .Font(DetailBuilder.GetDetailFont()) .ToolTipText(this, &FCustomizableObjectNodeObjectGroupDetails::DefaultValueComboBoxTooltip) ]; if (TSharedPtr GraphEditor = StaticCastSharedPtr(NodeGroup->GetGraphEditor())) { if (UCustomizableObject* NodeGroupCO = CastChecked(NodeGroup->GetCustomizableObjectGraph()->GetOuter())) { IDetailCategoryBuilder& BlocksCategory = DetailBuilder.EditCategory("External Objects"); TMultiMap ObjectNodesObjects = GetNodeGroupObjectNodeMapping(NodeGroupCO); TArray ChildNodes; ObjectNodesObjects.MultiFind(NodeGroup->NodeGuid, ChildNodes); for (const UCustomizableObjectNodeObject* ChildObjectNode : ChildNodes) { if (ChildObjectNode) { BlocksCategory.AddCustomRow(LOCTEXT("FCustomizableObjectNodeObjectGroupDetails", "External Customizable Objects in this Group")) [ SNew(SObjectPropertyEntryBox) .ObjectPath(ChildObjectNode->GetOutermostObject()->GetPathName()) .AllowedClass(UCustomizableObject::StaticClass()) .AllowClear(false) .DisplayUseSelected(false) .DisplayBrowse(true) .EnableContentPicker(false) .DisplayThumbnail(true) ]; } } } } } } void FCustomizableObjectNodeObjectGroupDetails::GenerateChildrenObjectNames() { ChildrenNameOptions.Reset(); InitialNameOption = nullptr; // if needed add a None option and set it as the default value if (NodeGroup->GroupType == ECustomizableObjectGroupType::COGT_ONE_OR_NONE) { ChildrenNameOptions.Add(MakeShareable(new FString("None"))); InitialNameOption = ChildrenNameOptions.Last(); } else { ChildrenNameOptions.Add(MakeShareable(new FString("- Not Selected -"))); InitialNameOption = ChildrenNameOptions.Last(); } // Adding linked children names const TArray ConnectedChildrenPins = FollowInputPinArray(*NodeGroup->ObjectsPin()); for (const UEdGraphPin* ChildPin : ConnectedChildrenPins) { if (ChildPin) { if (const UCustomizableObjectNodeObject* ChildObjectNode = Cast(ChildPin->GetOwningNode())) { ChildrenNameOptions.Add(MakeShareable(new FString(ChildObjectNode->GetObjectName()))); if (ChildObjectNode->GetObjectName().Equals(NodeGroup->DefaultValue)) { InitialNameOption = ChildrenNameOptions.Last(); } } else if (const UCustomizableObjectNodeObjectGroup* ChildGroupObjectNode = Cast(ChildPin->GetOwningNode())) { ChildrenNameOptions.Add(MakeShareable(new FString(ChildGroupObjectNode->GetGroupName()))); if (ChildGroupObjectNode->GetGroupName().Equals(NodeGroup->DefaultValue)) { InitialNameOption = ChildrenNameOptions.Last(); } } } } // Adding external children names if (TSharedPtr GraphEditor = StaticCastSharedPtr(NodeGroup->GetGraphEditor())) { if (UCustomizableObject* NodeGroupCO = CastChecked(NodeGroup->GetCustomizableObjectGraph()->GetOuter())) { TMultiMap ObjectNodesObjects = GetNodeGroupObjectNodeMapping(NodeGroupCO); TArray ChildNodes; ObjectNodesObjects.MultiFind(NodeGroup->NodeGuid, ChildNodes); for (const UCustomizableObjectNodeObject* ChildObjectNode : ChildNodes) { if (ChildObjectNode) { ChildrenNameOptions.Add(MakeShareable(new FString(ChildObjectNode->GetObjectName()))); if (ChildObjectNode->GetObjectName().Equals(NodeGroup->DefaultValue)) { InitialNameOption = ChildrenNameOptions.Last(); } } } } } if (DefaultValueSelector.IsValid()) { DefaultValueSelector->RefreshOptions(); DefaultValueSelector->SetSelectedItem(InitialNameOption); } } void FCustomizableObjectNodeObjectGroupDetails::OnSetDefaultValue(TSharedPtr NewSelection, ESelectInfo::Type SelectInfo) { if (NewSelection.IsValid() && (SelectInfo == ESelectInfo::OnMouseClick || SelectInfo == ESelectInfo::OnKeyPress)) { NodeGroup->DefaultValue = *NewSelection; } } EVisibility FCustomizableObjectNodeObjectGroupDetails::DefaultValueSelectorVisibility() const { if (NodeGroup->GroupType == ECustomizableObjectGroupType::COGT_ONE || NodeGroup->GroupType == ECustomizableObjectGroupType::COGT_ONE_OR_NONE) { return EVisibility::Visible; } return EVisibility::Hidden; } FText FCustomizableObjectNodeObjectGroupDetails::DefaultValueComboBoxTooltip() const { if (DefaultValueSelector.IsValid()) { if (ChildrenNameOptions.Num() && DefaultValueSelector->GetSelectedItem() == ChildrenNameOptions[0] && NodeGroup->GroupType == ECustomizableObjectGroupType::COGT_ONE) { return FText::FromString("When nothing selected, the first compiled option will be used as the default value."); } else if (DefaultValueSelector->GetSelectedItem().IsValid()) { return FText::FromString(*DefaultValueSelector->GetSelectedItem()); } } return FText(); } #undef LOCTEXT_NAMESPACE