diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 00c4b7a28..de5d77946 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -164,6 +164,7 @@
+
diff --git a/src/Artemis.Core/JsonConverters/SKColorConverter.cs b/src/Artemis.Core/JsonConverters/SKColorConverter.cs
new file mode 100644
index 000000000..d3fe0f69e
--- /dev/null
+++ b/src/Artemis.Core/JsonConverters/SKColorConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using Newtonsoft.Json;
+using SkiaSharp;
+
+namespace Artemis.Core.JsonConverters
+{
+ public class SKColorConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer)
+ {
+ writer.WriteValue(value.ToString());
+ }
+
+ public override SKColor ReadJson(JsonReader reader, Type objectType, SKColor existingValue, bool hasExistingValue, JsonSerializer serializer)
+ {
+ if (reader.Value is string value && !string.IsNullOrWhiteSpace(value))
+ {
+ return SKColor.Parse(value);
+ }
+
+ return SKColor.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index f784b2c65..606f5ccb3 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Artemis.Core.Events;
using Artemis.Core.Exceptions;
+using Artemis.Core.JsonConverters;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Services.Interfaces;
using Artemis.Core.Services.Storage.Interfaces;
+using Newtonsoft.Json;
using RGB.NET.Core;
using Serilog;
using SkiaSharp;
@@ -36,9 +38,18 @@ namespace Artemis.Core.Services
_pluginService.PluginEnabled += (sender, args) => _modules = _pluginService.GetPluginsOfType();
_pluginService.PluginDisabled += (sender, args) => _modules = _pluginService.GetPluginsOfType();
+ ConfigureJsonConvert();
Task.Run(Initialize);
}
+ private void ConfigureJsonConvert()
+ {
+ JsonConvert.DefaultSettings = () => new JsonSerializerSettings
+ {
+ Converters = new List { new SKColorConverter() }
+ };
+ }
+
public void Dispose()
{
// Dispose services
diff --git a/src/Artemis.Core/Services/LayerService.cs b/src/Artemis.Core/Services/LayerService.cs
index 3ad30d676..cc8211dc3 100644
--- a/src/Artemis.Core/Services/LayerService.cs
+++ b/src/Artemis.Core/Services/LayerService.cs
@@ -8,16 +8,19 @@ using Artemis.Core.Services.Interfaces;
using Newtonsoft.Json;
using Ninject;
using Ninject.Parameters;
+using Serilog;
namespace Artemis.Core.Services
{
public class LayerService : ILayerService
{
private readonly IKernel _kernel;
+ private readonly ILogger _logger;
- public LayerService(IKernel kernel)
+ public LayerService(IKernel kernel, ILogger logger)
{
_kernel = kernel;
+ _logger = logger;
}
public LayerElement InstantiateLayerElement(Layer layer, LayerElementDescriptor layerElementDescriptor, string settings, Guid? guid)
@@ -42,7 +45,19 @@ namespace Artemis.Core.Services
$"Settings where provided but layer element of type {layerElementDescriptor.LayerElementType.Name} has no Settings property."
);
}
- settingsInstance = JsonConvert.DeserializeObject(settings, settingsType);
+
+ try
+ {
+ settingsInstance = JsonConvert.DeserializeObject(settings, settingsType);
+ }
+ catch (JsonSerializationException e)
+ {
+ _logger.Warning(e, "Failed to deserialize settings for layer type {type}, resetting element settings - Plugin info: {pluginInfo}",
+ layerElementDescriptor.LayerElementType.Name,
+ layerElementDescriptor.LayerElementProvider.PluginInfo);
+
+ settingsInstance = Activator.CreateInstance(settingsType);
+ }
}
// If no settings found, provide a fresh instance of the settings type
else if (settingsType != null)
diff --git a/src/Artemis.Plugins.LayerElements.Noise/Artemis.Plugins.LayerElements.Noise.csproj b/src/Artemis.Plugins.LayerElements.Noise/Artemis.Plugins.LayerElements.Noise.csproj
index 811d6582c..8b2af9e34 100644
--- a/src/Artemis.Plugins.LayerElements.Noise/Artemis.Plugins.LayerElements.Noise.csproj
+++ b/src/Artemis.Plugins.LayerElements.Noise/Artemis.Plugins.LayerElements.Noise.csproj
@@ -100,6 +100,10 @@
Artemis.Core
False
+
+ {adb357e6-151d-4d0d-87cb-68fd0bc29812}
+ Artemis.UI.Shared
+
diff --git a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
index 8d128de48..3160b907b 100644
--- a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
+++ b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElement.cs
@@ -44,9 +44,10 @@ namespace Artemis.Plugins.LayerElements.Noise
// Scale down the render path to avoid computing a value for every pixel
var width = (int) (Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
var height = (int) (Math.Max(Layer.RenderRectangle.Width, Layer.RenderRectangle.Height) / Scale);
-
+ var opacity = (float) Math.Round(Settings.Color.Alpha / 255.0, 2, MidpointRounding.AwayFromZero);
using (var bitmap = new SKBitmap(new SKImageInfo(width, height)))
{
+ bitmap.Erase(new SKColor(0, 0, 0, 0));
// Only compute pixels inside LEDs, due to scaling there may be some rounding issues but it's neglect-able
foreach (var artemisLed in Layer.Leds)
{
@@ -60,13 +61,20 @@ namespace Artemis.Plugins.LayerElements.Noise
for (var y = yStart; y < yEnd; y++)
{
var v = _noise.Evaluate(Settings.XScale * x / width, Settings.YScale * y / height, _z);
- bitmap.SetPixel((int) x, (int) y, new SKColor(0, 0, 0, (byte) ((v + 1) * 127)));
+ var alpha = (byte) ((v + 1) * 127 * opacity);
+ // There's some fun stuff we can do here, like creating hard lines
+ // if (alpha > 128)
+ // alpha = 255;
+ // else
+ // alpha = 0;
+ var color = new SKColor(Settings.Color.Red, Settings.Color.Green, Settings.Color.Blue, alpha);
+ bitmap.SetPixel((int) x, (int) y, color);
}
}
}
using (var sh = SKShader.CreateBitmap(bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror, SKMatrix.MakeScale(Scale, Scale)))
- using (var paint = new SKPaint {Shader = sh})
+ using (var paint = new SKPaint {Shader = sh, BlendMode = Settings.BlendMode})
{
canvas.DrawPath(framePath, paint);
}
diff --git a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementSettings.cs b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementSettings.cs
index bee90789f..cbe481616 100644
--- a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementSettings.cs
+++ b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementSettings.cs
@@ -5,18 +5,31 @@ namespace Artemis.Plugins.LayerElements.Noise
{
public class NoiseLayerElementSettings : LayerElementSettings
{
+ private float _animationSpeed;
private SKBlendMode _blendMode;
+ private SKColor _color;
private float _xScale;
private float _yScale;
- private float _animationSpeed;
-
-
+
public NoiseLayerElementSettings()
{
- BlendMode = SKBlendMode.Color;
- XScale = 0.5f;
- YScale = 0.5f;
- AnimationSpeed = 50f;
+// Color = new SKColor(0, 0, 0);
+// BlendMode = SKBlendMode.Color;
+// XScale = 0.5f;
+// YScale = 0.5f;
+// AnimationSpeed = 50f;
+ }
+
+ public SKColor Color
+ {
+ get => _color;
+ set => SetAndNotify(ref _color, value);
+ }
+
+ public SKBlendMode BlendMode
+ {
+ get => _blendMode;
+ set => SetAndNotify(ref _blendMode, value);
}
public float XScale
@@ -36,11 +49,5 @@ namespace Artemis.Plugins.LayerElements.Noise
get => _animationSpeed;
set => SetAndNotify(ref _animationSpeed, value);
}
-
- public SKBlendMode BlendMode
- {
- get => _blendMode;
- set => SetAndNotify(ref _blendMode, value);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementView.xaml b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementView.xaml
index 4e37292d2..2123a0c1c 100644
--- a/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementView.xaml
+++ b/src/Artemis.Plugins.LayerElements.Noise/NoiseLayerElementView.xaml
@@ -3,19 +3,18 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:noiseLayer="clr-namespace:Artemis.Plugins.LayerElements.Noise"
+ xmlns:artemis="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
+ xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type noiseLayer:NoiseLayerElementViewModel}}">
-
-
-
+
@@ -29,6 +28,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -38,17 +55,21 @@
-
- Blend mode
- Affects how the noise is rendered on the rest of the layer
+
+
+
+
+
+
+
+ SelectedValue="{Binding LayerElement.Settings.BlendMode}" />
@@ -62,11 +83,13 @@
-
- X Scale
+
+
+
+
-
+
@@ -81,11 +104,13 @@
-
- Y Scale
+
+
+
+
-
+
@@ -100,11 +125,14 @@
-
- Animation speed
+
+
+
+
-
+
+
diff --git a/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj b/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
index af8d5a9fa..c7accaf55 100644
--- a/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
+++ b/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
@@ -82,7 +82,6 @@
-
diff --git a/src/Artemis.Plugins.Modules.General/ColorHelpers.cs b/src/Artemis.Plugins.Modules.General/ColorHelpers.cs
deleted file mode 100644
index df07d6012..000000000
--- a/src/Artemis.Plugins.Modules.General/ColorHelpers.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace Artemis.Plugins.Modules.General
-{
- public static class ColorHelpers
- {
- private static readonly Random Rand = new Random();
-
- public static int GetRandomHue()
- {
- return Rand.Next(0, 360);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Artemis.Plugins.Modules.General/GeneralModule.cs
index 8d91df18a..c807b6878 100644
--- a/src/Artemis.Plugins.Modules.General/GeneralModule.cs
+++ b/src/Artemis.Plugins.Modules.General/GeneralModule.cs
@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
-using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.Models;
-using Artemis.Core.Services.Storage.Interfaces;
using Artemis.Plugins.Modules.General.ViewModels;
-using SkiaSharp;
namespace Artemis.Plugins.Modules.General
{
@@ -13,31 +10,15 @@ namespace Artemis.Plugins.Modules.General
{
private readonly PluginSettings _settings;
- public GeneralModule(PluginInfo pluginInfo, PluginSettings settings, ISurfaceService surfaceService) : base(pluginInfo)
+ public GeneralModule(PluginInfo pluginInfo, PluginSettings settings) : base(pluginInfo)
{
_settings = settings;
DisplayName = "General";
ExpandsMainDataModel = true;
- DeviceShaders = new Dictionary();
- RainbowColors = new List();
- for (var i = 0; i < 9; i++)
- {
- if (i != 8)
- RainbowColors.Add(SKColor.FromHsv(i * 32, 100, 100));
- else
- RainbowColors.Add(SKColor.FromHsv(0, 100, 100));
- }
-
- surfaceService.SurfaceConfigurationUpdated += (sender, args) => DeviceShaders.Clear();
var testSetting = _settings.GetSetting("TestSetting", DateTime.Now);
}
- public int MovePercentage { get; set; }
-
- public Dictionary DeviceShaders { get; set; }
- public List RainbowColors { get; set; }
-
public override void EnablePlugin()
{
}
@@ -46,59 +27,6 @@ namespace Artemis.Plugins.Modules.General
{
}
- public override void Update(double deltaTime)
- {
- MovePercentage++;
- if (MovePercentage > 100)
- MovePercentage = 0;
-
- base.Update(deltaTime);
- }
-
-
- public override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas)
- {
- base.Render(deltaTime, surface, canvas);
- return;
-
- foreach (var device in surface.Devices)
- {
- using (var bitmap = new SKBitmap(new SKImageInfo((int) device.RenderRectangle.Width, (int) device.RenderRectangle.Height)))
- {
- using (var layerCanvas = new SKCanvas(bitmap))
- {
- layerCanvas.Clear();
- SKShader shader;
- if (DeviceShaders.ContainsKey(device))
- shader = DeviceShaders[device];
- else
- {
- shader = SKShader.CreateLinearGradient(
- new SKPoint(0, 0),
- new SKPoint(device.RenderRectangle.Width, 0),
- RainbowColors.ToArray(),
- null,
- SKShaderTileMode.Clamp);
- DeviceShaders.Add(device, shader);
- }
-
- using (var paint = new SKPaint {Shader = shader, FilterQuality = SKFilterQuality.Low})
- {
- layerCanvas.DrawRect(0, 0, device.RenderRectangle.Width, device.RenderRectangle.Height, paint);
- }
- }
-
- using (var bitmapShader = SKShader.CreateBitmap(bitmap, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat))
- using (var translated = SKShader.CreateLocalMatrix(bitmapShader, SKMatrix.MakeTranslation(device.RenderRectangle.Width / 100 * MovePercentage * -1, 0)))
- using (var translatedPaint = new SKPaint {Shader = translated, FilterQuality = SKFilterQuality.Low})
- {
- // Here we can let each module modify the shader as needed
- canvas.DrawRect(device.RenderRectangle, translatedPaint);
- }
- }
- }
- }
-
public override IEnumerable GetViewModels()
{
return new List {new GeneralViewModel(this)};
diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj
new file mode 100644
index 000000000..e27d3449d
--- /dev/null
+++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj
@@ -0,0 +1,127 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}
+ library
+ Artemis.UI.Shared
+ Artemis.UI.Shared
+ v4.7.2
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\MaterialDesignColors.1.2.0\lib\net45\MaterialDesignColors.dll
+
+
+ ..\packages\MaterialDesignThemes.2.6.0\lib\net45\MaterialDesignThemes.Wpf.dll
+
+
+ ..\packages\SkiaSharp.1.68.1\lib\net45\SkiaSharp.dll
+
+
+
+ ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll
+
+
+
+ ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll
+
+
+
+ ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ ColorPicker.xaml
+
+
+
+
+
+ UserControl1.xaml
+ Code
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Controls/ColorPicker.xaml b/src/Artemis.UI.Shared/ColorPicker.xaml
similarity index 62%
rename from src/Artemis.UI/Controls/ColorPicker.xaml
rename to src/Artemis.UI.Shared/ColorPicker.xaml
index 13fe03f15..05e8a582a 100644
--- a/src/Artemis.UI/Controls/ColorPicker.xaml
+++ b/src/Artemis.UI.Shared/ColorPicker.xaml
@@ -1,19 +1,23 @@
-
+
+
-
+
+
+
-
+
@@ -22,10 +26,10 @@
-
-
-
-
+
+
+
+
@@ -42,18 +46,13 @@
-
-
+
+
-
+
@@ -78,7 +77,8 @@
OverridesDefaultStyle="True"
Template="{StaticResource MaterialDesignColorSliderThumb}">
-
+
@@ -88,47 +88,46 @@
-
+
+ Text="{Binding Color, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource ColorToStringConverter}}"
+ MinWidth="95"
+ Padding="0 0 10 0"
+ HorizontalAlignment="Stretch" />
-
+
-
+
-
-
+ IsOpen="{Binding PopupOpen, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
+
-
+
+ Value="{Binding ColorOpacity, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+ Maximum="255" />
-
+
-
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/ColorPicker.xaml.cs b/src/Artemis.UI.Shared/ColorPicker.xaml.cs
new file mode 100644
index 000000000..a0e6e3a35
--- /dev/null
+++ b/src/Artemis.UI.Shared/ColorPicker.xaml.cs
@@ -0,0 +1,119 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace Artemis.UI.Shared
+{
+ ///
+ /// Interaction logic for ColorPicker.xaml
+ ///
+ public partial class ColorPicker : UserControl, INotifyPropertyChanged
+ {
+ public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(nameof(Color), typeof(Color), typeof(ColorPicker),
+ new FrameworkPropertyMetadata(default(Color), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorPropertyChangedCallback));
+
+ public static readonly DependencyProperty PopupOpenProperty = DependencyProperty.Register(nameof(PopupOpen), typeof(bool), typeof(ColorPicker),
+ new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PopupOpenPropertyChangedCallback));
+
+
+ internal static readonly DependencyProperty ColorOpacityProperty = DependencyProperty.Register(nameof(ColorOpacity), typeof(byte), typeof(ColorPicker),
+ new FrameworkPropertyMetadata((byte) 255, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorOpacityPropertyChangedCallback));
+
+ public static readonly RoutedEvent ColorChangedEvent =
+ EventManager.RegisterRoutedEvent(
+ nameof(Color),
+ RoutingStrategy.Bubble,
+ typeof(RoutedPropertyChangedEventHandler),
+ typeof(ColorPicker));
+
+ public static readonly RoutedEvent PopupOpenChangedEvent =
+ EventManager.RegisterRoutedEvent(
+ nameof(PopupOpen),
+ RoutingStrategy.Bubble,
+ typeof(RoutedPropertyChangedEventHandler),
+ typeof(ColorPicker));
+
+ private bool _inCallback;
+
+ public ColorPicker()
+ {
+ InitializeComponent();
+ }
+
+ public Color Color
+ {
+ get => (Color) GetValue(ColorProperty);
+ set => SetValue(ColorProperty, value);
+ }
+
+ public bool PopupOpen
+ {
+ get => (bool) GetValue(PopupOpenProperty);
+ set => SetValue(PopupOpenProperty, value);
+ }
+
+ internal byte ColorOpacity
+ {
+ get => (byte) GetValue(ColorOpacityProperty);
+ set => SetValue(ColorOpacityProperty, value);
+ }
+
+ private static void ColorPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var colorPicker = (ColorPicker) d;
+ if (colorPicker._inCallback)
+ return;
+
+ colorPicker._inCallback = true;
+
+ colorPicker.SetCurrentValue(ColorOpacityProperty, ((Color) e.NewValue).A);
+ colorPicker.OnPropertyChanged(nameof(Color));
+
+ colorPicker._inCallback = false;
+ }
+
+ private static void PopupOpenPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var colorPicker = (ColorPicker) d;
+ if (colorPicker._inCallback)
+ return;
+
+ colorPicker._inCallback = true;
+ colorPicker.OnPropertyChanged(nameof(PopupOpen));
+ colorPicker._inCallback = false;
+ }
+
+ private static void ColorOpacityPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var colorPicker = (ColorPicker) d;
+ if (colorPicker._inCallback)
+ return;
+
+ colorPicker._inCallback = true;
+
+ var color = colorPicker.Color;
+ if (e.NewValue is byte opacity)
+ color = Color.FromArgb(opacity, color.R, color.G, color.B);
+ colorPicker.SetCurrentValue(ColorProperty, color);
+ colorPicker.OnPropertyChanged(nameof(ColorOpacity));
+
+ colorPicker._inCallback = false;
+ }
+
+ private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
+ {
+ PopupOpen = !PopupOpen;
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Converters/ColorToSKColorConverter.cs b/src/Artemis.UI.Shared/Converters/ColorToSKColorConverter.cs
new file mode 100644
index 000000000..372ed8fa4
--- /dev/null
+++ b/src/Artemis.UI.Shared/Converters/ColorToSKColorConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+using SkiaSharp;
+
+namespace Artemis.UI.Shared.Converters
+{
+ ///
+ ///
+ /// Converts into a .
+ ///
+ [ValueConversion(typeof(Color), typeof(SKColor))]
+ public class SKColorToColorConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var skColor = (SKColor) value;
+ return Color.FromArgb(skColor.Alpha, skColor.Red, skColor.Green, skColor.Blue);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var color = (Color) value;
+ return new SKColor(color.R, color.G, color.B, color.A);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Converters/ColorToSolidColorConverter.cs b/src/Artemis.UI.Shared/Converters/ColorToSolidColorConverter.cs
new file mode 100644
index 000000000..570412502
--- /dev/null
+++ b/src/Artemis.UI.Shared/Converters/ColorToSolidColorConverter.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace Artemis.UI.Shared.Converters
+{
+ ///
+ ///
+ /// Converts into a with full opacity.
+ ///
+ [ValueConversion(typeof(Color), typeof(string))]
+ internal class ColorToSolidColorConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var color = (Color) value;
+ return Color.FromRgb(color.R, color.G, color.B);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Converters/ColorToStringConverter.cs b/src/Artemis.UI.Shared/Converters/ColorToStringConverter.cs
new file mode 100644
index 000000000..e01ac78a3
--- /dev/null
+++ b/src/Artemis.UI.Shared/Converters/ColorToStringConverter.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace Artemis.UI.Shared.Converters
+{
+ ///
+ ///
+ /// Converts into .
+ ///
+ [ValueConversion(typeof(Color), typeof(string))]
+ internal class ColorToStringConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value?.ToString();
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace((string) value))
+ return default(Color);
+
+ var color = ColorConverter.ConvertFromString((string) value);
+ if (color is Color c)
+ return c;
+
+ return default(Color);
+ }
+ catch (FormatException)
+ {
+ return default(Color);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Properties/AssemblyInfo.cs b/src/Artemis.UI.Shared/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..1f6408856
--- /dev/null
+++ b/src/Artemis.UI.Shared/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Artemis.UI.Shared")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HP Inc.")]
+[assembly: AssemblyProduct("Artemis.UI.Shared")]
+[assembly: AssemblyCopyright("Copyright © HP Inc. 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Artemis.UI.Shared/Properties/Resources.Designer.cs b/src/Artemis.UI.Shared/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..f931adadc
--- /dev/null
+++ b/src/Artemis.UI.Shared/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Artemis.UI.Shared.Properties {
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if ((resourceMan == null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Artemis.UI.Shared.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/src/Artemis.UI.Shared/Properties/Resources.resx b/src/Artemis.UI.Shared/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/src/Artemis.UI.Shared/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Properties/Settings.Designer.cs b/src/Artemis.UI.Shared/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..d2346eb37
--- /dev/null
+++ b/src/Artemis.UI.Shared/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Artemis.UI.Shared.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/src/Artemis.UI.Shared/Properties/Settings.settings b/src/Artemis.UI.Shared/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/src/Artemis.UI.Shared/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/UserControl1.xaml b/src/Artemis.UI.Shared/UserControl1.xaml
new file mode 100644
index 000000000..1bb466275
--- /dev/null
+++ b/src/Artemis.UI.Shared/UserControl1.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/src/Artemis.UI.Shared/UserControl1.xaml.cs b/src/Artemis.UI.Shared/UserControl1.xaml.cs
new file mode 100644
index 000000000..ee4b9f7db
--- /dev/null
+++ b/src/Artemis.UI.Shared/UserControl1.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Artemis.UI.Shared
+{
+ ///
+ /// Interaction logic for UserControl1.xaml
+ ///
+ public partial class UserControl1 : UserControl
+ {
+ public UserControl1()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/Artemis.UI.Shared/packages.config b/src/Artemis.UI.Shared/packages.config
new file mode 100644
index 000000000..2c6820adf
--- /dev/null
+++ b/src/Artemis.UI.Shared/packages.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 67e4c9841..2cbb9f949 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -171,9 +171,6 @@
Designer
-
- ColorPicker.xaml
-
@@ -250,10 +247,6 @@
Code
-
- Designer
- MSBuild:Compile
-
Designer
MSBuild:Compile
@@ -409,6 +402,10 @@
{9b811f9b-86b9-4771-87af-72bae7078a36}
Artemis.Core
+
+ {adb357e6-151d-4d0d-87cb-68fd0bc29812}
+ Artemis.UI.Shared
+
diff --git a/src/Artemis.UI/Controls/ColorPicker.xaml.cs b/src/Artemis.UI/Controls/ColorPicker.xaml.cs
deleted file mode 100644
index eea2f5cb1..000000000
--- a/src/Artemis.UI/Controls/ColorPicker.xaml.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Media;
-
-namespace Artemis.UI.Controls
-{
- ///
- /// Interaction logic for ColorPicker.xaml
- ///
- public partial class ColorPicker : UserControl, INotifyPropertyChanged
- {
- public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
- "Color",
- typeof(Color),
- typeof(ColorPicker),
- new FrameworkPropertyMetadata(default(Color), OnColorPropertyChanged)
- );
-
- private byte _colorOpacity;
-
- private static void OnColorPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
- {
- if (sender is ColorPicker colorPicker)
- {
- colorPicker.OnPropertyChanged(nameof(Color));
- colorPicker.OnPropertyChanged(nameof(ColorCode));
- colorPicker.OnPropertyChanged(nameof(SolidColor));
- colorPicker.OnPropertyChanged(nameof(ColorOpacity));
- }
- }
-
- public ColorPicker()
- {
- InitializeComponent();
- PropertyChanged += OnPropertyChanged;
- }
-
- private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(Color))
- {
- if (Color.A != _colorOpacity)
- Color = Color.FromArgb(_colorOpacity, Color.R, Color.G, Color.B);
- }
- }
-
- public Color Color
- {
- get => (Color) GetValue(ColorProperty);
- set => SetValue(ColorProperty, value);
- }
-
- public string ColorCode
- {
- get => Color.ToString();
- set
- {
- try
- {
- if (string.IsNullOrWhiteSpace(value))
- Color = new Color();
- else
- {
- var color = ColorConverter.ConvertFromString(value);
- if (color is Color c)
- {
- _colorOpacity = c.A;
- Color = c;
- }
- }
- }
- catch (FormatException)
- {
- // ignored
- }
- }
- }
-
- public Color? SolidColor => Color.FromRgb(Color.R, Color.G, Color.B);
-
- public byte ColorOpacity
- {
- get => _colorOpacity;
- set
- {
- _colorOpacity = value;
- if (Color.A != _colorOpacity)
- {
- Color = Color.FromArgb(_colorOpacity, Color.R, Color.G, Color.B);
- OnPropertyChanged(nameof(Color));
- }
- }
- }
-
- public bool PopupOpen { get; set; }
-
- private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
- {
- PopupOpen = !PopupOpen;
- }
-
- #region Events
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml b/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml
index c7d9f6c9b..6251da775 100644
--- a/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml
+++ b/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml
@@ -5,11 +5,25 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Workshop"
xmlns:s="https://github.com/canton7/Stylet"
- xmlns:controls="clr-namespace:Artemis.UI.Controls"
+ xmlns:controls="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Test
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs b/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs
index 3b3b267a1..64ea22105 100644
--- a/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs
@@ -1,38 +1,18 @@
-using System;
-using System.ComponentModel;
-using System.Windows.Media;
+using System.Windows.Media;
using Stylet;
namespace Artemis.UI.Screens.Workshop
{
public class WorkshopViewModel : Screen, IScreenViewModel
{
+ public Color TestColor { get; set; }
+ public bool TestPopupOpen { get; set; }
public string Title => "Workshop";
- public WorkshopViewModel()
+ public void UpdateValues()
{
- PropertyChanged += OnPropertyChanged;
- }
-
- private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- Console.WriteLine("Property changed:" + e.PropertyName);
- Console.WriteLine(TestColor);
- }
-
- public Color TestColor { get; set; }
-
-
- protected override void OnActivate()
- {
- TestColor = Color.FromRgb(255, 0, 0);
- base.OnActivate();
- }
-
- protected override void OnDeactivate()
- {
- Console.WriteLine(TestColor);
- base.OnDeactivate();
+ TestPopupOpen = !TestPopupOpen;
+ TestColor = Color.FromRgb(5, 174, 255);
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.sln b/src/Artemis.sln
index ddd50d604..4b9e686f8 100644
--- a/src/Artemis.sln
+++ b/src/Artemis.sln
@@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.LayerElemen
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.LayerElements.Noise", "Artemis.Plugins.LayerElements.Noise\Artemis.Plugins.LayerElements.Noise.csproj", "{7F4C7AB0-4C9B-452D-AFED-34544C903DEF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.UI.Shared", "Artemis.UI.Shared\Artemis.UI.Shared.csproj", "{ADB357E6-151D-4D0D-87CB-68FD0BC29812}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -111,6 +113,14 @@ Global
{7F4C7AB0-4C9B-452D-AFED-34544C903DEF}.Release|Any CPU.Build.0 = Release|Any CPU
{7F4C7AB0-4C9B-452D-AFED-34544C903DEF}.Release|x64.ActiveCfg = Release|Any CPU
{7F4C7AB0-4C9B-452D-AFED-34544C903DEF}.Release|x64.Build.0 = Release|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Debug|x64.Build.0 = Debug|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Release|x64.ActiveCfg = Release|Any CPU
+ {ADB357E6-151D-4D0D-87CB-68FD0BC29812}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE