コード例 #1
1
bool FStructureEditorUtils::AddVariable(UBlueprint* Blueprint, FName StructName, const FEdGraphPinType& VarType)
{
	if (NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("AddVariable", "Add Variable") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if (StructureDesc)
		{
			FString ErrorMessage;
			if (!CanHaveAMemberVariableOfType(StructureDesc->CompiledStruct, VarType, &ErrorMessage))
			{
				UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
				return false;
			}

			const FName VarName = FMemberVariableNameHelper::Generate(StructureDesc->CompiledStruct, FString());
			check(NULL == StructureDesc->Fields.FindByPredicate(FFindByNameHelper(VarName)));
			const FString DisplayName = VarName.ToString();
			check(IsUniqueVariableDisplayName(Blueprint, StructName, DisplayName));

			FBPVariableDescription NewVar;
			NewVar.VarName = VarName;
			NewVar.FriendlyName = DisplayName;
			NewVar.VarType = VarType;
			NewVar.VarGuid = FGuid::NewGuid();
			StructureDesc->Fields.Add(NewVar);

			OnStructureChanged(*StructureDesc, Blueprint);
			return true;
		}
	}
	return false;
}
コード例 #2
0
bool FStructureEditorUtils::ChangeVariableType(UUserDefinedStruct* Struct, FGuid VarGuid, const FEdGraphPinType& NewType)
{
    if (Struct)
    {
        FString ErrorMessage;
        if(!CanHaveAMemberVariableOfType(Struct, NewType, &ErrorMessage))
        {
            UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
            return false;
        }

        auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
        if(VarDesc)
        {
            const bool bChangedType = (VarDesc->ToPinType() != NewType);
            if (bChangedType)
            {
                const FScopedTransaction Transaction(LOCTEXT("ChangeVariableType", "Change Variable Type"));
                ModifyStructData(Struct);

                VarDesc->VarName = FMemberVariableNameHelper::Generate(Struct, VarDesc->FriendlyName, VarDesc->VarGuid);
                VarDesc->DefaultValue = FString();
                VarDesc->SetPinType(NewType);

                OnStructureChanged(Struct);
                return true;
            }
        }
    }
    return false;
}
コード例 #3
0
bool FStructureEditorUtils::RenameVariable(UUserDefinedStruct* Struct, FGuid VarGuid, const FString& NewDisplayNameStr)
{
    if (Struct)
    {
        auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
        if (VarDesc
                && !NewDisplayNameStr.IsEmpty()
                && FName(*NewDisplayNameStr).IsValidXName(INVALID_OBJECTNAME_CHARACTERS)
                && IsUniqueVariableDisplayName(Struct, NewDisplayNameStr))
        {
            const FScopedTransaction Transaction(LOCTEXT("RenameVariable", "Rename Variable"));
            ModifyStructData(Struct);

            VarDesc->FriendlyName = NewDisplayNameStr;
            //>>> TEMPORARY it's more important to prevent changes in structs instances, than to have consistent names
            if (GetGuidFromPropertyName(VarDesc->VarName).IsValid())
                //<<< TEMPORARY
            {
                const FName NewName = FMemberVariableNameHelper::Generate(Struct, NewDisplayNameStr, VarGuid);
                check(NULL == GetVarDesc(Struct).FindByPredicate(FFindByNameHelper<FStructVariableDescription>(NewName)))
                VarDesc->VarName = NewName;
            }
            OnStructureChanged(Struct);
            return true;
        }
    }
    return false;
}
コード例 #4
0
bool FStructureEditorUtils::RemoveVariable(UUserDefinedStruct* Struct, FGuid VarGuid)
{
    if(Struct)
    {
        const auto OldNum = GetVarDesc(Struct).Num();
        const bool bAllowToMakeEmpty = false;
        if (bAllowToMakeEmpty || (OldNum > 1))
        {
            const FScopedTransaction Transaction(LOCTEXT("RemoveVariable", "Remove Variable"));
            ModifyStructData(Struct);

            GetVarDesc(Struct).RemoveAll(FFindByGuidHelper<FStructVariableDescription>(VarGuid));
            if (OldNum != GetVarDesc(Struct).Num())
            {
                OnStructureChanged(Struct);
                return true;
            }
        }
        else
        {
            UE_LOG(LogBlueprint, Log, TEXT("Member variable cannot be removed. User Defined Structure cannot be empty"));
        }
    }
    return false;
}
コード例 #5
0
bool FStructureEditorUtils::AddVariable(UUserDefinedStruct* Struct, const FEdGraphPinType& VarType)
{
    if (Struct)
    {
        const FScopedTransaction Transaction( LOCTEXT("AddVariable", "Add Variable") );
        ModifyStructData(Struct);

        FString ErrorMessage;
        if (!CanHaveAMemberVariableOfType(Struct, VarType, &ErrorMessage))
        {
            UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
            return false;
        }

        const FGuid Guid = FGuid::NewGuid();
        FString DisplayName;
        const FName VarName = FMemberVariableNameHelper::Generate(Struct, FString(), Guid, &DisplayName);
        check(NULL == GetVarDesc(Struct).FindByPredicate(FStructureEditorUtils::FFindByNameHelper<FStructVariableDescription>(VarName)));
        check(IsUniqueVariableDisplayName(Struct, DisplayName));

        FStructVariableDescription NewVar;
        NewVar.VarName = VarName;
        NewVar.FriendlyName = DisplayName;
        NewVar.SetPinType(VarType);
        NewVar.VarGuid = Guid;
        NewVar.bDontEditoOnInstance = false;
        NewVar.bInvalidMember = false;
        GetVarDesc(Struct).Add(NewVar);

        OnStructureChanged(Struct);
        return true;
    }
    return false;
}
コード例 #6
0
bool FStructureEditorUtils::ChangeMultiLineTextEnabled(UUserDefinedStruct* Struct, FGuid VarGuid, bool bIsEnabled)
{
	auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
	if (CanEnableMultiLineText(Struct, VarGuid) && VarDesc->bEnableMultiLineText != bIsEnabled)
	{
		const FScopedTransaction Transaction(LOCTEXT("ChangeMultiLineTextEnabled", "Change Multi-line Text Enabled"));
		ModifyStructData(Struct);

		VarDesc->bEnableMultiLineText = bIsEnabled;
		auto Property = FindField<UProperty>(Struct, VarDesc->VarName);
		if (Property)
		{
			if (VarDesc->bEnableMultiLineText)
			{
				Property->SetMetaData("MultiLine", TEXT("true"));
			}
			else
			{
				Property->RemoveMetaData("MultiLine");
			}
		}
		OnStructureChanged(Struct);
		return true;
	}
	return false;
}
コード例 #7
0
bool FStructureEditorUtils::ChangeVariableDefaultValue(UBlueprint* Blueprint, FName StructName, FGuid VarGuid, const FString& NewDefaultValue)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("ChangeVariableDefaultValue", "Change Variable Default Value") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if (StructureDesc)
		{
			const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
			FBPVariableDescription* VarDesc = StructureDesc->Fields.FindByPredicate(FFindByGuidHelper(VarGuid));
			if (VarDesc 
				&& (NewDefaultValue != VarDesc->DefaultValue) 
				&& K2Schema->DefaultValueSimpleValidation(VarDesc->VarType, FString(), NewDefaultValue, NULL, FText::GetEmpty()))
			{
				VarDesc->DefaultValue = NewDefaultValue;

				OnStructureChanged(*StructureDesc, Blueprint);
				return true;
			}
		}
	}
	return false;
}
コード例 #8
0
bool FStructureEditorUtils::ChangeVariableType(UBlueprint* Blueprint, FName StructName, FGuid VarGuid, const FEdGraphPinType& NewType)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("ChangeVariableType", "Change Variable Type") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if(StructureDesc)
		{
			FString ErrorMessage;
			if(!CanHaveAMemberVariableOfType(StructureDesc->CompiledStruct, NewType, &ErrorMessage))
			{
				UE_LOG(LogBlueprint, Warning, TEXT("%s"), *ErrorMessage);
				return false;
			}

			FBPVariableDescription* VarDesc = StructureDesc->Fields.FindByPredicate(FFindByGuidHelper(VarGuid));
			if(VarDesc && (NewType != VarDesc->VarType))
			{
				VarDesc->VarName = FMemberVariableNameHelper::Generate(StructureDesc->CompiledStruct, VarDesc->FriendlyName);
				VarDesc->DefaultValue = FString();
				VarDesc->VarType = NewType;

				OnStructureChanged(*StructureDesc, Blueprint);
				return true;
			}
		}
	}
	return false;
}
コード例 #9
0
bool FStructureEditorUtils::RenameVariable(UBlueprint* Blueprint, FName StructName, FGuid VarGuid, const FString& NewDisplayNameStr)
{
	if (NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("RenameVariable", "Rename Variable") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if (StructureDesc)
		{
			const FName NewNameBase(*NewDisplayNameStr);
			if (NewNameBase.IsValidXName(INVALID_OBJECTNAME_CHARACTERS) &&
				IsUniqueVariableDisplayName(Blueprint, StructName, NewDisplayNameStr))
			{
				const FName NewName = FMemberVariableNameHelper::Generate(StructureDesc->CompiledStruct, NewDisplayNameStr);
				if (NULL == StructureDesc->Fields.FindByPredicate(FFindByNameHelper(NewName)))
				{
					FBPVariableDescription* VarDesc = StructureDesc->Fields.FindByPredicate(FFindByGuidHelper(VarGuid));
					if (VarDesc)
					{
						VarDesc->FriendlyName = NewDisplayNameStr;
						VarDesc->VarName = NewName;
						OnStructureChanged(*StructureDesc, Blueprint);
						return true;
					}
				}
			}
		}
	}
	return false;
}
コード例 #10
0
bool FStructureEditorUtils::ChangeVariableDefaultValue(UUserDefinedStruct* Struct, FGuid VarGuid, const FString& NewDefaultValue)
{
	auto ValidateDefaultValue = [](const FStructVariableDescription& VarDesc, const FString& InNewDefaultValue) -> bool
	{
		const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
		const FEdGraphPinType PinType = VarDesc.ToPinType();

		bool bResult = false;
		//TODO: validation for values, that are not passed by string
		if (PinType.PinCategory == K2Schema->PC_Text)
		{
			bResult = true;
		}
		else if ((PinType.PinCategory == K2Schema->PC_Object) 
			|| (PinType.PinCategory == K2Schema->PC_Interface) 
			|| (PinType.PinCategory == K2Schema->PC_Class)
			|| (PinType.PinCategory == K2Schema->PC_AssetClass)
			|| (PinType.PinCategory == K2Schema->PC_Asset))
		{
			// K2Schema->DefaultValueSimpleValidation finds an object, passed by path, invalid
			bResult = true;
		}
		else
		{
			bResult = K2Schema->DefaultValueSimpleValidation(PinType, FString(), InNewDefaultValue, NULL, FText::GetEmpty());
		}
		return bResult;
	};

	auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
	if (VarDesc 
		&& (NewDefaultValue != VarDesc->DefaultValue)
		&& ValidateDefaultValue(*VarDesc, NewDefaultValue))
	{
		bool bAdvancedValidation = true;
		if (!NewDefaultValue.IsEmpty())
		{
			const auto Property = FindField<UProperty>(Struct, VarDesc->VarName);
			FStructOnScope StructDefaultMem(Struct);
			bAdvancedValidation = StructDefaultMem.IsValid() && Property &&
				FBlueprintEditorUtils::PropertyValueFromString(Property, NewDefaultValue, StructDefaultMem.GetStructMemory());
		}

		if (bAdvancedValidation)
		{
			const FScopedTransaction Transaction(LOCTEXT("ChangeVariableDefaultValue", "Change Variable Default Value"));
			
			TGuardValue<FStructureEditorUtils::EStructureEditorChangeInfo> ActiveChangeGuard(FStructureEditorUtils::FStructEditorManager::ActiveChange, EStructureEditorChangeInfo::DefaultValueChanged);

			ModifyStructData(Struct);
			
			VarDesc->DefaultValue = NewDefaultValue;
			OnStructureChanged(Struct, EStructureEditorChangeInfo::DefaultValueChanged);
			return true;
		}
	}
	return false;
}
コード例 #11
0
bool FStructureEditorUtils::ChangeEditableOnBPInstance(UUserDefinedStruct* Struct, FGuid VarGuid, bool bInIsEditable)
{
    const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
    auto VarDesc = GetVarDescByGuid(Struct, VarGuid);
    const bool bNewDontEditoOnInstance = !bInIsEditable;
    if (VarDesc && (bNewDontEditoOnInstance != VarDesc->bDontEditoOnInstance))
    {
        const FScopedTransaction Transaction(LOCTEXT("ChangeVariableOnBPInstance", "Change variable editable on BP instance"));
        ModifyStructData(Struct);

        VarDesc->bDontEditoOnInstance = bNewDontEditoOnInstance;
        OnStructureChanged(Struct);
        return true;
    }
    return false;
}
コード例 #12
0
bool FStructureEditorUtils::AddStructure(UBlueprint* Blueprint)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("AddStructure", "Add Structure") );
		Blueprint->Modify();

		const FName StructName = MakeUniqueStructName(Blueprint, TEXT("NewStruct"));
		FBPStructureDescription StructureDesc;
		StructureDesc.Name = StructName;

		Blueprint->UserDefinedStructures.Add(StructureDesc);
		OnStructureChanged(StructureDesc, Blueprint);

		return true;
	}
	return false;
}
コード例 #13
0
bool FStructureEditorUtils::RemoveVariable(UBlueprint* Blueprint, FName StructName, FGuid VarGuid)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("RemoveVariable", "Remove Variable") );
		Blueprint->Modify();

		FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if(StructureDesc)
		{
			const auto OldNum = StructureDesc->Fields.Num();
			StructureDesc->Fields.RemoveAll(FFindByGuidHelper(VarGuid));
			if(OldNum != StructureDesc->Fields.Num())
			{
				OnStructureChanged(*StructureDesc, Blueprint);
				return true;
			}
		}
	}
	return false;
}
コード例 #14
0
bool FStructureEditorUtils::MoveVariable(UUserDefinedStruct* Struct, FGuid VarGuid, EMoveDirection MoveDirection)
{
    if (Struct)
    {
        const bool bMoveUp = (EMoveDirection::MD_Up == MoveDirection);
        auto& DescArray = GetVarDesc(Struct);
        const int32 InitialIndex = bMoveUp ? 1 : 0;
        const int32 IndexLimit = DescArray.Num() - (bMoveUp ? 0 : 1);
        for (int32 Index = InitialIndex; Index < IndexLimit; ++Index)
        {
            if (DescArray[Index].VarGuid == VarGuid)
            {
                const FScopedTransaction Transaction(LOCTEXT("ReorderVariables", "Varaibles reordered"));
                ModifyStructData(Struct);

                DescArray.Swap(Index, Index + (bMoveUp ? -1 : 1));
                OnStructureChanged(Struct);
                return true;
            }
        }
    }
    return false;
}
コード例 #15
0
bool FStructureEditorUtils::DuplicateStructure(UBlueprint* Blueprint, FName StructName)
{
	if(NULL != Blueprint)
	{
		const FScopedTransaction Transaction( LOCTEXT("RemoveStructure", "Remove Structure") );
		Blueprint->Modify();

		const FBPStructureDescription* StructureDesc = Blueprint->UserDefinedStructures.FindByPredicate(FFindByNameHelper(StructName));
		if (StructureDesc)
		{
			FBPStructureDescription NewStructureDesc(*StructureDesc);
			NewStructureDesc.CompiledStruct = NULL;
			NewStructureDesc.Name = MakeUniqueStructName(Blueprint, StructureDesc->Name.ToString());

			Blueprint->UserDefinedStructures.Add(NewStructureDesc);
			OnStructureChanged(NewStructureDesc, Blueprint);

			return true;
		}
	}

	return false;
}