void UDeveloperSettings::ImportConsoleVariableValues() { for (UProperty* Property = GetClass()->PropertyLink; Property; Property = Property->PropertyLinkNext) { if (!Property->HasAnyPropertyFlags(CPF_Config)) { continue; } FString CVarName = Property->GetMetaData(DeveloperSettingsConsoleVariableMetaFName); if (!CVarName.IsEmpty()) { IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(*CVarName); if (CVar) { if (Property->ImportText(*CVar->GetString(), Property->ContainerPtrToValuePtr<uint8>(this, 0), PPF_ConsoleVariable, this) == NULL) { UE_LOG(LogTemp, Error, TEXT("%s import failed for %s on console variable %s (=%s)"), *GetClass()->GetName(), *Property->GetName(), *CVarName, *CVar->GetString()); } } else { UE_LOG(LogTemp, Fatal, TEXT("%s failed to find console variable %s for %s"), *GetClass()->GetName(), *CVarName, *Property->GetName()); } } } }
static UProperty *get_field_from_name(UScriptStruct *u_struct, char *name) { FString attr = UTF8_TO_TCHAR(name); UProperty *u_property = u_struct->FindPropertyByName(FName(*attr)); if (u_property) return u_property; #if WITH_EDITOR static const FName DisplayNameKey(TEXT("DisplayName")); // if the property is not found, attempt to search for DisplayName for (TFieldIterator<UProperty> prop(u_struct); prop; ++prop) { UProperty *property = *prop; if (property->HasMetaData(DisplayNameKey)) { FString display_name = property->GetMetaData(DisplayNameKey); if (display_name.Len() > 0 && attr.Equals(display_name)) { return property; } } } #endif return nullptr; }
void SPropertyEditorAsset::Construct( const FArguments& InArgs, const TSharedPtr<FPropertyEditor>& InPropertyEditor ) { PropertyEditor = InPropertyEditor; PropertyHandle = InArgs._PropertyHandle; OnSetObject = InArgs._OnSetObject; OnShouldFilterAsset = InArgs._OnShouldFilterAsset; UProperty* Property = nullptr; if(PropertyEditor.IsValid()) { Property = PropertyEditor->GetPropertyNode()->GetProperty(); UObjectPropertyBase* ObjectProperty = Cast<UObjectPropertyBase>(Property); check(ObjectProperty); bAllowClear = !(Property->PropertyFlags & CPF_NoClear); ObjectClass = ObjectProperty->PropertyClass; bIsActor = ObjectProperty->PropertyClass->IsChildOf( AActor::StaticClass() ); } else { bAllowClear = InArgs._AllowClear; ObjectPath = InArgs._ObjectPath; ObjectClass = InArgs._Class; bIsActor = ObjectClass->IsChildOf( AActor::StaticClass() ); if (PropertyHandle.IsValid() && PropertyHandle->IsValidHandle()) { Property = PropertyHandle->GetProperty(); } else { CustomClassFilters.Add(ObjectClass); } } // Account for the allowed classes specified in the property metadata if (Property) { FString ClassFilterString; if (UArrayProperty* ArrayParent = Cast<UArrayProperty>(Property->GetOuter())) { ClassFilterString = ArrayParent->GetMetaData("AllowedClasses"); } else { ClassFilterString = Property->GetMetaData("AllowedClasses"); } if (ClassFilterString.IsEmpty()) { CustomClassFilters.Add(ObjectClass); } else { TArray<FString> CustomClassFilterNames; ClassFilterString.ParseIntoArray(CustomClassFilterNames, TEXT(","), true); for (auto It = CustomClassFilterNames.CreateConstIterator(); It; ++It) { const FString& ClassName = *It; UClass* Class = FindObject<UClass>(ANY_PACKAGE, *ClassName); if (!Class) { Class = LoadObject<UClass>(nullptr, *ClassName); } if (Class) { // If the class is an interface, expand it to be all classes in memory that implement the class. if (Class->HasAnyClassFlags(CLASS_Interface)) { for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { UClass* const ClassWithInterface = (*ClassIt); if (ClassWithInterface->ImplementsInterface(Class)) { CustomClassFilters.Add(ClassWithInterface); } } } else { CustomClassFilters.Add(Class); } } } } } if (InArgs._NewAssetFactories.IsSet()) { NewAssetFactories = InArgs._NewAssetFactories.GetValue(); } else if (CustomClassFilters.Num() > 1 || !CustomClassFilters.Contains(UObject::StaticClass())) { NewAssetFactories = PropertyCustomizationHelpers::GetNewAssetFactoriesForClasses(CustomClassFilters); } TSharedPtr<SHorizontalBox> ValueContentBox = NULL; ChildSlot [ SNew( SAssetDropTarget ) .OnIsAssetAcceptableForDrop( this, &SPropertyEditorAsset::OnAssetDraggedOver ) .OnAssetDropped( this, &SPropertyEditorAsset::OnAssetDropped ) [ SAssignNew( ValueContentBox, SHorizontalBox ) ] ]; TAttribute<bool> IsEnabledAttribute(this, &SPropertyEditorAsset::CanEdit); TAttribute<FText> TooltipAttribute(this, &SPropertyEditorAsset::OnGetToolTip); if (Property && Property->HasAllPropertyFlags(CPF_DisableEditOnTemplate)) { // There are some cases where editing an Actor Property is not allowed, such as when it is contained within a struct or a CDO TArray<UObject*> ObjectList; PropertyEditor->GetPropertyHandle()->GetOuterObjects(ObjectList); // If there is no objects, that means we must have a struct asset managing this property if (ObjectList.Num() == 0) { IsEnabledAttribute.Set(false); TooltipAttribute.Set(LOCTEXT("VariableHasDisableEditOnTemplate", "Editing this value in structure's defaults is not allowed")); } else { // Go through all the found objects and see if any are a CDO, we can't set an actor in a CDO default. for (UObject* Obj : ObjectList) { if (Obj->HasAllFlags(RF_ClassDefaultObject)) { IsEnabledAttribute.Set(false); TooltipAttribute.Set(LOCTEXT("VariableHasDisableEditOnTemplateTooltip", "Editing this value in a Class Default Object is not allowed")); break; } } } } AssetComboButton = SNew(SComboButton) .ToolTipText(TooltipAttribute) .ButtonStyle( FEditorStyle::Get(), "PropertyEditor.AssetComboStyle" ) .ForegroundColor(FEditorStyle::GetColor("PropertyEditor.AssetName.ColorAndOpacity")) .OnGetMenuContent( this, &SPropertyEditorAsset::OnGetMenuContent ) .OnMenuOpenChanged( this, &SPropertyEditorAsset::OnMenuOpenChanged ) .IsEnabled( IsEnabledAttribute ) .ContentPadding(2.0f) .ButtonContent() [ // Show the name of the asset or actor SNew(STextBlock) .TextStyle( FEditorStyle::Get(), "PropertyEditor.AssetClass" ) .Font( FEditorStyle::GetFontStyle( PropertyEditorConstants::PropertyFontStyle ) ) .Text(this,&SPropertyEditorAsset::OnGetAssetName) ]; TSharedRef<SHorizontalBox> ButtonBox = SNew( SHorizontalBox ); TSharedPtr<SVerticalBox> CustomContentBox; if( ShouldDisplayThumbnail(InArgs) ) { FObjectOrAssetData Value; GetValue( Value ); AssetThumbnail = MakeShareable( new FAssetThumbnail( Value.AssetData, InArgs._ThumbnailSize.X, InArgs._ThumbnailSize.Y, InArgs._ThumbnailPool ) ); ValueContentBox->AddSlot() .Padding( 0.0f, 0.0f, 2.0f, 0.0f ) .AutoWidth() [ SAssignNew( ThumbnailBorder, SBorder ) .Padding( 5.0f ) .BorderImage( this, &SPropertyEditorAsset::GetThumbnailBorder ) .OnMouseDoubleClick( this, &SPropertyEditorAsset::OnAssetThumbnailDoubleClick ) [ SNew( SBox ) .ToolTipText(TooltipAttribute) .WidthOverride( InArgs._ThumbnailSize.X ) .HeightOverride( InArgs._ThumbnailSize.Y ) [ AssetThumbnail->MakeThumbnailWidget() ] ] ]; ValueContentBox->AddSlot() [ SNew( SBox ) .VAlign( VAlign_Center ) [ SAssignNew( CustomContentBox, SVerticalBox ) + SVerticalBox::Slot() [ AssetComboButton.ToSharedRef() ] + SVerticalBox::Slot() .AutoHeight() .Padding( 0.0f, 2.0f, 4.0f, 2.0f ) [ ButtonBox ] ] ]; } else { ValueContentBox->AddSlot() [ SAssignNew( CustomContentBox, SVerticalBox ) +SVerticalBox::Slot() .VAlign( VAlign_Center ) [ SNew( SHorizontalBox ) + SHorizontalBox::Slot() [ AssetComboButton.ToSharedRef() ] + SHorizontalBox::Slot() .AutoWidth() .Padding( 4.f, 0.f ) [ ButtonBox ] ] ]; } if( InArgs._CustomContentSlot.Widget != SNullWidget::NullWidget ) { CustomContentBox->AddSlot() .VAlign( VAlign_Center ) .Padding( FMargin( 0.0f, 2.0f ) ) [ InArgs._CustomContentSlot.Widget ]; } if( !bIsActor && InArgs._DisplayUseSelected ) { ButtonBox->AddSlot() .VAlign(VAlign_Center) .AutoWidth() .Padding( 2.0f, 0.0f ) [ PropertyCustomizationHelpers::MakeUseSelectedButton( FSimpleDelegate::CreateSP( this, &SPropertyEditorAsset::OnUse ), FText(), IsEnabledAttribute ) ]; } if( InArgs._DisplayBrowse ) { ButtonBox->AddSlot() .Padding( 2.0f, 0.0f ) .AutoWidth() .VAlign(VAlign_Center) [ PropertyCustomizationHelpers::MakeBrowseButton( FSimpleDelegate::CreateSP( this, &SPropertyEditorAsset::OnBrowse ), TAttribute<FText>( this, &SPropertyEditorAsset::GetOnBrowseToolTip ) ) ]; } if( bIsActor ) { TSharedRef<SWidget> ActorPicker = PropertyCustomizationHelpers::MakeInteractiveActorPicker( FOnGetAllowedClasses::CreateSP(this, &SPropertyEditorAsset::OnGetAllowedClasses), FOnShouldFilterActor(), FOnActorSelected::CreateSP( this, &SPropertyEditorAsset::OnActorSelected ) ); ActorPicker->SetEnabled( IsEnabledAttribute ); ButtonBox->AddSlot() .Padding( 2.0f, 0.0f ) .AutoWidth() .VAlign(VAlign_Center) [ ActorPicker ]; } if( InArgs._ResetToDefaultSlot.Widget != SNullWidget::NullWidget ) { TSharedRef<SWidget> ResetToDefaultWidget = InArgs._ResetToDefaultSlot.Widget; ResetToDefaultWidget->SetEnabled( IsEnabledAttribute ); ButtonBox->AddSlot() .Padding( 4.0f, 0.0f ) .AutoWidth() .VAlign(VAlign_Center) [ ResetToDefaultWidget ]; } }
void FPropertyEditor::MakeNewBlueprint() { UProperty* NodeProperty = PropertyNode->GetProperty(); UClassProperty* ClassProp = Cast<UClassProperty>(NodeProperty); UClass* Class = (ClassProp ? ClassProp->MetaClass : FEditorClassUtils::GetClassFromString(NodeProperty->GetMetaData("MetaClass"))); if (Class) { UBlueprint* Blueprint = FKismetEditorUtilities::CreateBlueprintFromClass(LOCTEXT("CreateNewBlueprint", "Create New Blueprint"), Class, FString::Printf(TEXT("New%s"),*Class->GetName())); if(Blueprint != NULL && Blueprint->GeneratedClass) { PropertyHandle->SetValueFromFormattedString(Blueprint->GeneratedClass->GetPathName()); FAssetEditorManager::Get().OpenEditorForAsset(Blueprint); } } }
void FPaperTileMapDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailLayout) { const TArray< TWeakObjectPtr<UObject> >& SelectedObjects = DetailLayout.GetDetailsView().GetSelectedObjects(); MyDetailLayout = &DetailLayout; FNotifyHook* NotifyHook = DetailLayout.GetPropertyUtilities()->GetNotifyHook(); bool bEditingActor = false; UPaperTileMap* TileMap = nullptr; UPaperTileMapComponent* TileComponent = nullptr; for (int32 ObjectIndex = 0; ObjectIndex < SelectedObjects.Num(); ++ObjectIndex) { UObject* TestObject = SelectedObjects[ObjectIndex].Get(); if (AActor* CurrentActor = Cast<AActor>(TestObject)) { if (UPaperTileMapComponent* CurrentComponent = CurrentActor->FindComponentByClass<UPaperTileMapComponent>()) { bEditingActor = true; TileComponent = CurrentComponent; TileMap = CurrentComponent->TileMap; break; } } else if (UPaperTileMapComponent* TestComponent = Cast<UPaperTileMapComponent>(TestObject)) { TileComponent = TestComponent; TileMap = TestComponent->TileMap; break; } else if (UPaperTileMap* TestTileMap = Cast<UPaperTileMap>(TestObject)) { TileMap = TestTileMap; break; } } TileMapPtr = TileMap; TileMapComponentPtr = TileComponent; IDetailCategoryBuilder& TileMapCategory = DetailLayout.EditCategory("Tile Map"); TAttribute<EVisibility> InternalInstanceVis = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FPaperTileMapDetailsCustomization::GetVisibilityForInstancedOnlyProperties)); if (TileComponent != nullptr) { TileMapCategory .AddCustomRow(LOCTEXT( "TileMapInstancingControlsSearchText", "Edit New Promote Asset")) [ SNew(SVerticalBox) + SVerticalBox::Slot() .Padding(0.0f, 2.0f, 0.0f, 0.0f) .FillHeight(1.0f) .VAlign(VAlign_Center) [ SNew(SHorizontalBox) // Edit button +SHorizontalBox::Slot() .AutoWidth() .Padding( 2.0f, 0.0f ) .VAlign(VAlign_Center) .HAlign(HAlign_Left) [ SNew(SButton) .VAlign(VAlign_Center) .OnClicked(this, &FPaperTileMapDetailsCustomization::EnterTileMapEditingMode) .Visibility(this, &FPaperTileMapDetailsCustomization::GetNonEditModeVisibility) .Text( LOCTEXT("EditAsset", "Edit") ) .ToolTipText( LOCTEXT("EditAssetToolTip", "Edit this tile map") ) ] // Create new tile map button +SHorizontalBox::Slot() .AutoWidth() .Padding( 2.0f, 0.0f ) .VAlign(VAlign_Center) .HAlign(HAlign_Left) [ SNew(SButton) .VAlign(VAlign_Center) .OnClicked(this, &FPaperTileMapDetailsCustomization::OnNewButtonClicked) .Visibility(this, &FPaperTileMapDetailsCustomization::GetNewButtonVisiblity) .Text(LOCTEXT("CreateNewInstancedMap", "New")) .ToolTipText( LOCTEXT("CreateNewInstancedMapToolTip", "Create a new tile map") ) ] // Promote to asset button +SHorizontalBox::Slot() .AutoWidth() .Padding( 2.0f, 0.0f ) .VAlign(VAlign_Center) .HAlign(HAlign_Left) [ SNew(SButton) .VAlign(VAlign_Center) .OnClicked(this, &FPaperTileMapDetailsCustomization::OnPromoteButtonClicked) .Visibility(this, &FPaperTileMapDetailsCustomization::GetVisibilityForInstancedOnlyProperties) .Text(LOCTEXT("PromoteToAsset", "Promote to asset")) .ToolTipText(LOCTEXT("PromoteToAssetToolTip", "Save this tile map as a reusable asset")) ] ] ]; TileMapCategory.AddProperty(GET_MEMBER_NAME_CHECKED(UPaperTileMapComponent, TileMap)); } // Add the layer browser if (TileMap != nullptr) { TAttribute<EVisibility> LayerBrowserVis; LayerBrowserVis.Set(EVisibility::Visible); if (TileComponent != nullptr) { LayerBrowserVis = InternalInstanceVis; } FText TileLayerListText = LOCTEXT("TileLayerList", "Tile layer list"); TileMapCategory.AddCustomRow(TileLayerListText) .Visibility(LayerBrowserVis) [ SNew(SVerticalBox) +SVerticalBox::Slot() .AutoHeight() [ SNew(STextBlock) .Font(DetailLayout.GetDetailFont()) .Text(TileLayerListText) ] +SVerticalBox::Slot() [ SNew(STileLayerList, TileMap, NotifyHook) ] ]; } // Add all of the properties from the inline tilemap if ((TileComponent != nullptr) && (TileComponent->OwnsTileMap())) { TArray<UObject*> ListOfTileMaps; ListOfTileMaps.Add(TileMap); for (TFieldIterator<UProperty> PropIt(UPaperTileMap::StaticClass()); PropIt; ++PropIt) { UProperty* TestProperty = *PropIt; if (TestProperty->HasAnyPropertyFlags(CPF_Edit)) { FName CategoryName(*TestProperty->GetMetaData(TEXT("Category"))); IDetailCategoryBuilder& Category = DetailLayout.EditCategory(CategoryName); if (IDetailPropertyRow* ExternalRow = Category.AddExternalProperty(ListOfTileMaps, TestProperty->GetFName())) { ExternalRow->Visibility(InternalInstanceVis); } } } } // Make sure the setup category is near the top DetailLayout.EditCategory("Setup"); }
void SGAAttributeWidget::Construct(const FArguments& InArgs) { AttributesList.Empty(); AttributesNodes.Empty(); OnAttributeSelected = InArgs._OnAttributeSelectedIn; /* Intended look: ClassName --CategoryName ----AttributeName Or: ClassName --CategoryName ----AttributeType ------AttributeName + search. We really need search! */ for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { UClass* Class = *ClassIt; if (Class->IsChildOf(UGAAttributesBase::StaticClass()) && !FKismetEditorUtilities::IsClassABlueprintSkeleton(Class)) { FString className = Class->GetName(); if (!className.Contains(TEXT("REINST_"))) { TSharedPtr<FGAAttributeNode> classRootNode = MakeShareable(new FGAAttributeNode()); classRootNode->Attribute = className; //first let's find root of tree, which is class name classRootNode->NodeName = className; FString Category; //now let's categories as childs for (TFieldIterator<UProperty> PropertyIt(Class, EFieldIteratorFlags::ExcludeSuper); PropertyIt; ++PropertyIt) { UProperty* Prop = *PropertyIt; Category = Prop->GetMetaData("Category"); //check if we already have this category added.. bool bFoundExistingCategory = false; if (!Category.IsEmpty()) { for (TSharedPtr<FGAAttributeNode> childNode : classRootNode->ChildNodes) { if (childNode->NodeName == Category) { bFoundExistingCategory = true; TSharedPtr<FGAAttributeNode> attrNode = MakeShareable(new FGAAttributeNode()); attrNode->NodeName = Prop->GetName(); attrNode->ParentNode = childNode; childNode->ChildNodes.Add(attrNode); } } if (!bFoundExistingCategory) { TSharedPtr<FGAAttributeNode> categoryNode = MakeShareable(new FGAAttributeNode()); categoryNode->NodeName = Category; categoryNode->ParentNode = classRootNode; classRootNode->ChildNodes.Add(categoryNode); TSharedPtr<FGAAttributeNode> attrNode = MakeShareable(new FGAAttributeNode()); attrNode->NodeName = Prop->GetName(); attrNode->ParentNode = categoryNode; categoryNode->ChildNodes.Add(attrNode); } } } AttributesNodes.Add(classRootNode); } } } ChildSlot [ SAssignNew(AttributeTreeWidget, STreeView<TSharedPtr<FGAAttributeNode>>) .OnSelectionChanged(this, &SGAAttributeWidget::OnItemSelected) .TreeItemsSource(&AttributesNodes) .OnGenerateRow(this, &SGAAttributeWidget::OnGenerateRow) .OnGetChildren(this, &SGAAttributeWidget::OnGetChildren) .OnExpansionChanged(this, &SGAAttributeWidget::OnExpansionChanged) .SelectionMode(ESelectionMode::Single) ]; }