void UK2Node_SpawnActorFromClass::CreatePinsForClass(UClass* InClass, TArray<UEdGraphPin*>& OutClassPins)
{
	check(InClass != NULL);

	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

	const UObject* const ClassDefaultObject = InClass->GetDefaultObject(false);

	for (TFieldIterator<UProperty> PropertyIt(InClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		UClass* PropertyClass = CastChecked<UClass>(Property->GetOuter());
		const bool bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass());
		const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property);
		const bool bIsSettableExternally = !Property->HasAnyPropertyFlags(CPF_DisableEditOnInstance);

		if(	bIsExposedToSpawn &&
			!Property->HasAnyPropertyFlags(CPF_Parm) && 
			bIsSettableExternally &&
			Property->HasAllPropertyFlags(CPF_BlueprintVisible) &&
			!bIsDelegate &&
			(NULL == FindPin(Property->GetName()) ) )
		{
			UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName());
			const bool bPinGood = (Pin != NULL) && K2Schema->ConvertPropertyToPinType(Property, /*out*/ Pin->PinType);
			OutClassPins.Add(Pin);

			if (ClassDefaultObject && Pin != NULL && K2Schema->PinDefaultValueIsEditable(*Pin))
			{
				FString DefaultValueAsString;
				const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString);
				check( bDefaultValueSet );
				K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString);
			}

			// Copy tooltip from the property.
			if (Pin != nullptr)
			{
				K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip);
			}
		}
	}

	// Change class of output pin
	UEdGraphPin* ResultPin = GetResultPin();
	ResultPin->PinType.PinSubCategoryObject = InClass;
}
void AActor::ResetPropertiesForConstruction()
{
	// Get class CDO
	AActor* Default = GetClass()->GetDefaultObject<AActor>();
	// RandomStream struct name to compare against
	const FName RandomStreamName(TEXT("RandomStream"));

	// We don't want to reset references to world object
	const bool bIsLevelScriptActor = IsA(ALevelScriptActor::StaticClass());

	// Iterate over properties
	for( TFieldIterator<UProperty> It(GetClass()) ; It ; ++It )
	{
		UProperty* Prop = *It;
		UStructProperty* StructProp = Cast<UStructProperty>(Prop);
		UClass* PropClass = CastChecked<UClass>(Prop->GetOuter()); // get the class that added this property

		// First see if it is a random stream, if so reset before running construction script
		if( (StructProp != NULL) && (StructProp->Struct != NULL) && (StructProp->Struct->GetFName() == RandomStreamName) )
		{
			FRandomStream* StreamPtr =  StructProp->ContainerPtrToValuePtr<FRandomStream>(this);
			StreamPtr->Reset();
		}
		// If it is a blueprint added variable that is not editable per-instance, reset to default before running construction script
		else if( !bIsLevelScriptActor 
				&& Prop->HasAnyPropertyFlags(CPF_DisableEditOnInstance)
				&& PropClass->HasAnyClassFlags(CLASS_CompiledFromBlueprint) 
				&& !Prop->IsA(UDelegateProperty::StaticClass()) 
				&& !Prop->IsA(UMulticastDelegateProperty::StaticClass()) )
		{
			Prop->CopyCompleteValue_InContainer(this, Default);
		}
	}
}
bool FScriptCodeGeneratorBase::CanExportFunction(const FString& ClassNameCPP, UClass* Class, UFunction* Function)
{
	// We don't support delegates and non-public functions
	if ((Function->FunctionFlags & FUNC_Delegate))
	{
		return false;
	}

	// Reject if any of the parameter types is unsupported yet
	for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt)
	{
		UProperty* Param = *ParamIt;
		if (Param->IsA(UArrayProperty::StaticClass()) ||
			  Param->ArrayDim > 1 ||
			  Param->IsA(UDelegateProperty::StaticClass()) ||
				Param->IsA(UMulticastDelegateProperty::StaticClass()) ||
			  Param->IsA(UWeakObjectProperty::StaticClass()) ||
			  Param->IsA(UInterfaceProperty::StaticClass()))
		{
			return false;
		}
	}

	return true;
}
	FString CollectPropertyDescription(const UObject* Ob, const UClass* StopAtClass, const TArray<UProperty*>& PropertyData)
	{
		FString RetString;
		for (UProperty* TestProperty = Ob->GetClass()->PropertyLink; TestProperty; TestProperty = TestProperty->PropertyLinkNext)
		{
			// stop when reaching base class
			if (TestProperty->GetOuter() == StopAtClass)
			{
				break;
			}

			// skip properties without any setup data	
			if (TestProperty->HasAnyPropertyFlags(CPF_Transient) ||
				TestProperty->HasAnyPropertyFlags(CPF_DisableEditOnInstance) ||
				PropertyData.Contains(TestProperty))
			{
				continue;
			}

			if (TestProperty->IsA(UClassProperty::StaticClass()) ||
				TestProperty->IsA(UStructProperty::StaticClass()) ||
				CanUsePropertyType(TestProperty))
			{
				if (RetString.Len())
				{
					RetString.AppendChar(TEXT('\n'));
				}

				const uint8* PropData = TestProperty->ContainerPtrToValuePtr<uint8>(Ob);
				RetString += DescribeProperty(TestProperty, PropData);
			}
		}

		return RetString;
	}
