Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
!TemplateAssetFactory
Id: A3F2E1D4-7B6C-4A9E-8D3F-1C5B2E4F7A90
AssetTypeName: ColorPaletteAsset
Name: Color Palette
Scope: Asset
Description: A custom color palette for the GameStudio color picker. Import from a .gpl file or define colors manually.
Group: Rendering
DefaultOutputName: ColorPalette
19 changes: 19 additions & 0 deletions sources/editor/Stride.Core.Assets.Editor/ViewModel/ColorPalette.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System.Collections.Generic;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Core.Serialization;
using Stride.Core.Serialization.Contents;

namespace Stride.Core.Assets.Editor.ViewModel
{
[DataContract]
[ContentSerializer(typeof(DataContentSerializerWithReuse<ColorPalette>))]
[ReferenceSerializer, DataSerializerGlobal(typeof(ReferenceSerializer<ColorPalette>), Profile = "Content")]
public class ColorPalette
{
public Dictionary<string, Color3> Colors { get; set; } = new Dictionary<string, Color3>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System.Collections.Generic;
using System.Threading.Tasks;
using Stride.Core;
using Stride.Core.Assets;
using Stride.Core.Assets.Compiler;
using Stride.Core.BuildEngine;
using Stride.Core.Mathematics;
using Stride.Core.Serialization.Contents;

namespace Stride.Core.Assets.Editor.ViewModel
{
[AssetDescription(FileExtension, AllowArchetype = false)]
[AssetContentType(typeof(ColorPalette))]
[AssetFormatVersion("Stride", CurrentVersion, "1.0.0.0")]
public sealed class ColorPaletteAsset : Asset
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the first time we ever have an asset defined within an editor library. I'm not 100% sure it will work properly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is missing a [DataContract] attribute.

{
private const string CurrentVersion = "1.0.0.0";
public const string FileExtension = ".sdpalette";
public string SourceFile { get; set; } = string.Empty;
public Dictionary<string, Color3> Colors { get; set; } = new Dictionary<string, Color3>();
}

[AssetCompiler(typeof(ColorPaletteAsset), typeof(AssetCompilationContext))]
public sealed class ColorPaletteCompiler : AssetCompilerBase
{
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem,
string targetUrlInStorage, AssetCompilerResult result)
{
var asset = (ColorPaletteAsset)assetItem.Asset;
result.BuildSteps = new AssetBuildStep(assetItem);
result.BuildSteps.Add(new ColorPaletteCommand(targetUrlInStorage, asset, assetItem.Package));
}

private class ColorPaletteCommand : AssetCommand<ColorPaletteAsset>
{
public ColorPaletteCommand(string url, ColorPaletteAsset parameters, IAssetFinder assetFinder)
: base(url, parameters, assetFinder) { }

protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
{
var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService);

Dictionary<string, Color3> colors;

if (!string.IsNullOrWhiteSpace(Parameters.SourceFile))
{
colors = GplPaletteParser.TryParse(Parameters.SourceFile)
?? Parameters.Colors;
}
else
{
colors = Parameters.Colors;
}

var runtime = new ColorPalette { Colors = colors };
assetManager.Save(Url, runtime);

return Task.FromResult(ResultStatus.Successful);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System.Collections.Generic;

using System.Collections.Generic;
using Stride.Core.Mathematics;

namespace Stride.Core.Assets.Editor.ViewModel
{
public static class ColorPaletteViewModel
{
public static Dictionary<string, Color3> Colors = new Dictionary<string, Color3>
public static readonly Dictionary<string, Color3> DefaultColors = new Dictionary<string, Color3>
{
{ "Silver", new Color3(0.98695203f, 0.981576133f, 0.960581067f) },
{ "Silver", new Color3(0.98695203f, 0.981576133f, 0.960581067f) },
{ "Aluminium", new Color3(0.959559115f, 0.963518888f, 0.964957682f) },
{ "Gold", new Color3(1.0f, 0.88565079f, 0.609162496f) },
{ "Copper", new Color3(0.979292159f, 0.814900815f, 0.754550145f) },
{ "Chromium", new Color3(0.761787833f, 0.765888197f, 0.764724015f) },
{ "Nickel", new Color3(0.827766422f, 0.797984931f, 0.74652364f) },
{ "Titanium", new Color3(0.756946965f, 0.727607463f, 0.695207239f) },
{ "Cobalt", new Color3(0.829103572f, 0.824958926f, 0.812750243f) },
{ "Platimium", new Color3(0.834934076f, 0.814845027f, 0.783999116f) },
{ "Gold", new Color3(1.0f, 0.88565079f, 0.609162496f) },
{ "Copper", new Color3(0.979292159f, 0.814900815f, 0.754550145f) },
{ "Chromium", new Color3(0.761787833f, 0.765888197f, 0.764724015f) },
{ "Nickel", new Color3(0.827766422f, 0.797984931f, 0.74652364f) },
{ "Titanium", new Color3(0.756946965f, 0.727607463f, 0.695207239f) },
{ "Cobalt", new Color3(0.829103572f, 0.824958926f, 0.812750243f) },
{ "Platinum", new Color3(0.834934076f, 0.814845027f, 0.783999116f) },
};

private static Dictionary<string, Color3>? _colors;

public static Dictionary<string, Color3> Colors
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XAML binding to this property won't work as it is a static binding. If the Dictionary is meant to be modified, then:

  • the class must derive from ViewModelbase
  • the property must raise the PropertyChanged event upon changes
  • we need to use an observable collection instead of a dictionary (in such case we can change it to a collection of a tuple of string and Color3).

{
get
{
if (_colors is null)
_colors = DefaultColors;
return _colors;
}
}

public static void SetPalette(ColorPalette? palette)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is never called.

{
_colors = palette?.Colors ?? DefaultColors;
}

public static void ResetToDefault() => _colors = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;

using Stride.Core.Mathematics;

namespace Stride.Core.Assets.Editor.ViewModel
{
public static class GplPaletteParser
{
public static Dictionary<string, Color3>? TryParse(string filePath)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expected signature for TryParse method is bool TryParse(string filePath, out Dictionary<string, Color3>? colors). Taking into account nullability annotation:

bool TryParse(string filePath, [NotNullWhen(true)] out Dictionary<string, Color3>? colors)

{
if (!File.Exists(filePath))
return null;

var colors = new Dictionary<string, Color3>();

try
{
var lines = File.ReadAllLines(filePath);

if (lines.Length == 0 || !lines[0].Trim().Equals("GIMP Palette", StringComparison.OrdinalIgnoreCase))
return null;

int index = 1;
int unnamedIndex = 1;

for (; index < lines.Length; index++)
{
var line = lines[index].Trim();

if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#") || line.StartsWith("Name:") || line.StartsWith("Columns:"))
continue;

var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

if (parts.Length < 3)
continue;

if (!byte.TryParse(parts[0], out byte r) ||
!byte.TryParse(parts[1], out byte g) ||
!byte.TryParse(parts[2], out byte b))
continue;

var name = parts.Length >= 4
? string.Join(" ", parts, 3, parts.Length - 3).Trim()
: $"Color {unnamedIndex++}";

var key = name;
int suffix = 2;
while (colors.ContainsKey(key))
key = $"{name} {suffix++}";

colors[key] = new Color3(r / 255f, g / 255f, b / 255f);
}

return colors.Count > 0 ? colors : null;
}
catch (Exception)
{
return null;
}
}
}
}
Loading