FLinearColor SGraphPinColor::GetColor() const
{
	FString ColorString = GraphPinObj->GetDefaultAsString();
	FLinearColor PinColor;

	// Ensure value is sensible
	if (!PinColor.InitFromString(ColorString)) 
	{
		PinColor = FLinearColor::Black;
	}
	return PinColor;
}
void FColorStructCustomization::CreateColorPicker( bool bUseAlpha, bool bOnlyRefreshOnOk )
{
	int32 NumObjects = StructPropertyHandle->GetNumOuterObjects();

	SavedPreColorPickerColors.Empty();
	TArray<FString> PerObjectValues;
	StructPropertyHandle->GetPerObjectValues( PerObjectValues );

	for( int32 ObjectIndex = 0; ObjectIndex < NumObjects; ++ObjectIndex )
	{
		if( bIsLinearColor )
		{
			FLinearColor Color;
			Color.InitFromString( PerObjectValues[ObjectIndex] );
			SavedPreColorPickerColors.Add( Color );	
		}
		else
		{
			FColor Color;
			Color.InitFromString( PerObjectValues[ObjectIndex] );
			SavedPreColorPickerColors.Add( Color.ReinterpretAsLinear() );
		}
	}

	FLinearColor InitialColor;
	GetColorAsLinear(InitialColor);

	// This needs to be meta data.  Other colors could benefit from this
	const bool bRefreshOnlyOnOk = StructPropertyHandle->GetProperty()->GetOwnerClass()->IsChildOf(UMaterialExpressionConstant3Vector::StaticClass());

	FColorPickerArgs PickerArgs;
	PickerArgs.bUseAlpha = !bIgnoreAlpha;
	PickerArgs.bOnlyRefreshOnMouseUp = false;
	PickerArgs.bOnlyRefreshOnOk = bRefreshOnlyOnOk;
	PickerArgs.DisplayGamma = TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) );
	PickerArgs.OnColorCommitted = FOnLinearColorValueChanged::CreateSP( this, &FColorStructCustomization::OnSetColorFromColorPicker );
	PickerArgs.OnColorPickerCancelled = FOnColorPickerCancelled::CreateSP( this, &FColorStructCustomization::OnColorPickerCancelled );
	PickerArgs.OnInteractivePickBegin = FSimpleDelegate::CreateSP( this, &FColorStructCustomization::OnColorPickerInteractiveBegin );
	PickerArgs.OnInteractivePickEnd = FSimpleDelegate::CreateSP( this, &FColorStructCustomization::OnColorPickerInteractiveEnd );
	PickerArgs.InitialColorOverride = InitialColor;
	PickerArgs.ParentWidget = ColorPickerParentWidget;

	OpenColorPicker(PickerArgs);
}
TSharedRef<SColorPicker> FColorStructCustomization::CreateInlineColorPicker()
{
	int32 NumObjects = StructPropertyHandle->GetNumOuterObjects();

	SavedPreColorPickerColors.Empty();
	TArray<FString> PerObjectValues;
	StructPropertyHandle->GetPerObjectValues( PerObjectValues );

	for( int32 ObjectIndex = 0; ObjectIndex < NumObjects; ++ObjectIndex )
	{
		if( bIsLinearColor )
		{
			FLinearColor Color;
			Color.InitFromString( PerObjectValues[ObjectIndex] );
			SavedPreColorPickerColors.Add( Color );	
		}
		else
		{
			FColor Color;
			Color.InitFromString( PerObjectValues[ObjectIndex] );
			SavedPreColorPickerColors.Add( Color.ReinterpretAsLinear() );
		}
	}

	FLinearColor InitialColor;
	GetColorAsLinear(InitialColor);

	// This needs to be meta data.  Other colors could benefit from this
	const bool bRefreshOnlyOnOk = StructPropertyHandle->GetProperty()->GetOwnerClass()->IsChildOf(UMaterialExpressionConstant3Vector::StaticClass());
	
	return SNew(SColorPicker)
		.Visibility(this, &FColorStructCustomization::GetInlineColorPickerVisibility)
		.DisplayInlineVersion(true)
		.OnlyRefreshOnMouseUp(false)
		.OnlyRefreshOnOk(bRefreshOnlyOnOk)
		.DisplayGamma(TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) ))
		.OnColorCommitted(FOnLinearColorValueChanged::CreateSP( this, &FColorStructCustomization::OnSetColorFromColorPicker ))
		.OnColorPickerCancelled(FOnColorPickerCancelled::CreateSP( this, &FColorStructCustomization::OnColorPickerCancelled ))
		.OnInteractivePickBegin(FSimpleDelegate::CreateSP( this, &FColorStructCustomization::OnColorPickerInteractiveBegin ))
		.OnInteractivePickEnd(FSimpleDelegate::CreateSP( this, &FColorStructCustomization::OnColorPickerInteractiveEnd ))
		.TargetColorAttribute(InitialColor);
}
const TSharedPtr<FLinearColor> CollectionViewUtils::LoadColor(const FString& InCollectionName, const ECollectionShareType::Type& InCollectionType)
{
	check(InCollectionType != ECollectionShareType::CST_All);

	const FString ColorKeyStr = ToConfigKey(InCollectionName, InCollectionType);

	// See if we have a value cached first
	{
		TSharedPtr<FLinearColor>* const CachedColor = CollectionColors.Find(ColorKeyStr);
		if(CachedColor)
		{
			return *CachedColor;
		}
	}
		
	// Loads the color of collection at the given path from the config
	if(FPaths::FileExists(GEditorUserSettingsIni))
	{
		// Create a new entry from the config, skip if it's default
		FString ColorStr;
		if(GConfig->GetString(TEXT("CollectionColor"), *ColorKeyStr, ColorStr, GEditorUserSettingsIni))
		{
			FLinearColor Color;
			if(Color.InitFromString(ColorStr) && !Color.Equals(CollectionViewUtils::GetDefaultColor()))
			{
				return CollectionColors.Add(ColorKeyStr, MakeShareable(new FLinearColor(Color)));
			}
		}
		else
		{
			return CollectionColors.Add(ColorKeyStr, MakeShareable(new FLinearColor(CollectionViewUtils::GetDefaultColor())));
		}
	}

	return nullptr;
}
bool CollectionViewUtils::HasCustomColors( TArray< FLinearColor >* OutColors )
{
	if(!FPaths::FileExists(GEditorUserSettingsIni))
	{
		return false;
	}

	// Read individual entries from a config file.
	TArray<FString> Section;
	GConfig->GetSection(TEXT("CollectionColor"), Section, GEditorUserSettingsIni);

	bool bHasCustom = false;
	const FCollectionManagerModule& CollectionManagerModule = FModuleManager::Get().LoadModuleChecked<FCollectionManagerModule>("CollectionManager");
	const ICollectionManager& CollectionManager = CollectionManagerModule.Get();

	for(FString& EntryStr : Section)
	{
		EntryStr.Trim();

		FString ColorKeyStr;
		FString ColorStr;
		if(!EntryStr.Split("=", &ColorKeyStr, &ColorStr))
		{
			continue;
		}

		// Ignore any that have invalid or default colors
		FLinearColor CurrentColor;
		if(!CurrentColor.InitFromString(ColorStr) || CurrentColor.Equals(CollectionViewUtils::GetDefaultColor()))
		{
			continue;
		}

		// Ignore any that reference old collections
		FString CollectionName;
		ECollectionShareType::Type CollectionType;
		if(!FromConfigKey(ColorKeyStr, CollectionName, CollectionType) || !CollectionManager.CollectionExists(*CollectionName, CollectionType))
		{
			continue;
		}

		bHasCustom = true;
		if(OutColors)
		{
			// Only add if not already present (ignores near matches too)
			bool bAdded = false;
			for(const FLinearColor& Color : *OutColors)
			{
				if(CurrentColor.Equals(Color))
				{
					bAdded = true;
					break;
				}
			}
			if(!bAdded)
			{
				OutColors->Add(CurrentColor);
			}
		}
		else
		{
			break;
		}
	}

	return bHasCustom;
}