void UBehaviorTreeGraphNode::DiffProperties(UStruct* Struct, void* DataA, void* DataB, FDiffResults& Results, FDiffSingleResult& Diff)
{
    for (TFieldIterator<UProperty> PropertyIt(Struct, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
    {
        UProperty* Prop = *PropertyIt;
        // skip properties we cant see
        if (!Prop->HasAnyPropertyFlags(CPF_Edit|CPF_BlueprintVisible) ||
                Prop->HasAnyPropertyFlags(CPF_Transient) ||
                Prop->HasAnyPropertyFlags(CPF_DisableEditOnInstance) ||
                Prop->IsA(UFunction::StaticClass()) ||
                Prop->IsA(UDelegateProperty::StaticClass()) ||
                Prop->IsA(UMulticastDelegateProperty::StaticClass()))
        {
            continue;
        }

        FString ValueStringA = BlueprintNodeHelpers::DescribeProperty(Prop, Prop->ContainerPtrToValuePtr<uint8>(DataA));
        FString ValueStringB  = BlueprintNodeHelpers::DescribeProperty(Prop, Prop->ContainerPtrToValuePtr<uint8>(DataB));

        if ( ValueStringA != ValueStringB )
        {
            if(Results)
            {
                Diff.DisplayString = FText::Format(LOCTEXT("DIF_NodePropertyFmt", "Property Changed: {0} "), FText::FromString(Prop->GetName()));
                Results.Add(Diff);
            }
        }
    }
}
void SGraphPinLiveEditVar::GenerateComboBoxIndexesRecurse( UStruct *InStruct, FString PropertyPrefix, TArray< TSharedPtr<int32> >& OutComboBoxIndexes )
{
	check( InStruct != NULL );

	for (TFieldIterator<UProperty> PropertyIt(InStruct, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		if ( !Property->IsA(UNumericProperty::StaticClass()) )
		{
			if ( Property->IsA(UStructProperty::StaticClass()) )
			{
				UStructProperty *StructProp = Cast<UStructProperty>(Property);
				if ( IsPropertyPermitedForLiveEditor(*StructProp) )
				{
					if ( Property->ArrayDim > 1 )
					{
						for ( int32 i = 0; i < Property->ArrayDim; ++i )
						{
							FString arrayIndex = FString::Printf( TEXT("[%d]"), i );
							FString NewPropertyPrefix = FString::Printf( TEXT("%s%s%s."), *PropertyPrefix, *Property->GetName(), *arrayIndex );
							GenerateComboBoxIndexesRecurse( StructProp->Struct, NewPropertyPrefix, OutComboBoxIndexes );
						}
					}
					else
					{
						FString NewPropertyPrefix = FString::Printf( TEXT("%s%s."), *PropertyPrefix, *Property->GetName() );
						GenerateComboBoxIndexesRecurse( StructProp->Struct, NewPropertyPrefix, OutComboBoxIndexes );
					}
				}
			}
			else if ( Property->IsA(UArrayProperty::StaticClass()) )
			{
				UArrayProperty *ArrayProp = Cast<UArrayProperty>(Property);

			}
			continue;
		}

		if ( IsPropertyPermitedForLiveEditor(*Property) )
		{
			if ( Property->ArrayDim > 1 )
			{
				for ( int32 i = 0; i < Property->ArrayDim; ++i )
				{
					FString arrayIndex = FString::Printf( TEXT("[%d]"), i );
					FString Name = PropertyPrefix + Property->GetName() + arrayIndex;
					VariableNameList.Add( Name );
				}
			}
			else
			{
				FString Name = PropertyPrefix + Property->GetName();
				VariableNameList.Add( Name );
			}
		}
	}
}
void UK2Node_SpawnActor::CreatePinsForClass(UClass* InClass)
{
	check(InClass != NULL);

	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

	for (TFieldIterator<UProperty> PropertyIt(InClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		UClass* PropertyClass = CastChecked<UClass>(Property->GetOuter());
		const bool bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass());
		const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property);
		const bool bIsSettableExternally = !Property->HasAnyPropertyFlags(CPF_DisableEditOnInstance);

		if(	bIsExposedToSpawn &&
			!Property->HasAnyPropertyFlags(CPF_Parm) && 
			bIsSettableExternally &&
			Property->HasAllPropertyFlags(CPF_BlueprintVisible) &&
			!bIsDelegate )
		{
			UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName());
			const bool bPinGood = (Pin != NULL) && K2Schema->ConvertPropertyToPinType(Property, /*out*/ Pin->PinType);	
		}
	}

	// Change class of output pin
	UEdGraphPin* ResultPin = GetResultPin();
	ResultPin->PinType.PinSubCategoryObject = InClass;
}
void SetCellValue( const TSharedRef< IPropertyTableCell >& Cell, FString Value )
{
	if ( Cell->IsReadOnly() )
	{
		return;
	}

	// We need to sanitize property name strings
	TSharedPtr<FPropertyNode> PropertyNode = Cell->GetNode();
	if (PropertyNode.IsValid())
	{
		UProperty* NodeProperty = PropertyNode->GetProperty();
		if (NodeProperty->IsA(UNameProperty::StaticClass()))
		{
			// Remove any pre-existing return characters
			Value = Value.TrimQuotes().Replace(TEXT("\n"), TEXT(""));
		}
	}

	FString CurrentValue = Cell->GetValueAsString();
	if ( CurrentValue != Value )
	{
		// Set value
		Cell->SetValueFromString( Value );
	}
}
uint8* UAnimSequenceBase::FindNotifyPropertyData(int32 NotifyIndex, UArrayProperty*& ArrayProperty)
{
	// initialize to NULL
	ArrayProperty = NULL;

	if(Notifies.IsValidIndex(NotifyIndex))
	{
		// find Notifies property start point
		UProperty* Property = FindField<UProperty>(GetClass(), TEXT("Notifies"));

		// found it and if it is array
		if(Property && Property->IsA(UArrayProperty::StaticClass()))
		{
			// find Property Value from UObject we got
			uint8* PropertyValue = Property->ContainerPtrToValuePtr<uint8>(this);

			// it is array, so now get ArrayHelper and find the raw ptr of the data
			ArrayProperty = CastChecked<UArrayProperty>(Property);
			FScriptArrayHelper ArrayHelper(ArrayProperty, PropertyValue);

			if(ArrayProperty->Inner && NotifyIndex < ArrayHelper.Num())
			{
				//Get property data based on selected index
				return ArrayHelper.GetRawPtr(NotifyIndex);
			}
		}
	}
	return NULL;
}
void SPropertyEditorCombo::SendToObjects( const FString& NewValue )
{
	const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode();
	UProperty* Property = PropertyNode->GetProperty();

	FString Value;
	if ( bUsesAlternateDisplayValues && !Property->IsA(UStrProperty::StaticClass()))
	{
		// currently only enum properties can use alternate display values; this 
		// might change, so assert here so that if support is expanded to other 
		// property types without updating this block of code, we'll catch it quickly
		UEnum* Enum = CastChecked<UByteProperty>(Property)->Enum;
		check(Enum != nullptr);

		const int32 Index = FindEnumValueIndex(Enum, NewValue);
		check( Index != INDEX_NONE );

		Value = Enum->GetEnumName(Index);

		FText ToolTipValue = Enum->GetToolTipText(Index);
		FText ToolTipText = Property->GetToolTipText();
		if (!ToolTipValue.IsEmpty())
		{
			ToolTipText = FText::Format(FText::FromString(TEXT("{0}\n\n{1}")), ToolTipText, ToolTipValue);
		}
		SetToolTipText(ToolTipText);
	}
	else
	{
		Value = NewValue;
	}

	const TSharedRef< IPropertyHandle > PropertyHandle = PropertyEditor->GetPropertyHandle();
	PropertyHandle->SetValueFromFormattedString( Value );
}
Esempio n. 11
0
//------------------------------------------------------------------------------
static void BlueprintActionDatabaseImpl::AddClassPropertyActions(UClass const* const Class, FActionList& ActionListOut)
{
	using namespace FBlueprintNodeSpawnerFactory; // for MakeDelegateNodeSpawner()

	bool const bIsComponent  = Class->IsChildOf<UActorComponent>();
	bool const bIsActorClass = Class->IsChildOf<AActor>();
	
	// loop over all the properties in the specified class; exclude-super because 
	// we can always get the super properties by looking up that class separateHavely 
	for (TFieldIterator<UProperty> PropertyIt(Class, EFieldIteratorFlags::ExcludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		if (!IsPropertyBlueprintVisible(Property))
		{
			continue;
		}

 		bool const bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass());
 		if (bIsDelegate)
 		{
			UMulticastDelegateProperty* DelegateProperty = CastChecked<UMulticastDelegateProperty>(Property);
			if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintAssignable))
			{
				UBlueprintNodeSpawner* AddSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_AddDelegate::StaticClass(), DelegateProperty);
				ActionListOut.Add(AddSpawner);
				
				UBlueprintNodeSpawner* AssignSpawner = MakeAssignDelegateNodeSpawner(DelegateProperty);
				ActionListOut.Add(AssignSpawner);
			}
			
			if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintCallable))
			{
				UBlueprintNodeSpawner* CallSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_CallDelegate::StaticClass(), DelegateProperty);
				ActionListOut.Add(CallSpawner);
			}
			
			UBlueprintNodeSpawner* RemoveSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_RemoveDelegate::StaticClass(), DelegateProperty);
			ActionListOut.Add(RemoveSpawner);
			UBlueprintNodeSpawner* ClearSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_ClearDelegate::StaticClass(), DelegateProperty);
			ActionListOut.Add(ClearSpawner);

			if (bIsComponent)
			{
				ActionListOut.Add(MakeComponentBoundEventSpawner(DelegateProperty));
			}
			else if (bIsActorClass)
			{
				ActionListOut.Add(MakeActorBoundEventSpawner(DelegateProperty));
			}
 		}
		else
		{
			UBlueprintVariableNodeSpawner* GetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableGet::StaticClass(), Property);
			ActionListOut.Add(GetterSpawner);
			UBlueprintVariableNodeSpawner* SetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableSet::StaticClass(), Property);
			ActionListOut.Add(SetterSpawner);
		}
	}
}
bool FPropertyTableColumn::CanSortBy() const
{
	TWeakObjectPtr< UObject > Object = DataSource->AsUObject();
	UProperty* Property = Cast< UProperty >( Object.Get() );

	TSharedPtr< FPropertyPath > Path = DataSource->AsPropertyPath();
	if ( Property == NULL && Path.IsValid() )
	{
		Property = Path->GetLeafMostProperty().Property.Get();
	}

	if ( Property != NULL )
	{
		return Property->IsA( UByteProperty::StaticClass() )  ||
			Property->IsA( UIntProperty::StaticClass() )   ||
			Property->IsA( UBoolProperty::StaticClass() )  ||
			Property->IsA( UFloatProperty::StaticClass() ) ||
			Property->IsA( UNameProperty::StaticClass() )  ||
			Property->IsA( UStrProperty::StaticClass() )   ||
			( Property->IsA( UObjectProperty::StaticClass() ) && !Property->HasAnyPropertyFlags(CPF_InstancedReference) );
			//Property->IsA( UTextProperty::StaticClass() );
	}

	return false;
}
void FCSharpWrapperGenerator::GenerateFunctionWrapper(const UFunction* Function)
{
	FString formalInteropArgs, actualInteropArgs, formalManagedArgs, actualManagedArgs;
	UProperty* returnValue = GetWrapperArgsAndReturnType(
		Function, formalInteropArgs, actualInteropArgs, formalManagedArgs, actualManagedArgs
	);
	const bool bHasReturnValue = (returnValue != nullptr);
	const bool bReturnsBool = (bHasReturnValue && returnValue->IsA(UBoolProperty::StaticClass()));
	const FString returnValueInteropTypeName = 
		bHasReturnValue ? GetPropertyInteropType(returnValue) : TEXT("void");
	const FString returnValueManagedTypeName =
		bHasReturnValue ? GetPropertyManagedType(returnValue) : TEXT("void");
	const FString delegateTypeName = GetDelegateTypeName(Function->GetName(), bHasReturnValue);
	const FString delegateName = GetDelegateName(Function->GetName());

	GeneratedGlue 
		// declare a managed delegate type matching the type of the native wrapper function
		<< UnmanagedFunctionPointerAttribute
		<< (bReturnsBool ? MarshalReturnedBoolAsUint8Attribute : FString())
		<< FString::Printf(
			TEXT("private delegate %s %s(%s);"),
			*returnValueInteropTypeName, *delegateTypeName, *formalInteropArgs
		)
		// declare a delegate instance that will be bound to the native wrapper function
		<< FString::Printf(
			TEXT("private static %s %s;"),
			*delegateTypeName, *delegateName
		)
		// define a managed method that calls the native wrapper function through the delegate 
		// declared above
		<< FString::Printf(
			TEXT("public %s %s(%s)"),
			*returnValueManagedTypeName, *Function->GetName(), *formalManagedArgs
		)
		<< FCodeFormatter::OpenBrace();

	// call the delegate bound to the native wrapper function
	if (bHasReturnValue)
	{
		GeneratedGlue 
			<< FString::Printf(TEXT("var value = %s(%s);"), *delegateName, *actualInteropArgs)
			<< GetReturnValueHandler(returnValue);
	}
	else
	{
		GeneratedGlue << FString::Printf(TEXT("%s(%s);"), *delegateName, *actualInteropArgs);
	}
		
	GeneratedGlue
		<< FCodeFormatter::CloseBrace()
		<< FCodeFormatter::LineTerminator();

	FExportedFunction funcInfo;
	funcInfo.DelegateName = delegateName;
	funcInfo.DelegateTypeName = delegateTypeName;
	ExportedFunctions.Add(funcInfo);
}
void SPropertyEditorCombo::SendToObjects( const FString& NewValue )
{
	const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode();
	UProperty* Property = PropertyNode->GetProperty();

	FString Value;
	FString ToolTipValue;
	if ( bUsesAlternateDisplayValues && !Property->IsA(UStrProperty::StaticClass()))
	{
		// currently only enum properties can use alternate display values; this might change, so assert here so that if support is expanded to other property types
		// without updating this block of code, we'll catch it quickly
		UEnum* Enum = CastChecked<UByteProperty>(Property)->Enum;
		check(Enum);
		int32 Index = INDEX_NONE;
		for( int32 ItemIndex = 0; ItemIndex <  Enum->NumEnums(); ++ItemIndex )
		{
			const FString EnumName = Enum->GetEnumName(ItemIndex);
			const FString DisplayName = Enum->GetDisplayNameText(ItemIndex ).ToString();
			if( DisplayName.Len() > 0 )
			{
				if ( DisplayName == NewValue )
				{
					Index = ItemIndex;
					break;
				}
			}
			else if (EnumName == NewValue)
			{
				Index = ItemIndex;
				break;
			}
		}

		check( Index != INDEX_NONE );

		Value = Enum->GetEnumName(Index);

		ToolTipValue = Enum->GetMetaData( TEXT("ToolTip"), Index );
		FString ToolTipText = Property->GetToolTipText().ToString();
		if (ToolTipValue.Len() > 0)
		{
			ToolTipText = FString::Printf(TEXT("%s\n\n%s"), *ToolTipText, *ToolTipValue);
		}
		SetToolTipText(ToolTipText);
	}
	else
	{
		Value = NewValue;
	}

	const TSharedRef< IPropertyHandle > PropertyHandle = PropertyEditor->GetPropertyHandle();
	PropertyHandle->SetValueFromFormattedString( Value );
}
void UK2Node_AddComponent::AllocatePinsForExposedVariables()
{
	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

	const UActorComponent* TemplateComponent = GetTemplateFromNode();
	const UClass* ComponentClass = TemplateComponent ? TemplateComponent->GetClass() : nullptr;

	if (ComponentClass != nullptr)
	{
		const UObject* ClassDefaultObject = ComponentClass ? ComponentClass->ClassDefaultObject : nullptr;

		for (TFieldIterator<UProperty> PropertyIt(ComponentClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
		{
			UProperty* Property = *PropertyIt;
			const bool bNotDelegate = !Property->IsA(UMulticastDelegateProperty::StaticClass());
			const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property);
			const bool bIsVisible = Property->HasAllPropertyFlags(CPF_BlueprintVisible);
			const bool bNotParam = !Property->HasAllPropertyFlags(CPF_Parm);
			if(bNotDelegate && bIsExposedToSpawn && bIsVisible && bNotParam)
			{
				FEdGraphPinType PinType;
				K2Schema->ConvertPropertyToPinType(Property, /*out*/ PinType);	
				const bool bIsUnique = (NULL == FindPin(Property->GetName()));
				if (K2Schema->FindSetVariableByNameFunction(PinType) && bIsUnique)
				{
					UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName());
					Pin->PinType = PinType;
					bHasExposedVariable = true;

					if ((ClassDefaultObject != nullptr) && K2Schema->PinDefaultValueIsEditable(*Pin))
					{
						FString DefaultValueAsString;
						const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString);
						check(bDefaultValueSet);
						K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString);
					}

					// Copy tooltip from the property.
					K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip);
				}
			}
		}
	}

	// Hide transform and attachment pins if it is not a scene component
	const bool bHideTransformPins = (ComponentClass != nullptr) ? !ComponentClass->IsChildOf(USceneComponent::StaticClass()) : false;

	UEdGraphPin* ManualAttachmentPin = GetManualAttachmentPin();
	ManualAttachmentPin->SafeSetHidden(bHideTransformPins);

	UEdGraphPin* TransformPin = GetRelativeTransformPin();
	TransformPin->SafeSetHidden(bHideTransformPins);
}
bool FStructureEditorUtils::CanEnableMultiLineText(const UUserDefinedStruct* Struct, FGuid VarGuid)
{
	auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
	if (VarDesc)
	{
		UProperty* Property = FindField<UProperty>(Struct, VarDesc->VarName);

		// If this is an array, we need to test its inner property as that's the real type
		if (UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Property))
		{
			Property = ArrayProperty->Inner;
		}

		if (Property)
		{
			// Can only set multi-line text on string and text properties
			return Property->IsA(UStrProperty::StaticClass())
				|| Property->IsA(UTextProperty::StaticClass());
		}
	}
	return false;
}
void ULiveEditorKismetLibrary::ReplicateChangesToChildren( FName PropertyName, UObject *Archetype )
{	
	if ( Archetype == NULL )
		return;
	
	//find our child instances from the LiveEditManage lookup cache
	TArray< TWeakObjectPtr<UObject> > PiePartners;
	FLiveEditorManager::Get().FindPiePartners( Archetype, PiePartners );

	for(TArray< TWeakObjectPtr<UObject> >::TIterator It(PiePartners); It; ++It)
	{
		if ( !(*It).IsValid() )
			continue;

		UObject *Object = (*It).Get();
		check( Object->IsA(Archetype->GetClass()) );	//little sanity check, but the object cache manages all this for us
		nLiveEditorKismetLibrary::CopyPropertyFromArchetype( Object, Archetype, PropertyName );
	}

	void *ContainerPtr = Archetype;
	int32 ArrayIndex = 0;
	UProperty *Prop = nLiveEditorKismetLibrary::GetPropertyByName( Archetype, Archetype->GetClass(), PropertyName.ToString(), &ContainerPtr, ArrayIndex );
	if ( Prop && Prop->IsA( UNumericProperty::StaticClass() ) )
	{
		check( ContainerPtr != NULL );
		FString ClassName = Archetype->GetClass()->GetName();
		FString ValueString;
		void *Value = Prop->ContainerPtrToValuePtr<void>(ContainerPtr, ArrayIndex);
		Prop->ExportTextItem(ValueString, Value, NULL, NULL, 0);
		FLiveEditorManager::Get().BroadcastValueUpdate( ClassName, PropertyName.ToString(), ValueString );
	}

	/**
	 * Object iteration method should we want to dump the PIEObjectCache
	 * Downside is that it is perceptably slow (though still usable)
	TArray<UObject*> ObjectsToChange;
	const bool bIncludeDerivedClasses = true;
	GetObjectsOfClass(Archetype->GetClass(), ObjectsToChange, bIncludeDerivedClasses);
	for ( auto ObjIt = ObjectsToChange.CreateIterator(); ObjIt; ++ObjIt )
	{
		UObject *Object = *ObjIt;

		UWorld *World = GEngine->GetWorldFromContextObject( Object, false );
		if ( World == NULL || World->WorldType != EWorldType::PIE )
			continue;

		CopyPropertyFromArchetype( Object, Archetype, PropertyName );
	}
	*/
}
bool FDeviceProfileTextureLODSettingsColumn::Supports(const TSharedRef< IPropertyTableColumn >& Column, const TSharedRef< IPropertyTableUtilities >& Utilities) const
{
	if( Column->GetDataSource()->IsValid() )
	{
		TSharedPtr< FPropertyPath > PropertyPath = Column->GetDataSource()->AsPropertyPath();
		if( PropertyPath.IsValid() && PropertyPath->GetNumProperties() > 0 )
		{
			const FPropertyInfo& PropertyInfo = PropertyPath->GetRootProperty();
			UProperty* Property = PropertyInfo.Property.Get();
			if (Property->GetName() == TEXT("TextureLODGroups") && Property->IsA(UArrayProperty::StaticClass()))
			{
				return true;
			}
		}
	}

	return false;
}
bool SGraphPinLiveEditVar::IsPropertyPermitedForLiveEditor( UProperty &Property )
{
	const bool bIsDelegate = Property.IsA(UMulticastDelegateProperty::StaticClass());
		
	//YES (must have all)
	uint64 MustHaveFlags = CPF_Edit;

	//NO (must not have any)
	uint64 MustNotHaveFlags = CPF_BlueprintReadOnly | CPF_DisableEditOnInstance | CPF_EditConst | CPF_Parm;

	if ( !Property.HasAllPropertyFlags(MustHaveFlags) )
		return false;
	if ( Property.HasAnyPropertyFlags(MustNotHaveFlags) )
		return false;
	if ( bIsDelegate )
		return false;

	return true;
}
void FPropertyTableRow::GenerateChildren()
{
	if ( !DataSource->IsValid() || DataSource->AsPropertyPath().IsValid() )
	{
		return;
	}

	const TSharedRef< class IPropertyTable > TableRef = GetTable();
	TWeakObjectPtr< UObject > Object = DataSource->AsUObject();
	TSharedRef< FObjectPropertyNode > ObjectNode = TableRef->GetObjectPropertyNode( Object );
	TSharedRef< FPropertyPath > RootPath = TableRef->GetRootPath();

	TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, ObjectNode );

	if ( !PropertyNode.IsValid() )
	{
		return;
	}

	PropertyNode = FPropertyNode::FindPropertyNodeByPath( PartialPath, PropertyNode.ToSharedRef() );

	if ( !PropertyNode.IsValid() )
	{
		return;
	}

	UProperty* Property = PropertyNode->GetProperty();

	if ( Property != NULL && Property->IsA( UArrayProperty::StaticClass() ) )
	{
		for (int Index = 0; Index < PropertyNode->GetNumChildNodes(); Index++)
		{
			TSharedPtr< FPropertyNode > ChildNode = PropertyNode->GetChildNode( Index );

			FPropertyInfo Extension;
			Extension.Property = ChildNode->GetProperty();
			Extension.ArrayIndex = ChildNode->GetArrayIndex();

			Children.Add( MakeShareable( new FPropertyTableRow( TableRef, Object, RootPath->ExtendPath( Extension ) ) ) );
		}
	}
}
uint8* UAnimSequenceBase::FindArrayProperty(const TCHAR* PropName, UArrayProperty*& ArrayProperty, int32 ArrayIndex)
{
	// find Notifies property start point
	UProperty* Property = FindField<UProperty>(GetClass(), PropName);

	// found it and if it is array
	if (Property && Property->IsA(UArrayProperty::StaticClass()))
	{
		// find Property Value from UObject we got
		uint8* PropertyValue = Property->ContainerPtrToValuePtr<uint8>(this);

		// it is array, so now get ArrayHelper and find the raw ptr of the data
		ArrayProperty = CastChecked<UArrayProperty>(Property);
		FScriptArrayHelper ArrayHelper(ArrayProperty, PropertyValue);

		if (ArrayProperty->Inner && ArrayIndex < ArrayHelper.Num())
		{
			//Get property data based on selected index
			return ArrayHelper.GetRawPtr(ArrayIndex);
		}
	}
	return NULL;
}
Esempio n. 22
0
	/**
	 * Caches the property value
	 */
	void CacheValue()
	{
		Data.Reset();

		FPropertyNode& PropertyNodeRef = *PropertyNode.Pin();
		UProperty* Property = PropertyNodeRef.GetProperty();
		{
			// Not supported yet
			check( !Property->IsA( UArrayProperty::StaticClass() ) )

			if( PropertyNodeRef.GetArrayIndex() == INDEX_NONE && Property->ArrayDim > 1 )
			{
				// Check static arrays
				Data.AddZeroed( Property->ArrayDim * Property->ElementSize );
				Property->CopyCompleteValue( Data.GetData(), PropertyValueAddress);
			}
			else
			{
				// Regular properties
				Data.AddZeroed( Property->ElementSize );
				Property->CopySingleValue( Data.GetData(), PropertyValueAddress );
			}
		}
	}
void FPropertyTable::UpdateRows()
{
	if( Orientation == EPropertyTableOrientation::AlignPropertiesInColumns )
	{
		TMultiMap< UObject*, TSharedRef< IPropertyTableRow > > RowsMap;

		for (int RowIdx = 0; RowIdx < Rows.Num(); ++RowIdx)
		{
			RowsMap.Add(Rows[RowIdx]->GetDataSource()->AsUObject().Get(), Rows[RowIdx]);
		}

		Rows.Empty();
		for( auto ObjectIter = SourceObjects.CreateConstIterator(); ObjectIter; ++ObjectIter )
		{
			const TWeakObjectPtr< UObject >& Object = *ObjectIter;

			if( Object.IsValid() )
			{
				const TSharedRef< FObjectPropertyNode > ObjectNode = GetObjectPropertyNode( Object );
				const TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, ObjectNode );

				//@todo This system will need to change in order to properly support arrays [11/30/2012 Justin.Sargent]
				if ( PropertyNode.IsValid() )
				{
					UProperty* Property = PropertyNode->GetProperty();

					if ( Property != NULL && Property->IsA( UArrayProperty::StaticClass() ) )
					{
						for (int ChildIdx = 0; ChildIdx < PropertyNode->GetNumChildNodes(); ChildIdx++)
						{
							TSharedPtr< FPropertyNode > ChildNode = PropertyNode->GetChildNode( ChildIdx );

							FPropertyInfo Extension;
							Extension.Property = ChildNode->GetProperty();
							Extension.ArrayIndex = ChildNode->GetArrayIndex();
							TSharedRef< FPropertyPath > Path = FPropertyPath::CreateEmpty()->ExtendPath( Extension );
							TArray< TSharedRef< IPropertyTableRow > > MapResults;
							bool Found = false;

							RowsMap.MultiFind(Object.Get(), MapResults);

							for (int MapIdx = 0; MapIdx < MapResults.Num(); ++MapIdx)
							{
								if (FPropertyPath::AreEqual(Path, MapResults[MapIdx]->GetPartialPath()))
								{
									Found = true;
									Rows.Add(MapResults[MapIdx]);
									break;
								}
							}

							if (!Found)
							{
								Rows.Add( MakeShareable( new FPropertyTableRow( SharedThis( this ), Object, Path ) ) );
							}
						}
					}
					else
					{
						TArray< TSharedRef< IPropertyTableRow > > MapResults;
						bool Found = false;

						RowsMap.MultiFind(Object.Get(), MapResults);

						for (int MapIdx = 0; MapIdx < MapResults.Num(); ++MapIdx)
						{
							if (MapResults[MapIdx]->GetPartialPath()->GetNumProperties() == 0)
							{
								Found = true;
								Rows.Add(MapResults[MapIdx]);
								break;
							}
						}

						if (!Found)
						{
							Rows.Add( MakeShareable( new FPropertyTableRow( SharedThis( this ), Object ) ) );
						}
					}
				}
			}
		}
	}

	const TSharedPtr< IPropertyTableColumn > Column = SortedByColumn.Pin();
	if ( Column.IsValid() && SortedColumnMode != EColumnSortMode::None )
	{
		Column->Sort( Rows, SortedColumnMode );
	}

	RowsChanged.Broadcast();
}
void FPropertyTable::UpdateColumns()
{
	if( Orientation == EPropertyTableOrientation::AlignPropertiesInColumns)
	{
		TMultiMap< UProperty*, TSharedRef< IPropertyTableColumn > > ColumnsMap;
		for (int ColumnIdx = 0; ColumnIdx < Columns.Num(); ++ColumnIdx)
		{
			TSharedRef< IDataSource > DataSource = Columns[ColumnIdx]->GetDataSource();
			TSharedPtr< FPropertyPath > PropertyPath = DataSource->AsPropertyPath();
			if( PropertyPath.IsValid() && PropertyPath->GetNumProperties() > 0 )
			{
				ColumnsMap.Add(PropertyPath->GetRootProperty().Property.Get(), Columns[ColumnIdx]);
			}
		}

		Columns.Empty();

		if ( ShowRowHeader )
		{
			TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableRowHeaderColumn( SharedThis( this ) ) );
			Columns.Add( NewColumn );
		}

		if ( ShowObjectName )
		{
			TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableObjectNameColumn( SharedThis( this ) ) );
			NewColumn->SetFrozen( true );
			Columns.Add( NewColumn );
		}

		TArray< TWeakObjectPtr< UStruct > > UniqueTypes;
		TArray< int > TypeCounter;

		for( auto ObjectIter = SourceObjects.CreateConstIterator(); ObjectIter; ++ObjectIter )
		{
			auto Object = *ObjectIter;

			if( !Object.IsValid() )
			{
				continue;
			}

			const TSharedRef< FObjectPropertyNode > RootObjectNode = GetObjectPropertyNode( Object );

			TWeakObjectPtr< UStruct > Type;
			if ( RootPath->GetNumProperties() == 0 )
			{
				Type = RootObjectNode->GetObjectBaseClass();
			}
			else
			{
				const TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, RootObjectNode );

				if ( !PropertyNode.IsValid() )
				{
					continue;
				}

				const TWeakObjectPtr< UProperty > Property = PropertyNode->GetProperty();

				if ( !Property.IsValid() || !Property->IsA( UStructProperty::StaticClass() ) )
				{
					continue;
				}

				UStructProperty* StructProperty = Cast< UStructProperty >( Property.Get() );
				Type = StructProperty->Struct;
			}

			if ( !Type.IsValid() )
			{
				continue;
			}

			int FoundIndex = -1;
			if ( UniqueTypes.Find( Type, /*OUT*/FoundIndex ) )
			{
				TypeCounter[ FoundIndex ] = TypeCounter[ FoundIndex ] + 1;
				continue;
			}

			UniqueTypes.Add( Type );
			TypeCounter.Add( 1 );
		}

		if ( UniqueTypes.Num() > 0 )
		{
			int HighestCountIndex = 0;
			int HighestCount = 0;
			for (int Index = 0; Index < TypeCounter.Num(); Index++)
			{
				if ( TypeCounter[Index] > HighestCount )
				{
					HighestCountIndex = Index;
					HighestCount = TypeCounter[Index];
				}
			}

			TWeakObjectPtr< UStruct > PrimaryType = UniqueTypes[ HighestCountIndex ];

			for (TFieldIterator<UProperty> PropertyIter( PrimaryType.Get(), EFieldIteratorFlags::IncludeSuper); PropertyIter; ++PropertyIter)
			{
				TWeakObjectPtr< UProperty > Property = *PropertyIter;

				if ( PropertyIter->HasAnyPropertyFlags(CPF_AssetRegistrySearchable) )
				{
					TArray< TSharedRef< IPropertyTableColumn > > MapResults;

					ColumnsMap.MultiFind(Property.Get(), MapResults);
					if(MapResults.Num() > 0)
					{
						for (int MapIdx = 0; MapIdx < MapResults.Num(); ++MapIdx)
						{
							Columns.Add(MapResults[MapIdx]);
						}
					}
					else
					{
						TSharedRef< IPropertyTableColumn > NewColumn = CreateColumn( Property );
						Columns.Add( NewColumn );
					}
				}
			}
		}
	}
	else
	{
		Columns.Empty();

		if( SourceObjects.Num() > 0 )
		{
			UClass* ObjectClass = SourceObjects[0]->GetClass();
			TSharedRef< IPropertyTableColumn > HeadingColumn = MakeShareable( new FPropertyTablePropertyNameColumn( SharedThis( this ) ) );

			Columns.Add( HeadingColumn );

			for( auto ObjectIter = SourceObjects.CreateConstIterator(); ObjectIter; ++ObjectIter )
			{
				auto Object = *ObjectIter;

				if( Object.IsValid() )
				{
					const TSharedRef< FObjectPropertyNode > ObjectNode = GetObjectPropertyNode( Object );
					const TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, ObjectNode );

					UProperty* Property = PropertyNode->GetProperty();
					if ( Property != NULL && Property->IsA( UArrayProperty::StaticClass() ) )
					{
						for (int ChildIdx = 0; ChildIdx < PropertyNode->GetNumChildNodes(); ChildIdx++)
						{
							TSharedPtr< FPropertyNode > ChildNode = PropertyNode->GetChildNode( ChildIdx );
							FPropertyInfo Extension;
							Extension.Property = ChildNode->GetProperty();
							Extension.ArrayIndex = ChildNode->GetArrayIndex();
							TSharedRef< FPropertyPath > Path = FPropertyPath::CreateEmpty()->ExtendPath( Extension );
							TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableColumn( SharedThis( this ), Object, Path ) );
							Columns.Add( NewColumn );
						}
					}
					else if (  Property != NULL )
					{
						TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableColumn( SharedThis( this ), Object ) );
						Columns.Add( NewColumn );
					}
				}

			}
		}
	}

	ColumnsChanged.Broadcast();
}
	static void CopyPropertyFromArchetype( UObject *Target, UObject *Archetype, FName PropertyName )
	{
		if ( Target == NULL || Archetype == NULL || !Target->IsA( Archetype->GetClass() ) )
			return;

		void *ArchetypeContainerPtr = Archetype;
		int32 ArchetypeArrayIndex;
		UProperty *Prop = GetPropertyByName( Archetype, Archetype->GetClass(), PropertyName.ToString(), &ArchetypeContainerPtr, ArchetypeArrayIndex );
		if ( !Prop || !Prop->IsA( UNumericProperty::StaticClass() ) )
			return;
		check(ArchetypeContainerPtr != NULL);

		void *TargetContainerPtr = Target; //(void*)((uint8*)ArchetypeContainerPtr - (uint8*)Archetype + (uint8*)Target);
		int32 TargetArrayIndex;
		UProperty *TargetProp = GetPropertyByName( Target, Target->GetClass(), PropertyName.ToString(), &TargetContainerPtr, TargetArrayIndex );
		check( TargetProp != NULL && TargetProp->IsA( UNumericProperty::StaticClass() ) );
		check( TargetArrayIndex == ArchetypeArrayIndex );

		if ( Prop->IsA( UByteProperty::StaticClass() ) )
		{
			UByteProperty *NumericProp = CastChecked<UByteProperty>(Prop);
			uint8 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UInt8Property::StaticClass() ) )
		{
			UInt8Property *NumericProp = CastChecked<UInt8Property>(Prop);
			int32 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UInt16Property::StaticClass() ) )
		{
			UInt16Property *NumericProp = CastChecked<UInt16Property>(Prop);
			int16 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UIntProperty::StaticClass() ) )
		{
			UIntProperty *NumericProp = CastChecked<UIntProperty>(Prop);
			int32 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UInt64Property::StaticClass() ) )
		{
			UInt64Property *NumericProp = CastChecked<UInt64Property>(Prop);
			int64 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UUInt16Property::StaticClass() ) )
		{
			UUInt16Property *NumericProp = CastChecked<UUInt16Property>(Prop);
			uint16 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UUInt32Property::StaticClass() ) )
		{
			UUInt32Property *NumericProp = CastChecked<UUInt32Property>(Prop);
			uint32 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UInt64Property::StaticClass() ) )
		{
			UInt64Property *NumericProp = CastChecked<UInt64Property>(Prop);
			uint64 ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UFloatProperty::StaticClass() ) )
		{
			UFloatProperty *NumericProp = CastChecked<UFloatProperty>(Prop);
			float ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
		else if ( Prop->IsA( UDoubleProperty::StaticClass() ) )
		{
			UDoubleProperty *NumericProp = CastChecked<UDoubleProperty>(Prop);
			double ArchetypeVal = NumericProp->GetPropertyValue_InContainer(ArchetypeContainerPtr, ArchetypeArrayIndex);
			NumericProp->SetPropertyValue_InContainer(TargetContainerPtr, ArchetypeVal, ArchetypeArrayIndex);
		}
	}
void UK2Node_LiveEditObject::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
	Super::ExpandNode(CompilerContext, SourceGraph);

	const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema();

	UEdGraphPin *SourceExecPin = GetExecPin();
	UEdGraphPin *SourceThenPin = GetThenPin();
	UEdGraphPin *SourceBlueprintPin = GetBlueprintPin();
	UEdGraphPin *SourceBaseClassPin = GetBaseClassPin();
	UEdGraphPin *SourceDescriptionPin = GetDescriptionPin();
	UEdGraphPin *SourcePermittedBindingsPin = GetPermittedBindingsPin();
	UEdGraphPin *SourceOnMidiInputPin = GetOnMidiInputPin();

	UEdGraphPin *SourceVariablePin = GetVariablePin();
	if(NULL == SourceVariablePin)
	{
		CompilerContext.MessageLog.Error(*LOCTEXT("LiveEditObjectNodeMissingBlueprint_Error", "LiveEdit node @@ must have a blueprint specified and a variable selected to tune.").ToString(), this);
		// we break exec links so this is the only error we get, don't want the SpawnActor node being considered and giving 'unexpected node' type warnings
		BreakAllNodeLinks();
		return;
	}

	UClass* SpawnClass = GetClassToSpawn();
	if(NULL == SpawnClass)
	{
		CompilerContext.MessageLog.Error(*LOCTEXT("LiveEditObjectNodeMissingBaseClass_Error", "LiveEdit node @@ must have a Base Class specified.").ToString(), this);
		// we break exec links so this is the only error we get, don't want the SpawnActor node being considered and giving 'unexpected node' type warnings
		BreakAllNodeLinks();
		return;
	}

	if ( SourcePermittedBindingsPin->LinkedTo.Num() == 0 )
	{
		CompilerContext.MessageLog.Error(*LOCTEXT("LiveEditObjectNodeMissingBinding_Error", "LiveEdit node @@ must specify Permitted Bindings.").ToString(), this);
		// we break exec links so this is the only error we get, don't want the SpawnActor node being considered and giving 'unexpected node' type warnings
		BreakAllNodeLinks();
		return;
	}

	//sanity check the VariablePin value
	{
		UProperty *Property = UK2Node_LiveEditObjectStatics::GetPropertyByName( SpawnClass, *SourceVariablePin->DefaultValue );
		if ( Property == NULL || !Property->IsA(UNumericProperty::StaticClass()) )
		{
			CompilerContext.MessageLog.Error(*LOCTEXT("LiveEditObjectNodeInvalidVariable_Error", "LiveEdit node @@ must have a valid variable selected.").ToString(), this);
			// we break exec links so this is the only error we get, don't want the SpawnActor node being considered and giving 'unexpected node' type warnings
			BreakAllNodeLinks();
			return;
		}
	}

	//hooks to pins that are generated after a BaseClass is set
	UEdGraphPin *DeltaMultPin = GetDeltaMultPin();
	UEdGraphPin *ShouldClampPin = GetShouldClampPin();
	UEdGraphPin *ClampMinPin = GetClampMinPin();
	UEdGraphPin *ClampMaxPin = GetClampMaxPin();

	UK2Node_Self *SelfNode  = CompilerContext.SpawnIntermediateNode<UK2Node_Self>(this,SourceGraph);
	SelfNode->AllocateDefaultPins();
	UEdGraphPin *SelfNodeThenPin = SelfNode->FindPinChecked(Schema->PN_Self);

	FString EventNameGuid = GetEventName();
		
	//Create the registration part of the LiveEditor binding process
	{
		UK2Node_CallFunction *RegisterForMIDINode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		RegisterForMIDINode->FunctionReference.SetExternalMember( TEXT("RegisterForLiveEditEvent"), ULiveEditorKismetLibrary::StaticClass() );
		RegisterForMIDINode->AllocateDefaultPins();

		UEdGraphPin *ExecPin = RegisterForMIDINode->GetExecPin();
		CompilerContext.MovePinLinksToIntermediate(*SourceExecPin, *ExecPin);

		UEdGraphPin *ThenPin = RegisterForMIDINode->GetThenPin();
		CompilerContext.MovePinLinksToIntermediate(*SourceThenPin, *ThenPin);

		UEdGraphPin *TargetPin = RegisterForMIDINode->FindPinChecked( FString(TEXT("Target")) );
		TargetPin->MakeLinkTo(SelfNodeThenPin);

		UEdGraphPin *EventNamePin = RegisterForMIDINode->FindPinChecked( FString(TEXT("EventName")) );
		EventNamePin->DefaultValue = EventNameGuid;
		
		UEdGraphPin *DescriptionPin = RegisterForMIDINode->FindPinChecked( FString(TEXT("Description")) );
		CompilerContext.CopyPinLinksToIntermediate( *SourceDescriptionPin, *DescriptionPin);

		UEdGraphPin *PermittedBindingsPin = RegisterForMIDINode->FindPinChecked( FString(TEXT("PermittedBindings")) );
		CompilerContext.CopyPinLinksToIntermediate( *SourcePermittedBindingsPin, *PermittedBindingsPin);
	}

	//Create the event handling part of the LiveEditor binding process
	{
		//
		//the event itself
		//
		UFunction *EventMIDISignature = GetEventMIDISignature();
		UK2Node_Event* EventNode = CompilerContext.SpawnIntermediateNode<UK2Node_Event>(this, SourceGraph);
		check(EventNode);
		EventNode->EventSignatureClass = Cast<UClass>(EventMIDISignature->GetOuter());
		EventNode->EventSignatureName = EventMIDISignature->GetFName();
		EventNode->CustomFunctionName = *EventNameGuid;
		EventNode->bInternalEvent = true;
		EventNode->AllocateDefaultPins();

		// Cache these out because we'll connect the sequence to it
		UEdGraphPin *EventThenPin = EventNode->FindPinChecked( Schema->PN_Then );
		UEdGraphPin *EventDeltaPin = EventNode->FindPinChecked( FString(TEXT("Delta")) );
		UEdGraphPin *EventMidiValuePin = EventNode->FindPinChecked( FString(TEXT("MidiValue")) );
		UEdGraphPin *EventControlTypePin = EventNode->FindPinChecked( FString(TEXT("ControlType")) );


		//
		// Check if Blueprint is NULL
		//
		UEdGraphPin *CompareBlueprintToNullBranchThenPin = NULL;
		{
			UK2Node_CallFunction *CompareBlueprintToNullNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
			CompareBlueprintToNullNode->FunctionReference.SetExternalMember( TEXT("NotEqual_ObjectObject"), UKismetMathLibrary::StaticClass() );
			CompareBlueprintToNullNode->AllocateDefaultPins();

			//Set A Pin to the Blueprint Pin
			UEdGraphPin *CompareBlueprintToNullAPin = CompareBlueprintToNullNode->FindPinChecked( FString(TEXT("A")) );
			CompilerContext.CopyPinLinksToIntermediate( *SourceBlueprintPin, *CompareBlueprintToNullAPin);

			// hook for Compare Blueprint to NULL result
			UEdGraphPin *CompareBlueprintToNullResultPin = CompareBlueprintToNullNode->GetReturnValuePin();

			// Create the BRANCH that will drive the comparison
			UK2Node_IfThenElse* CompareBlueprintToNullBranchNode = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>(this, SourceGraph);
			CompareBlueprintToNullBranchNode->AllocateDefaultPins();

			//hook up the condition
			CompareBlueprintToNullResultPin->MakeLinkTo( CompareBlueprintToNullBranchNode->GetConditionPin() );

			//hook event to the branck input
			EventThenPin->MakeLinkTo( CompareBlueprintToNullBranchNode->GetExecPin() );

			//cache ot the THEN pin for later linkup
			CompareBlueprintToNullBranchThenPin = CompareBlueprintToNullBranchNode->GetThenPin();
		}

		//
		// Get Class Default Object
		//
		UK2Node_CallFunction *GetClassDefaultObjectNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		GetClassDefaultObjectNode->FunctionReference.SetExternalMember( TEXT("GetBlueprintClassDefaultObject"), ULiveEditorKismetLibrary::StaticClass() );
		GetClassDefaultObjectNode->AllocateDefaultPins();

		UEdGraphPin *GetClassDefaultObjectBlueprintPin = GetClassDefaultObjectNode->FindPinChecked( TEXT("Blueprint") );
		CompilerContext.CopyPinLinksToIntermediate( *SourceBlueprintPin, *GetClassDefaultObjectBlueprintPin);

		//hook for later -> the pointer to the ClassDefaultObject of our BlueprintPin
		UEdGraphPin *GetClassDefaultObjectResultPin = GetClassDefaultObjectNode->GetReturnValuePin();


		//
		// Compare to BaseClass to make sure that the target Blueprint IsA(BaseClass)
		//
		UEdGraphPin *ClassIsChildOfBranchThenPin = NULL;
		{
			//
			//we need to get the class of the Blueprint pin
			UK2Node_CallFunction *GetClassNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
			GetClassNode->FunctionReference.SetExternalMember( TEXT("GetObjectClass"), UGameplayStatics::StaticClass() );
			GetClassNode->AllocateDefaultPins();

			//Pin in the GetClassDefaultObjectResultPin to the Object Parameter of the GetObjectClass FUNCTION
			//we want to make sure that the Class of the DEFAULT_OBJECT IsA( BaseClass )
			UEdGraphPin *GetClassObjectPin = GetClassNode->FindPinChecked( FString(TEXT("Object")) );
			GetClassDefaultObjectResultPin->MakeLinkTo( GetClassObjectPin );

			//hook for the Class result
			UEdGraphPin *GetClassReturnValuePin = GetClassNode->GetReturnValuePin();

			//
			//the ClassIsChildOf FUNCTION
			UK2Node_CallFunction *ClassIsChildOfNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
			ClassIsChildOfNode->FunctionReference.SetExternalMember( TEXT("ClassIsChildOf"), UKismetMathLibrary::StaticClass() );
			ClassIsChildOfNode->AllocateDefaultPins();

			//hook up the test pin
			UEdGraphPin *ClassIsChildOfTestPin = ClassIsChildOfNode->FindPinChecked( FString(TEXT("TestClass")) );
			GetClassReturnValuePin->MakeLinkTo( ClassIsChildOfTestPin );

			//copy our BaseClass Pin into the ClassIsChildOf Parameter
			UEdGraphPin *ClassIsChildOfParentPin = ClassIsChildOfNode->FindPinChecked( FString(TEXT("ParentClass")) );
			CompilerContext.CopyPinLinksToIntermediate( *SourceBaseClassPin, *ClassIsChildOfParentPin);

			//hook for return value
			UEdGraphPin *ClassIsChildOfResultPin = ClassIsChildOfNode->GetReturnValuePin();

			//
			// Create the BRANCH that will drive the comparison
			UK2Node_IfThenElse* ClassIsChildOfBranchNode = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>(this, SourceGraph);
			ClassIsChildOfBranchNode->AllocateDefaultPins();

			//hook up the previous branch to this one
			check( CompareBlueprintToNullBranchThenPin != NULL );
			CompareBlueprintToNullBranchThenPin->MakeLinkTo( ClassIsChildOfBranchNode->GetExecPin() );

			//hook up our condition
			ClassIsChildOfResultPin->MakeLinkTo( ClassIsChildOfBranchNode->GetConditionPin() );

			//cache ot the THEN pin for later linkup
			ClassIsChildOfBranchThenPin = ClassIsChildOfBranchNode->GetThenPin();
		}


		//
		//The set variable function (to set LiveEdited new value)
		//
		UK2Node_CallFunction *ModifyVarNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		ModifyVarNode->FunctionReference.SetExternalMember( TEXT("ModifyPropertyByName"), ULiveEditorKismetLibrary::StaticClass() );
		ModifyVarNode->AllocateDefaultPins();

		// Make link from the event to the Set variable node
		UEdGraphPin *ModifyVarExecPin = ModifyVarNode->GetExecPin();
		ClassIsChildOfBranchThenPin->MakeLinkTo( ModifyVarExecPin );

		//link up the Target Pin
		UEdGraphPin *ModifyVarNodeTargetPin = ModifyVarNode->FindPinChecked( TEXT("Target") );
		GetClassDefaultObjectResultPin->MakeLinkTo( ModifyVarNodeTargetPin );

		//link up the PropertyName Pin
		UEdGraphPin *ModifyVarNodePropertyNamePin = ModifyVarNode->FindPinChecked( TEXT("PropertyName") );
		ModifyVarNodePropertyNamePin->DefaultValue = SourceVariablePin->DefaultValue;

		//link up the MIDI Value Pin
		UEdGraphPin *ModifyVarNodeMidiValuePin = ModifyVarNode->FindPinChecked( TEXT("MidiValue") );
		EventMidiValuePin->MakeLinkTo(ModifyVarNodeMidiValuePin);

		//link up the ControlType Pin
		UEdGraphPin *ModifyVarNodeControlTypePin = ModifyVarNode->FindPinChecked( TEXT("ControlType") );
		EventControlTypePin->MakeLinkTo(ModifyVarNodeControlTypePin);

		//hook for the Delta Pin
		UEdGraphPin *ModifyVarNodeDeltaPin = ModifyVarNode->FindPinChecked( TEXT("Delta") );

		//Clamping
		if ( ShouldClampPin->DefaultValue == FString(TEXT("true")) )
		{
			UEdGraphPin *ModifyVarNodeShouldClampPin = ModifyVarNode->FindPinChecked( TEXT("bShouldClamp") );
			CompilerContext.CopyPinLinksToIntermediate( *ShouldClampPin, *ModifyVarNodeShouldClampPin);

			check( ClampMinPin != NULL );
			UEdGraphPin *ModifyVarNodeClampMinPin = ModifyVarNode->FindPinChecked( TEXT("ClampMin") );
			CompilerContext.CopyPinLinksToIntermediate( *ClampMinPin, *ModifyVarNodeClampMinPin);

			check( ClampMaxPin != NULL );
			UEdGraphPin *ModifyVarNodeClampMaxPin = ModifyVarNode->FindPinChecked( TEXT("ClampMax") );
			CompilerContext.CopyPinLinksToIntermediate( *ClampMaxPin, *ModifyVarNodeClampMaxPin);
		}

		//hook for ModifyVar THEN
		UEdGraphPin *ModifyVarNodeThenPin = ModifyVarNode->GetThenPin();

		//
		// The Multiply Delta * DeltaMult function
		//
		UK2Node_CallFunction *MultiplyNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		MultiplyNode->FunctionReference.SetExternalMember( TEXT("Multiply_FloatFloat"), UKismetMathLibrary::StaticClass() );
		MultiplyNode->AllocateDefaultPins();

		//cache this out. it will be linked to from the output of the (int)Delta -> (float)Delta Conversion function
		UEdGraphPin *MultiplyNodeFirstPin = MultiplyNode->FindPinChecked( FString(TEXT("A")) );

		// 2nd input to the Add function comes from the Current variable value
		UEdGraphPin *MultiplyNodeSecondPin = MultiplyNode->FindPinChecked( FString(TEXT("B")) );
		CompilerContext.CopyPinLinksToIntermediate( *DeltaMultPin, *MultiplyNodeSecondPin);

		UEdGraphPin *MultiplyNodeReturnValuePin = MultiplyNode->GetReturnValuePin();
		MultiplyNodeReturnValuePin->MakeLinkTo( ModifyVarNodeDeltaPin );

		//
		// The Convert function to go from (int)Delta to ULiveEditorKismetLibrary::ModifyPropertyByName(... float Delta ...)
		//
		FName ConvertFunctionName;
		bool success = Schema->SearchForAutocastFunction( EventDeltaPin, MultiplyNodeFirstPin, ConvertFunctionName );
		check( success );
		UK2Node_CallFunction *ConvertDeltaNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		ConvertDeltaNode->FunctionReference.SetExternalMember( ConvertFunctionName, UKismetMathLibrary::StaticClass() );
		ConvertDeltaNode->AllocateDefaultPins();

		FName PinName;
		success = UK2Node_LiveEditObjectStatics::SearchForConvertPinName( Schema, EventDeltaPin, PinName );
		check( success );
		UEdGraphPin *ConvertDeltaInputPin = ConvertDeltaNode->FindPinChecked( PinName.ToString() );
		EventDeltaPin->MakeLinkTo( ConvertDeltaInputPin );

		UEdGraphPin *ConvertDeltaOutputPin = ConvertDeltaNode->GetReturnValuePin();
		ConvertDeltaOutputPin->MakeLinkTo( MultiplyNodeFirstPin );

		//
		// TODO - markDirty
		//

		//
		// send out the object value updates
		//
		UK2Node_CallFunction *ReplicationNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this,SourceGraph);
		ReplicationNode->FunctionReference.SetExternalMember( TEXT("ReplicateChangesToChildren"), ULiveEditorKismetLibrary::StaticClass() );
		ReplicationNode->AllocateDefaultPins();

		UEdGraphPin *ReplicationNodeVarNamePin = ReplicationNode->FindPinChecked( TEXT("PropertyName") );
		ReplicationNodeVarNamePin->DefaultValue = SourceVariablePin->DefaultValue;

		UEdGraphPin *ReplicationNodeArchetypePin = ReplicationNode->FindPinChecked( FString(TEXT("Archetype")) );
		GetClassDefaultObjectResultPin->MakeLinkTo( ReplicationNodeArchetypePin );

		UEdGraphPin *ReplicationNodeExecPin = ReplicationNode->GetExecPin();
		ModifyVarNodeThenPin->MakeLinkTo( ReplicationNodeExecPin );

		UEdGraphPin *ReplicationNodeThenPin = ReplicationNode->FindPinChecked( FString(TEXT("then")) );

		//
		// Finally, activate our OnMidiInput pin
		//
		CompilerContext.CopyPinLinksToIntermediate( *SourceOnMidiInputPin, *ReplicationNodeThenPin);
			
	}

	// Break any links to the expanded node
	BreakAllNodeLinks();
}
Esempio n. 27
0
void SSingleProperty::SetObject( UObject* InObject )
{
	DestroyColorPicker();

	if( !RootPropertyNode.IsValid() )
	{
		RootPropertyNode = MakeShareable( new FObjectPropertyNode );
	}

	RootPropertyNode->RemoveAllObjects();
	ValueNode.Reset();

	if( InObject )
	{
		RootPropertyNode->AddObject( InObject );
	}


	FPropertyNodeInitParams InitParams;
	InitParams.ParentNode = NULL;
	InitParams.Property = NULL;
	InitParams.ArrayOffset = 0;
	InitParams.ArrayIndex = INDEX_NONE;
	// we'll generate the children
	InitParams.bAllowChildren = false;
	InitParams.bForceHiddenPropertyVisibility = false;

	RootPropertyNode->InitNode( InitParams );

	ValueNode = RootPropertyNode->GenerateSingleChild( PropertyName );

	bool bIsAcceptableProperty = false;
	// valid criteria for standalone properties 
	if( ValueNode.IsValid() )
	{
		UProperty* Property = ValueNode->GetProperty();

		bIsAcceptableProperty = true;
		// not an array property (dynamic or static)
		bIsAcceptableProperty &= !( Property->IsA( UArrayProperty::StaticClass() ) || (Property->ArrayDim > 1 && ValueNode->GetArrayIndex() == INDEX_NONE) );
		// not a struct property unless its a built in type like a vector
		bIsAcceptableProperty &= ( !Property->IsA( UStructProperty::StaticClass() ) || PropertyEditorHelpers::IsBuiltInStructProperty( Property ) );
	}

	if( bIsAcceptableProperty )
	{
		ValueNode->RebuildChildren();

		TSharedRef< FPropertyEditor > PropertyEditor = FPropertyEditor::Create( ValueNode.ToSharedRef(), TSharedPtr< IPropertyUtilities >( PropertyUtilities ).ToSharedRef() );
		ValueNode->SetDisplayNameOverride( NameOverride );

		TSharedPtr<SHorizontalBox> HorizontalBox;

		ChildSlot
		[
			SAssignNew( HorizontalBox, SHorizontalBox )
		];

		if( NamePlacement != EPropertyNamePlacement::Hidden )
		{
			HorizontalBox->AddSlot()
			.Padding( 2.0f, 0.0f, 2.0f, 4.0f )
			.AutoWidth()
			.VAlign( VAlign_Center )
			[
				SNew( SPropertyNameWidget, PropertyEditor )
				.DisplayResetToDefault( false )
			];
		}

		HorizontalBox->AddSlot()
		.Padding( 0.0f, 2.0f, 0.0f, 2.0f )
		.FillWidth(1.0f)
		.VAlign( VAlign_Center )
		[
			SNew( SPropertyValueWidget, PropertyEditor, PropertyUtilities.ToSharedRef() )
		];

		HorizontalBox->AddSlot()
		.Padding( 2.0f )
		.AutoWidth()
		.VAlign( VAlign_Center )
		[
			SNew( SResetToDefaultPropertyEditor,  PropertyEditor )
		];
	}
	else
	{
		ChildSlot
		[
			SNew(STextBlock)
			.Font(PropertyFont)
			.Text(NSLOCTEXT("PropertyEditor", "SinglePropertyInvalidType", "Cannot Edit Inline"))
			.ToolTipText(NSLOCTEXT("PropertyEditor", "SinglePropertyInvalidType_Tooltip", "Properties of this type cannot be edited inline; edit it elsewhere"))
		];

		// invalid or missing property
		RootPropertyNode->RemoveAllObjects();
		ValueNode.Reset();
		RootPropertyNode.Reset();
	}
}
	static void SetPropertyValue( UObject *Target, const FString &PropertyName, const FString &PropertyValue )
	{

		if ( Target == NULL )
			return;

		void *ContainerPtr = Target;
		int32 ArrayIndex;
		UProperty *Prop = nLiveEditorListenServer::GetPropertyByName( Target, Target->GetClass(), PropertyName, &ContainerPtr, ArrayIndex );
		if ( !Prop || !Prop->IsA( UNumericProperty::StaticClass() ) )
		{
			return;
		}

		check( ContainerPtr != NULL );

		if ( Prop->IsA( UByteProperty::StaticClass() ) )
		{
			UByteProperty *NumericProp = CastChecked<UByteProperty>(Prop);
			uint8 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UInt8Property::StaticClass() ) )
		{
			UInt8Property *NumericProp = CastChecked<UInt8Property>(Prop);
			int32 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UInt16Property::StaticClass() ) )
		{
			UInt16Property *NumericProp = CastChecked<UInt16Property>(Prop);
			int16 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UIntProperty::StaticClass() ) )
		{
			UIntProperty *NumericProp = CastChecked<UIntProperty>(Prop);
			int32 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UInt64Property::StaticClass() ) )
		{
			UInt64Property *NumericProp = CastChecked<UInt64Property>(Prop);
			int64 Value = FCString::Atoi64( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UUInt16Property::StaticClass() ) )
		{
			UUInt16Property *NumericProp = CastChecked<UUInt16Property>(Prop);
			uint16 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UUInt32Property::StaticClass() ) )
		{
			UUInt32Property *NumericProp = CastChecked<UUInt32Property>(Prop);
			uint32 Value = FCString::Atoi( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UInt64Property::StaticClass() ) )
		{
			UInt64Property *NumericProp = CastChecked<UInt64Property>(Prop);
			uint64 Value = FCString::Atoi64( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UFloatProperty::StaticClass() ) )
		{
			UFloatProperty *NumericProp = CastChecked<UFloatProperty>(Prop);
			float Value = FCString::Atof( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
		else if ( Prop->IsA( UDoubleProperty::StaticClass() ) )
		{
			UDoubleProperty *NumericProp = CastChecked<UDoubleProperty>(Prop);
			double Value = FCString::Atod( *PropertyValue );
			NumericProp->SetPropertyValue_InContainer(ContainerPtr, Value, ArrayIndex);
		}
	}
Esempio n. 29
0
void UK2Node_LatentAbilityCall::CreatePinsForClass(UClass* InClass)
{
	check(InClass != NULL);

	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

	const UObject* const ClassDefaultObject = InClass->GetDefaultObject(false);

	SpawnParmPins.Empty();

	// Tasks can hide spawn parameters by doing meta = (HideSpawnParms="PropertyA,PropertyB")
	// (For example, hide Instigator in situations where instigator is not relevant to your task)
	
	TArray<FString> IgnorePropertyList;
	{
		UFunction* ProxyFunction = ProxyFactoryClass->FindFunctionByName(ProxyFactoryFunctionName);

		FString IgnorePropertyListStr = ProxyFunction->GetMetaData(FName(TEXT("HideSpawnParms")));
	
		if (!IgnorePropertyListStr.IsEmpty())
		{
			IgnorePropertyListStr.ParseIntoArray(IgnorePropertyList, TEXT(","), true);
		}
	}

	for (TFieldIterator<UProperty> PropertyIt(InClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		UClass* PropertyClass = CastChecked<UClass>(Property->GetOuter());
		const bool bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass());
		const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property);
		const bool bIsSettableExternally = !Property->HasAnyPropertyFlags(CPF_DisableEditOnInstance);

		if (bIsExposedToSpawn &&
			!Property->HasAnyPropertyFlags(CPF_Parm) &&
			bIsSettableExternally &&
			Property->HasAllPropertyFlags(CPF_BlueprintVisible) &&
			!bIsDelegate && 
			!IgnorePropertyList.Contains(Property->GetName()) &&
			(FindPin(Property->GetName()) == nullptr) )
		{


			UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName());
			const bool bPinGood = (Pin != NULL) && K2Schema->ConvertPropertyToPinType(Property, /*out*/ Pin->PinType);
			SpawnParmPins.Add(Pin);

			if (ClassDefaultObject && Pin && K2Schema->PinDefaultValueIsEditable(*Pin))
			{
				FString DefaultValueAsString;
				const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString);
				check(bDefaultValueSet);
				K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString);
			}

			// Copy tooltip from the property.
			if (Pin != nullptr)
			{
				K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip);
			}
		}
	}
}
void FPropertyTableColumn::Sort( TArray< TSharedRef< class IPropertyTableRow > >& Rows, const EColumnSortMode::Type SortMode )
{
	if ( SortMode == EColumnSortMode::None )
	{
		return;
	}

	TWeakObjectPtr< UObject > Object = DataSource->AsUObject();
	UProperty* Property = Cast< UProperty >( Object.Get() );

	TSharedPtr< FPropertyPath > Path = DataSource->AsPropertyPath();
	if ( Property == NULL && Path.IsValid() )
	{
		Property = Path->GetLeafMostProperty().Property.Get();
	}

	if (!Property)
	{
		return;
	}

	if ( Property->IsA( UByteProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UByteProperty> ByteProperty( Cast< UByteProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UByteProperty >( SharedThis( this ), ByteProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UByteProperty >( SharedThis( this ), ByteProperty ) );
		}
	}
	else if ( Property->IsA( UIntProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UIntProperty> IntProperty( Cast< UIntProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UIntProperty >( SharedThis( this ), IntProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UIntProperty >( SharedThis( this ), IntProperty ) );
		}
	}
	else if ( Property->IsA( UBoolProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UBoolProperty> BoolProperty( Cast< UBoolProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UBoolProperty >( SharedThis( this ), BoolProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UBoolProperty >( SharedThis( this ), BoolProperty ) );
		}
	}
	else if ( Property->IsA( UFloatProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UFloatProperty> FloatProperty( Cast< UFloatProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UFloatProperty >( SharedThis( this ), FloatProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UFloatProperty >( SharedThis( this ), FloatProperty ) );
		}
	}
	else if ( Property->IsA( UNameProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UNameProperty> NameProperty( Cast< UNameProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UNameProperty >( SharedThis( this ), NameProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UNameProperty >( SharedThis( this ), NameProperty ) );
		}
	}
	else if ( Property->IsA( UStrProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UStrProperty> StrProperty( Cast< UStrProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UStrProperty >( SharedThis( this ), StrProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UStrProperty >( SharedThis( this ), StrProperty ) );
		}
	}
	else if ( Property->IsA( UObjectProperty::StaticClass() ) )
	{
		TWeakObjectPtr<UObjectProperty> ObjectProperty( Cast< UObjectProperty >( Property ) );

		if ( SortMode == EColumnSortMode::Ascending )
		{
			Rows.Sort( FCompareRowByColumnAscending< UObjectProperty >( SharedThis( this ), ObjectProperty ) );
		}
		else
		{
			Rows.Sort( FCompareRowByColumnDescending< UObjectProperty >( SharedThis( this ), ObjectProperty ) );
		}
	}
	//else if ( Property->IsA( UTextProperty::StaticClass() ) )
	//{
	//	if ( SortMode == EColumnSortMode::Ascending )
	//	{
	//		Rows.Sort( FCompareRowByColumnAscending< UTextProperty >( SharedThis( this ) ) );
	//	}
	//	else
	//	{
	//		Rows.Sort( FCompareRowByColumnDescending< UTextProperty >( SharedThis( this ) ) );
	//	}
	//}
	else
	{
		check( false && "Cannot Sort Rows by this Column!" );
	}
}