diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 4a17e3e64..e1b091e70 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -172,11 +172,14 @@ - - - + + + + + + @@ -189,9 +192,11 @@ + + diff --git a/src/Artemis.Core/Models/Profile/Abstract/ProfileElement.cs b/src/Artemis.Core/Models/Profile/Abstract/ProfileElement.cs index 06f08c99e..8fec27918 100644 --- a/src/Artemis.Core/Models/Profile/Abstract/ProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/Abstract/ProfileElement.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Linq; +using Artemis.Core.Models.Surface; using Stylet; namespace Artemis.Core.Models.Profile.Abstract @@ -44,7 +45,7 @@ namespace Artemis.Core.Models.Profile.Abstract /// /// Renders the element /// - public abstract void Render(double deltaTime, Surface.ArtemisSurface surface, Graphics graphics); + public abstract void Render(double deltaTime, ArtemisSurface surface, Graphics graphics); /// /// Applies the profile element's properties to the underlying storage entity @@ -73,7 +74,7 @@ namespace Artemis.Core.Models.Profile.Abstract layers.AddRange(Children.Where(c => c is Layer).Cast()); // Add all layers in folders inside this element - foreach (var childFolder in Children.Where(c => c is Folder).Cast()) + foreach (var childFolder in Children.Where(c => c is Folder).Cast()) layers.AddRange(childFolder.GetAllLayers()); return layers; diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs index 72527628b..41fde07ae 100644 --- a/src/Artemis.Core/Models/Profile/Folder.cs +++ b/src/Artemis.Core/Models/Profile/Folder.cs @@ -2,7 +2,7 @@ using System; using System.Drawing; using System.Linq; using Artemis.Core.Models.Profile.Abstract; -using Artemis.Core.Services.Interfaces; +using Artemis.Core.Models.Surface; using Artemis.Storage.Entities.Profile; namespace Artemis.Core.Models.Profile @@ -19,7 +19,7 @@ namespace Artemis.Core.Models.Profile Name = name; } - public Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity, IPluginService pluginService) + internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity) { FolderEntity = folderEntity; EntityId = folderEntity.Id; @@ -33,10 +33,10 @@ namespace Artemis.Core.Models.Profile // Load child folders foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId)) - _children.Add(new Folder(profile, this, childFolder, pluginService)); + _children.Add(new Folder(profile, this, childFolder)); // Load child layers foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId)) - _children.Add(new Layer(profile, this, childLayer, pluginService)); + _children.Add(new Layer(profile, this, childLayer)); // Ensure order integrity, should be unnecessary but no one is perfect specially me _children = _children.OrderBy(c => c.Order).ToList(); @@ -56,7 +56,7 @@ namespace Artemis.Core.Models.Profile profileElement.Update(deltaTime); } - public override void Render(double deltaTime, Surface.ArtemisSurface surface, Graphics graphics) + public override void Render(double deltaTime, ArtemisSurface surface, Graphics graphics) { // Folders don't render but their children do foreach (var profileElement in Children) diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index 4acf2ecbf..aee7eab8b 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -7,15 +7,15 @@ using System.Linq; using Artemis.Core.Extensions; using Artemis.Core.Models.Profile.Abstract; using Artemis.Core.Models.Surface; -using Artemis.Core.Plugins.Abstract; -using Artemis.Core.Plugins.Interfaces; -using Artemis.Core.Services.Interfaces; +using Artemis.Core.Plugins.LayerElement; using Artemis.Storage.Entities.Profile; +using Newtonsoft.Json; namespace Artemis.Core.Models.Profile { public sealed class Layer : ProfileElement { + private readonly List _layerElements; private List _leds; public Layer(Profile profile, ProfileElement parent, string name) @@ -26,10 +26,12 @@ namespace Artemis.Core.Models.Profile Profile = profile; Parent = parent; Name = name; + _leds = new List(); + _layerElements = new List(); } - internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity, IPluginService pluginService) + internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) { LayerEntity = layerEntity; EntityId = layerEntity.Id; @@ -39,46 +41,44 @@ namespace Artemis.Core.Models.Profile Name = layerEntity.Name; Order = layerEntity.Order; - LayerType = pluginService.GetLayerTypeByGuid(layerEntity.LayerTypeGuid); _leds = new List(); + _layerElements = new List(); } internal LayerEntity LayerEntity { get; set; } public ReadOnlyCollection Leds => _leds.AsReadOnly(); - public LayerType LayerType { get; private set; } - public ILayerTypeConfiguration LayerTypeConfiguration { get; set; } + public ReadOnlyCollection LayerElements => _layerElements.AsReadOnly(); public Rectangle RenderRectangle { get; set; } public GraphicsPath RenderPath { get; set; } public override void Update(double deltaTime) { - if (LayerType == null) - return; - - lock (LayerType) - { - LayerType.Update(this); - } + foreach (var layerElement in LayerElements) + layerElement.Update(deltaTime); } public override void Render(double deltaTime, ArtemisSurface surface, Graphics graphics) { - if (LayerType == null) - return; + graphics.SetClip(RenderPath); - lock (LayerType) - { - LayerType.Render(this, surface, graphics); - } + foreach (var layerElement in LayerElements) + layerElement.RenderPreProcess(surface, graphics); + + foreach (var layerElement in LayerElements) + layerElement.Render(surface, graphics); + + foreach (var layerElement in LayerElements) + layerElement.RenderPostProcess(surface, graphics); + + graphics.ResetClip(); } internal override void ApplyToEntity() { LayerEntity.Id = EntityId; LayerEntity.ParentId = Parent?.EntityId ?? new Guid(); - LayerEntity.LayerTypeGuid = LayerType?.PluginInfo.Guid ?? new Guid(); LayerEntity.Order = Order; LayerEntity.Name = Name; @@ -97,26 +97,18 @@ namespace Artemis.Core.Models.Profile } LayerEntity.Condition.Clear(); - + LayerEntity.Elements.Clear(); - } - - public void ApplySurface(ArtemisSurface surface) - { - var leds = new List(); - - // Get the surface LEDs for this layer - var availableLeds = surface.Devices.SelectMany(d => d.Leds).ToList(); - foreach (var ledEntity in LayerEntity.Leds) + foreach (var layerElement in LayerElements) { - var match = availableLeds.FirstOrDefault(a => a.Device.RgbDevice.GetDeviceHashCode() == ledEntity.DeviceHash && - a.RgbLed.Id.ToString() == ledEntity.LedName); - if (match != null) - leds.Add(match); + var layerElementEntity = new LayerElementEntity + { + PluginGuid = layerElement.Descriptor.LayerElementProvider.PluginInfo.Guid, + LayerElementType = layerElement.GetType().Name, + Configuration = JsonConvert.SerializeObject(layerElement.Settings) + }; + LayerEntity.Elements.Add(layerElementEntity); } - - _leds = leds; - CalculateRenderProperties(); } public void AddLed(ArtemisLed led) @@ -143,17 +135,27 @@ namespace Artemis.Core.Models.Profile CalculateRenderProperties(); } - public void UpdateLayerType(LayerType layerType) + internal void AddLayerElement(LayerElement layerElement) { - if (LayerType != null) + _layerElements.Add(layerElement); + } + + public void ApplySurface(ArtemisSurface surface) + { + var leds = new List(); + + // Get the surface LEDs for this layer + var availableLeds = surface.Devices.SelectMany(d => d.Leds).ToList(); + foreach (var ledEntity in LayerEntity.Leds) { - lock (LayerType) - { - LayerType.Dispose(); - } + var match = availableLeds.FirstOrDefault(a => a.Device.RgbDevice.GetDeviceHashCode() == ledEntity.DeviceHash && + a.RgbLed.Id.ToString() == ledEntity.LedName); + if (match != null) + leds.Add(match); } - LayerType = layerType; + _leds = leds; + CalculateRenderProperties(); } internal void CalculateRenderProperties() @@ -167,8 +169,8 @@ namespace Artemis.Core.Models.Profile // Determine to top-left and bottom-right var minX = Leds.Min(l => l.AbsoluteRenderRectangle.X); var minY = Leds.Min(l => l.AbsoluteRenderRectangle.Y); - var maxX = Leds.Max(l => l.AbsoluteRenderRectangle.X); - var maxY = Leds.Max(l => l.AbsoluteRenderRectangle.Y); + var maxX = Leds.Max(l => l.AbsoluteRenderRectangle.X + l.AbsoluteRenderRectangle.Width); + var maxY = Leds.Max(l => l.AbsoluteRenderRectangle.Y + l.AbsoluteRenderRectangle.Height); RenderRectangle = new Rectangle(minX, minY, maxX - minX, maxY - minY); diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs index 5caac88bf..2f6f17395 100644 --- a/src/Artemis.Core/Models/Profile/Profile.cs +++ b/src/Artemis.Core/Models/Profile/Profile.cs @@ -3,8 +3,8 @@ using System.Drawing; using System.Linq; using Artemis.Core.Exceptions; using Artemis.Core.Models.Profile.Abstract; +using Artemis.Core.Models.Surface; using Artemis.Core.Plugins.Models; -using Artemis.Core.Services.Interfaces; using Artemis.Storage.Entities.Profile; namespace Artemis.Core.Models.Profile @@ -23,7 +23,7 @@ namespace Artemis.Core.Models.Profile ApplyToEntity(); } - internal Profile(PluginInfo pluginInfo, ProfileEntity profileEntity, IPluginService pluginService) + internal Profile(PluginInfo pluginInfo, ProfileEntity profileEntity) { ProfileEntity = profileEntity; EntityId = profileEntity.Id; @@ -36,7 +36,7 @@ namespace Artemis.Core.Models.Profile if (rootFolder == null) AddChild(new Folder(this, null, "Root folder")); else - AddChild(new Folder(this, null, rootFolder, pluginService)); + AddChild(new Folder(this, null, rootFolder)); } public PluginInfo PluginInfo { get; } @@ -56,7 +56,7 @@ namespace Artemis.Core.Models.Profile } } - public override void Render(double deltaTime, Surface.ArtemisSurface surface, Graphics graphics) + public override void Render(double deltaTime, ArtemisSurface surface, Graphics graphics) { lock (this) { @@ -86,12 +86,14 @@ namespace Artemis.Core.Models.Profile } - internal void Activate() + internal void Activate(ArtemisSurface surface) { lock (this) { - if (IsActivated) return; + if (IsActivated) + return; + ApplySurface(surface); OnActivated(); IsActivated = true; } @@ -113,7 +115,7 @@ namespace Artemis.Core.Models.Profile return $"{nameof(Order)}: {Order}, {nameof(Name)}: {Name}, {nameof(PluginInfo)}: {PluginInfo}"; } - public void ApplySurface(Surface.ArtemisSurface surface) + public void ApplySurface(ArtemisSurface surface) { foreach (var layer in GetAllLayers()) layer.ApplySurface(surface); @@ -140,7 +142,7 @@ namespace Artemis.Core.Models.Profile { Deactivated?.Invoke(this, EventArgs.Empty); } - + #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs index 0260df1d8..bc04acd54 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs @@ -36,7 +36,7 @@ namespace Artemis.Core.Models.Surface IsActive = surfaceEntity.IsActive; // Devices are not populated here but as they are detected - Devices = new List(); + Devices = new List(); } public RGBSurface RgbSurface { get; } diff --git a/src/Artemis.Core/Plugins/Abstract/Device.cs b/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs similarity index 60% rename from src/Artemis.Core/Plugins/Abstract/Device.cs rename to src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs index d417b3c5d..39651d56f 100644 --- a/src/Artemis.Core/Plugins/Abstract/Device.cs +++ b/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using Artemis.Core.Extensions; using Artemis.Core.Plugins.Models; @@ -8,22 +9,24 @@ namespace Artemis.Core.Plugins.Abstract { /// /// - /// Allows you to implement your own RGB device + /// Allows you to implement and register your own device provider /// - public abstract class Device : Plugin + public abstract class DeviceProvider : Plugin { - protected Device(PluginInfo pluginInfo, IRGBDeviceProvider deviceProvider) : base(pluginInfo) + protected DeviceProvider(PluginInfo pluginInfo, IRGBDeviceProvider rgbDeviceProvider) : base(pluginInfo) { - DeviceProvider = deviceProvider ?? throw new ArgumentNullException(nameof(deviceProvider)); + RgbDeviceProvider = rgbDeviceProvider ?? throw new ArgumentNullException(nameof(rgbDeviceProvider)); } - public IRGBDeviceProvider DeviceProvider { get; } + public IRGBDeviceProvider RgbDeviceProvider { get; } protected void ResolveAbsolutePath(Type type, object sender, ResolvePathEventArgs e) { if (sender.GetType().IsGenericType(type)) { + Debug.WriteLine(e.RelativePart); + Debug.WriteLine(e.FileName); // Start from the plugin directory if (e.RelativePart != null && e.FileName != null) e.FinalPath = Path.Combine(PluginInfo.Directory.FullName, e.RelativePart, e.FileName); diff --git a/src/Artemis.Core/Plugins/Abstract/LayerType.cs b/src/Artemis.Core/Plugins/Abstract/LayerType.cs deleted file mode 100644 index 53987f8e9..000000000 --- a/src/Artemis.Core/Plugins/Abstract/LayerType.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Drawing; -using Artemis.Core.Models.Profile; -using Artemis.Core.Models.Surface; -using Artemis.Core.Plugins.Models; - -namespace Artemis.Core.Plugins.Abstract -{ - /// - /// - /// Allows you to create your own layer type - /// - public abstract class LayerType : Plugin - { - protected LayerType(PluginInfo pluginInfo) : base(pluginInfo) - { - } - - /// - /// Updates the layer type - /// - /// - public abstract void Update(Layer layer); - - /// - /// Renders the layer type - /// - public abstract void Render(Layer device, ArtemisSurface surface, Graphics graphics); - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/ModuleViewModel.cs b/src/Artemis.Core/Plugins/Abstract/ModuleViewModel.cs index baacbe5bf..809960d57 100644 --- a/src/Artemis.Core/Plugins/Abstract/ModuleViewModel.cs +++ b/src/Artemis.Core/Plugins/Abstract/ModuleViewModel.cs @@ -9,7 +9,7 @@ namespace Artemis.Core.Plugins.Abstract Module = module; DisplayName = displayName; } - + public Module Module { get; } } } \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs index bb0f73e95..69d4f52ed 100644 --- a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs +++ b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using Artemis.Core.Exceptions; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Surface; using Artemis.Core.Plugins.Models; @@ -34,8 +35,10 @@ namespace Artemis.Core.Plugins.Abstract } } - public void ChangeActiveProfile(Profile profile) + internal void ChangeActiveProfile(Profile profile, ArtemisSurface surface) { + if (profile != null && profile.PluginInfo != PluginInfo) + throw new ArtemisCoreException($"Cannot activate a profile of plugin {profile.PluginInfo} on a module of plugin {PluginInfo}."); lock (this) { if (profile == ActiveProfile) @@ -44,7 +47,7 @@ namespace Artemis.Core.Plugins.Abstract ActiveProfile?.Deactivate(); ActiveProfile = profile; - ActiveProfile?.Activate(); + ActiveProfile?.Activate(surface); } OnActiveProfileChanged(); @@ -53,7 +56,7 @@ namespace Artemis.Core.Plugins.Abstract #region Events public event EventHandler ActiveProfileChanged; - + protected virtual void OnActiveProfileChanged() { ActiveProfileChanged?.Invoke(this, EventArgs.Empty); diff --git a/src/Artemis.Core/Plugins/Interfaces/ILayerTypeConfiguration.cs b/src/Artemis.Core/Plugins/Interfaces/ILayerTypeConfiguration.cs deleted file mode 100644 index 6d9bb15ae..000000000 --- a/src/Artemis.Core/Plugins/Interfaces/ILayerTypeConfiguration.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Artemis.Core.Plugins.Interfaces -{ - public interface ILayerTypeConfiguration - { - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerElement/LayerElement.cs b/src/Artemis.Core/Plugins/LayerElement/LayerElement.cs new file mode 100644 index 000000000..b4df0ab4e --- /dev/null +++ b/src/Artemis.Core/Plugins/LayerElement/LayerElement.cs @@ -0,0 +1,47 @@ +using System.Drawing; +using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Surface; + +namespace Artemis.Core.Plugins.LayerElement +{ + public abstract class LayerElement + { + protected LayerElement(Layer layer, LayerElementSettings settings, LayerElementDescriptor descriptor) + { + Layer = layer; + Settings = settings; + Descriptor = descriptor; + } + + public Layer Layer { get; } + public LayerElementSettings Settings { get; } + public LayerElementDescriptor Descriptor { get; } + + /// + /// Called by the profile editor to populate the layer element properties panel + /// + /// + public abstract LayerElementViewModel GetViewModel(); + + /// + /// Called before rendering every frame, write your update logic here + /// + /// + public abstract void Update(double deltaTime); + + /// + /// Called before rendering, in the order configured on the layer + /// + public abstract void RenderPreProcess(ArtemisSurface surface, Graphics graphics); + + /// + /// Called during rendering, in the order configured on the layer + /// + public abstract void Render(ArtemisSurface surface, Graphics graphics); + + /// + /// Called after rendering, in the order configured on the layer + /// + public abstract void RenderPostProcess(ArtemisSurface surface, Graphics graphics); + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerElement/LayerElementDescriptor.cs b/src/Artemis.Core/Plugins/LayerElement/LayerElementDescriptor.cs new file mode 100644 index 000000000..ee94d20b4 --- /dev/null +++ b/src/Artemis.Core/Plugins/LayerElement/LayerElementDescriptor.cs @@ -0,0 +1,22 @@ +using System; + +namespace Artemis.Core.Plugins.LayerElement +{ + public class LayerElementDescriptor + { + internal LayerElementDescriptor(string displayName, string description, string icon, Type layerElementType, LayerElementProvider layerElementProvider) + { + DisplayName = displayName; + Description = description; + Icon = icon; + LayerElementType = layerElementType; + LayerElementProvider = layerElementProvider; + } + + public string DisplayName { get; } + public string Description { get; } + public string Icon { get; } + public Type LayerElementType { get; } + public LayerElementProvider LayerElementProvider { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerElement/LayerElementProvider.cs b/src/Artemis.Core/Plugins/LayerElement/LayerElementProvider.cs new file mode 100644 index 000000000..699e2a86b --- /dev/null +++ b/src/Artemis.Core/Plugins/LayerElement/LayerElementProvider.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Artemis.Core.Plugins.Abstract; +using Artemis.Core.Plugins.Models; + +namespace Artemis.Core.Plugins.LayerElement +{ + /// + /// + /// Allows you to create one or more s usable by profile layers. + /// + public abstract class LayerElementProvider : Plugin + { + private readonly List _layerElementDescriptors; + + protected LayerElementProvider(PluginInfo pluginInfo) : base(pluginInfo) + { + _layerElementDescriptors = new List(); + } + + public ReadOnlyCollection LayerElementDescriptors => _layerElementDescriptors.AsReadOnly(); + + protected void AddLayerElementDescriptor(string displayName, string description, string icon) where T : LayerElement + { + _layerElementDescriptors.Add(new LayerElementDescriptor(displayName, description, icon, typeof(T), this)); + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerElement/LayerElementSettings.cs b/src/Artemis.Core/Plugins/LayerElement/LayerElementSettings.cs new file mode 100644 index 000000000..c7bc34236 --- /dev/null +++ b/src/Artemis.Core/Plugins/LayerElement/LayerElementSettings.cs @@ -0,0 +1,8 @@ +using Stylet; + +namespace Artemis.Core.Plugins.LayerElement +{ + public abstract class LayerElementSettings : PropertyChangedBase + { + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerElement/LayerElementViewModel.cs b/src/Artemis.Core/Plugins/LayerElement/LayerElementViewModel.cs new file mode 100644 index 000000000..125d0c37f --- /dev/null +++ b/src/Artemis.Core/Plugins/LayerElement/LayerElementViewModel.cs @@ -0,0 +1,14 @@ +using Stylet; + +namespace Artemis.Core.Plugins.LayerElement +{ + public abstract class LayerElementViewModel : PropertyChangedBase + { + protected LayerElementViewModel(LayerElement layerElement) + { + LayerElement = layerElement; + } + + public LayerElement LayerElement { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/RGB.NET/GraphicsDecorator.cs b/src/Artemis.Core/RGB.NET/GraphicsDecorator.cs index c9433f1ec..25c126c96 100644 --- a/src/Artemis.Core/RGB.NET/GraphicsDecorator.cs +++ b/src/Artemis.Core/RGB.NET/GraphicsDecorator.cs @@ -54,7 +54,16 @@ namespace Artemis.Core.RGB.NET public Graphics GetGraphics() { - return _bitmap == null ? null : Graphics.FromImage(_bitmap.Bitmap); + try + { + return _bitmap == null ? null : Graphics.FromImage(_bitmap.Bitmap); + } + catch (AccessViolationException) + { + // ignored + } + + return null; } public Bitmap GetBitmap() diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index a1fae6776..5f099afd9 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -5,7 +5,6 @@ using Artemis.Core.Events; using Artemis.Core.Exceptions; using Artemis.Core.Plugins.Abstract; using Artemis.Core.Services.Interfaces; -using Artemis.Core.Services.Storage; using Artemis.Core.Services.Storage.Interfaces; using RGB.NET.Core; using Serilog; diff --git a/src/Artemis.Core/Services/DeviceService.cs b/src/Artemis.Core/Services/DeviceService.cs index 6594f8e8d..c511a1593 100644 --- a/src/Artemis.Core/Services/DeviceService.cs +++ b/src/Artemis.Core/Services/DeviceService.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; +using System.Drawing; using System.Threading.Tasks; using Artemis.Core.Events; using Artemis.Core.Models.Surface; @@ -56,9 +52,9 @@ namespace Artemis.Core.Services public interface IDeviceService : IArtemisService { /// - /// Identifies the device by making it blink white 5 times + /// Identifies the device by making it blink white 5 times /// /// void IdentifyDevice(ArtemisDevice device); } -} +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Interfaces/ILayerService.cs b/src/Artemis.Core/Services/Interfaces/ILayerService.cs new file mode 100644 index 000000000..a5da4b0a9 --- /dev/null +++ b/src/Artemis.Core/Services/Interfaces/ILayerService.cs @@ -0,0 +1,18 @@ +using Artemis.Core.Models.Profile; +using Artemis.Core.Plugins.LayerElement; + +namespace Artemis.Core.Services.Interfaces +{ + public interface ILayerService : IArtemisService + { + /// + /// Instantiates and adds the described by the provided + /// to the provided . + /// + /// The layer to add the new layer element to + /// The descriptor of the new layer element + /// JSON settings to be deserialized and injected into the layer element + /// + LayerElement InstantiateLayerElement(Layer layer, LayerElementDescriptor layerElementDescriptor, string settings = null); + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Interfaces/IPluginService.cs b/src/Artemis.Core/Services/Interfaces/IPluginService.cs index 031b1a788..57c102e97 100644 --- a/src/Artemis.Core/Services/Interfaces/IPluginService.cs +++ b/src/Artemis.Core/Services/Interfaces/IPluginService.cs @@ -55,13 +55,6 @@ namespace Artemis.Core.Services.Interfaces /// A list containing all the plugin info List GetAllPluginInfo(); - /// - /// Finds an instance of the layer type matching the given GUID - /// - /// The GUID of the layer type to find - /// An instance of the layer type - LayerType GetLayerTypeByGuid(Guid layerTypeGuid); - /// /// Finds all enabled instances of type /// diff --git a/src/Artemis.Core/Services/LayerService.cs b/src/Artemis.Core/Services/LayerService.cs new file mode 100644 index 000000000..0fca51b5e --- /dev/null +++ b/src/Artemis.Core/Services/LayerService.cs @@ -0,0 +1,50 @@ +using Artemis.Core.Models.Profile; +using Artemis.Core.Plugins.Exceptions; +using Artemis.Core.Plugins.LayerElement; +using Artemis.Core.Services.Interfaces; +using Newtonsoft.Json; +using Ninject; +using Ninject.Parameters; + +namespace Artemis.Core.Services +{ + public class LayerService : ILayerService + { + private readonly IKernel _kernel; + + public LayerService(IKernel kernel) + { + _kernel = kernel; + } + + public LayerElement InstantiateLayerElement(Layer layer, LayerElementDescriptor layerElementDescriptor, string settings) + { + // Deserialize the settings, if provided + object deserializedSettings = null; + if (settings != null) + { + var settingsType = layerElementDescriptor.LayerElementType.GetProperty(nameof(LayerElement.Settings))?.PropertyType; + if (settingsType == null) + { + throw new ArtemisPluginException( + layerElementDescriptor.LayerElementProvider.PluginInfo, + $"Layer element of type {layerElementDescriptor.LayerElementType} has no Settings property." + ); + } + + deserializedSettings = JsonConvert.DeserializeObject(settings, settingsType); + } + + var arguments = new IParameter[] + { + new ConstructorArgument("layer", layer), + new ConstructorArgument("settings", deserializedSettings), + new ConstructorArgument("descriptor", layerElementDescriptor) + }; + var layerElement = (LayerElement) _kernel.Get(layerElementDescriptor.LayerElementType, arguments); + layer.AddLayerElement(layerElement); + + return layerElement; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/PluginService.cs b/src/Artemis.Core/Services/PluginService.cs index 1aea17fbf..8ec9b04da 100644 --- a/src/Artemis.Core/Services/PluginService.cs +++ b/src/Artemis.Core/Services/PluginService.cs @@ -285,19 +285,6 @@ namespace Artemis.Core.Services return new List(_plugins); } - /// - public LayerType GetLayerTypeByGuid(Guid layerTypeGuid) - { - var pluginInfo = _plugins.FirstOrDefault(p => p.Guid == layerTypeGuid); - if (pluginInfo == null) - return null; - - if (!(pluginInfo.Instance is LayerType layerType)) - throw new ArtemisPluginException(pluginInfo, "Plugin is expected to implement exactly one LayerType"); - - return layerType; - } - /// public List GetPluginsOfType() where T : Plugin { @@ -309,7 +296,7 @@ namespace Artemis.Core.Services public Plugin GetDevicePlugin(IRGBDevice rgbDevice) { - return GetPluginsOfType().First(d => d.DeviceProvider.Devices.Contains(rgbDevice)); + return GetPluginsOfType().First(d => d.RgbDeviceProvider.Devices.Contains(rgbDevice)); } public void Dispose() diff --git a/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs b/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs index ee144a633..269db16ea 100644 --- a/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs +++ b/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs @@ -12,5 +12,12 @@ namespace Artemis.Core.Services.Storage.Interfaces Profile GetActiveProfile(ProfileModule module); void UpdateProfile(Profile profile, bool includeChildren); void DeleteProfile(Profile profile); + + /// + /// Activates the profile for the given with the currently active surface + /// + /// The module to activate the profile for + /// The profile to activate + void ActivateProfile(ProfileModule module, Profile profile); } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index 1e226638c..59d8de400 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -16,8 +16,8 @@ namespace Artemis.Core.Services.Storage public class ProfileService : IProfileService { private readonly IPluginService _pluginService; - private readonly ISurfaceService _surfaceService; private readonly IProfileRepository _profileRepository; + private readonly ISurfaceService _surfaceService; internal ProfileService(IPluginService pluginService, ISurfaceService surfaceService, IProfileRepository profileRepository) { @@ -29,6 +29,73 @@ namespace Artemis.Core.Services.Storage _surfaceService.SurfaceConfigurationUpdated += SurfaceServiceOnSurfaceConfigurationUpdated; } + public List GetProfiles(ProfileModule module) + { + var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid); + var profiles = new List(); + foreach (var profileEntity in profileEntities) + { + // If the profile entity matches the module's currently active profile, use that instead + if (module.ActiveProfile != null && module.ActiveProfile.EntityId == profileEntity.Id) + profiles.Add(module.ActiveProfile); + else + profiles.Add(new Profile(module.PluginInfo, profileEntity)); + } + + return profiles; + } + + public Profile GetActiveProfile(ProfileModule module) + { + if (module.ActiveProfile != null) + return module.ActiveProfile; + + var moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid); + var profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault(); + if (profileEntity == null) + return null; + + return new Profile(module.PluginInfo, profileEntity); + } + + public Profile CreateProfile(ProfileModule module, string name) + { + var profile = new Profile(module.PluginInfo, name); + _profileRepository.Add(profile.ProfileEntity); + + if (_surfaceService.ActiveSurface != null) + profile.ApplySurface(_surfaceService.ActiveSurface); + return profile; + } + + + public void ActivateProfile(ProfileModule module, Profile profile) + { + module.ChangeActiveProfile(profile, _surfaceService.ActiveSurface); + } + + public void DeleteProfile(Profile profile) + { + _profileRepository.Remove(profile.ProfileEntity); + } + + public void UpdateProfile(Profile profile, bool includeChildren) + { + profile.ApplyToEntity(); + if (includeChildren) + { + foreach (var folder in profile.GetAllFolders()) + folder.ApplyToEntity(); + foreach (var layer in profile.GetAllLayers()) + layer.ApplyToEntity(); + + if (_surfaceService.ActiveSurface != null) + profile.ApplySurface(_surfaceService.ActiveSurface); + } + + _profileRepository.Save(profile.ProfileEntity); + } + private void SurfaceServiceOnActiveSurfaceConfigurationChanged(object sender, SurfaceConfigurationEventArgs e) { ApplySurfaceToProfiles(e.Surface); @@ -47,66 +114,5 @@ namespace Artemis.Core.Services.Storage foreach (var profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList()) profileModule.ActiveProfile.ApplySurface(surface); } - - public List GetProfiles(ProfileModule module) - { - var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid); - var profiles = new List(); - foreach (var profileEntity in profileEntities) - { - // If the profile entity matches the module's currently active profile, use that instead - if (module.ActiveProfile != null && module.ActiveProfile.EntityId == profileEntity.Id) - profiles.Add(module.ActiveProfile); - else - profiles.Add(new Profile(module.PluginInfo, profileEntity, _pluginService)); - } - - return profiles; - } - - public Profile GetActiveProfile(ProfileModule module) - { - if (module.ActiveProfile != null) - return module.ActiveProfile; - - var moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid); - var profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault(); - if (profileEntity == null) - return null; - - return new Profile(module.PluginInfo, profileEntity, _pluginService); - } - - public Profile CreateProfile(ProfileModule module, string name) - { - var profile = new Profile(module.PluginInfo, name); - _profileRepository.Add(profile.ProfileEntity); - - if (_surfaceService.ActiveSurface != null) - profile.ApplySurface(_surfaceService.ActiveSurface); - return profile; - } - - public void DeleteProfile(Profile profile) - { - _profileRepository.Remove(profile.ProfileEntity); - } - - public void UpdateProfile(Profile profile, bool includeChildren) - { - profile.ApplyToEntity(); - if (includeChildren) - { - foreach (var folder in profile.GetAllFolders()) - folder.ApplyToEntity(); - foreach (var layer in profile.GetAllLayers()) - layer.ApplyToEntity(); - - if (_surfaceService.ActiveSurface != null) - profile.ApplySurface(_surfaceService.ActiveSurface); - } - - _profileRepository.Save(profile.ProfileEntity); - } } } \ No newline at end of file diff --git a/src/Artemis.Core/packages.config b/src/Artemis.Core/packages.config index 868ed378e..2733bfdeb 100644 --- a/src/Artemis.Core/packages.config +++ b/src/Artemis.Core/packages.config @@ -1,4 +1,5 @@  + diff --git a/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj b/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj index a35f6590c..5ffeb1d0e 100644 --- a/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj +++ b/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj @@ -54,7 +54,7 @@ - + diff --git a/src/Artemis.Plugins.Devices.Corsair/CorsairDevice.cs b/src/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs similarity index 62% rename from src/Artemis.Plugins.Devices.Corsair/CorsairDevice.cs rename to src/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs index e20f81def..43b68e493 100644 --- a/src/Artemis.Plugins.Devices.Corsair/CorsairDevice.cs +++ b/src/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs @@ -8,11 +8,11 @@ using RGB.NET.Devices.Corsair; namespace Artemis.Plugins.Devices.Corsair { // ReSharper disable once UnusedMember.Global - public class CorsairDevice : Device + public class CorsairDeviceProvider : DeviceProvider { private readonly IRgbService _rgbService; - public CorsairDevice(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, CorsairDeviceProvider.Instance) + public CorsairDeviceProvider(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, RGB.NET.Devices.Corsair.CorsairDeviceProvider.Instance) { _rgbService = rgbService; } @@ -20,9 +20,9 @@ namespace Artemis.Plugins.Devices.Corsair public override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(CorsairRGBDevice<>), sender, args); - CorsairDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "CUESDK.x64_2017.dll")); - CorsairDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "CUESDK_2017.dll")); - _rgbService.AddDeviceProvider(DeviceProvider); + RGB.NET.Devices.Corsair.CorsairDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "CUESDK.x64_2017.dll")); + RGB.NET.Devices.Corsair.CorsairDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "CUESDK_2017.dll")); + _rgbService.AddDeviceProvider(RgbDeviceProvider); } public override void DisablePlugin() diff --git a/src/Artemis.Plugins.Devices.Corsair/Images/Corsair/HeadsetStands/ST100RGB.png b/src/Artemis.Plugins.Devices.Corsair/Images/Corsair/HeadsetStands/ST100RGB.png new file mode 100644 index 000000000..0f10cad25 Binary files /dev/null and b/src/Artemis.Plugins.Devices.Corsair/Images/Corsair/HeadsetStands/ST100RGB.png differ diff --git a/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/HeadsetStands/ST100RGB.xml b/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/HeadsetStands/ST100RGB.xml new file mode 100644 index 000000000..043e9e9ad --- /dev/null +++ b/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/HeadsetStands/ST100RGB.xml @@ -0,0 +1,138 @@ + + + Corsair MM800 RGB + Physical layout of Corsairs ST100 RGB + HeadsetStand + Key + Corsair + ST100RGB + 145 + 148 + 42 + 44 + Images\Corsair\HeadsetStands + ST100RGB.png + + + 5 + 10 + + + = + + + + + = + + + + + ~ + 1.2 + 1 + + + 1 + 1 + + + ~ + - + + + ~ + - + + + M0.442,0.467 L0.456,0.518 L0.456,0.567 L0.446,0.62 L0.438,0.645 L0.469,0.613 L0.52,0.579 L0.564,0.569 L0.583,0.596 L0.593,0.564 L0.59,0.528 L0.566,0.474 L0.545,0.43 L0.516,0.384 L0.523,0.445 L0.521,0.491 L0.516,0.55 L0.518,0.496 L0.519,0.469 L0.501,0.447 L0.486,0.425 L0.489,0.469 L0.492,0.528 L0.484,0.564 L0.484,0.499z M0.451,0.411 L0.463,0.443 L0.464,0.467 L0.484,0.479 L0.478,0.435z M0.488,0.379 L0.497,0.43 L0.516,0.447 L0.513,0.406z M0.52,0.318 L0.528,0.37 L0.532,0.394 L0.557,0.418 L0.568,0.457 L0.572,0.425 L0.559,0.377 L0.543,0.343z + -3.75 + 0 + 0.45 + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/Keyboards/K65RGB/UK.xml b/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/Keyboards/K65RGB/UK.xml new file mode 100644 index 000000000..7fd6642c3 --- /dev/null +++ b/src/Artemis.Plugins.Devices.Corsair/Layouts/Corsair/Keyboards/K65RGB/UK.xml @@ -0,0 +1,496 @@ + + + Corsair K70 RGB - Physical UK + Physical UK-Layout of Corsairs K70 RGB (Logical: BE, CH, DE, ES, EU, FR, IT, ND, MEX, RU, UK, US_Int) + Darth Affe + Keyboard + Key + Corsair + K70 RGB + 436 + 165 + Images\Corsair\Keyboards + K70RGB.png + + + + Circle + 298 + 6 + 10mm + 10mm + + + Circle + +9 + 10mm + 10mm + + + + 375 + 6 + 12mm + + + + + 4 + 28 + + + + +12.667 + + + + + + + +12.667 + + + + + + + +12.667 + + + + + + + +5 + + + + + + +5 + 12mm + + + 12mm + + + 12mm + + + 12mm + + + + + 4 + 49 + + + + + + + + + + + + + + + 2 + + + + +5 + + + + + + +5 + + + + + + + + 4 + + + 1.5 + + + + + + + + + + + + + + + M0,0 L0,0.5 L0.16666666666,0.5 L0.16666666666,1 L1,1 L1,0 Z + 1.5 + 2 + + + + +5 + + + + + + +5 + + + + + 2 + + + + + 4 + ~ + 1.75 + + + + + + + + + + + + + + + + +90.75 + + + + + + + 4 + + + 1.25 + + + + + + + + + + + + + + 2.75 + + + + +24 + + + + +24 + + + + + 2 + + + + + 4 + ~ + 1.5 + + + + 1.25 + + + 6.5 + + + 1.25 + + + + + 1.5 + + + + +5 + + + + + + +5 + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.Plugins.Devices.Logitech/Artemis.Plugins.Devices.Logitech.csproj b/src/Artemis.Plugins.Devices.Logitech/Artemis.Plugins.Devices.Logitech.csproj index 492b0902e..6f4b09ced 100644 --- a/src/Artemis.Plugins.Devices.Logitech/Artemis.Plugins.Devices.Logitech.csproj +++ b/src/Artemis.Plugins.Devices.Logitech/Artemis.Plugins.Devices.Logitech.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Artemis.Plugins.Devices.Logitech/LogitechDevice.cs b/src/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs similarity index 51% rename from src/Artemis.Plugins.Devices.Logitech/LogitechDevice.cs rename to src/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs index c2411e8ed..2c66497cb 100644 --- a/src/Artemis.Plugins.Devices.Logitech/LogitechDevice.cs +++ b/src/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs @@ -7,11 +7,11 @@ using RGB.NET.Devices.Logitech; namespace Artemis.Plugins.Devices.Logitech { - public class LogitechDevice : Device + public class LogitechDeviceProvider : DeviceProvider { private readonly IRgbService _rgbService; - public LogitechDevice(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, LogitechDeviceProvider.Instance) + public LogitechDeviceProvider(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, RGB.NET.Devices.Logitech.LogitechDeviceProvider.Instance) { _rgbService = rgbService; } @@ -19,9 +19,9 @@ namespace Artemis.Plugins.Devices.Logitech public override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(LogitechRGBDevice<>), sender, args); - LogitechDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "LogitechLedEnginesWrapper.dll")); - LogitechDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "LogitechLedEnginesWrapper.dll")); - _rgbService.AddDeviceProvider(DeviceProvider); + RGB.NET.Devices.Logitech.LogitechDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "LogitechLedEnginesWrapper.dll")); + RGB.NET.Devices.Logitech.LogitechDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "LogitechLedEnginesWrapper.dll")); + _rgbService.AddDeviceProvider(RgbDeviceProvider); } public override void DisablePlugin() diff --git a/src/Artemis.Plugins.Devices.Logitech/app.config b/src/Artemis.Plugins.Devices.Logitech/app.config index e995f3d3b..c8bc187aa 100644 --- a/src/Artemis.Plugins.Devices.Logitech/app.config +++ b/src/Artemis.Plugins.Devices.Logitech/app.config @@ -1,4 +1,5 @@  + diff --git a/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj b/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerElements.Brush.csproj similarity index 78% rename from src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj rename to src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerElements.Brush.csproj index b2da4aa8a..f39c66274 100644 --- a/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj +++ b/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerElements.Brush.csproj @@ -7,8 +7,8 @@ {0F288A66-6EB0-4589-8595-E33A3A3EAEA2} Library Properties - Artemis.Plugins.LayerTypes.Brush - Artemis.Plugins.LayerTypes.Brush + Artemis.Plugins.LayerElements.Brush + Artemis.Plugins.LayerElements.Brush v4.7.2 512 true @@ -33,14 +33,20 @@ 4 + + ..\packages\MaterialDesignColors.1.2.0\lib\net45\MaterialDesignColors.dll + False + + + ..\packages\MaterialDesignThemes.2.6.0\lib\net45\MaterialDesignThemes.Wpf.dll + False + - - ..\packages\QRCoder.1.2.5\lib\net40\QRCoder.dll - False ..\..\..\RGB.NET\bin\net45\RGB.NET.Core.dll + False ..\packages\Stylet.1.2.0\lib\net45\Stylet.dll @@ -52,6 +58,7 @@ ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll False + @@ -59,14 +66,13 @@ - - ..\packages\QRCoder.1.2.5\lib\net40\UnityEngine.dll - - - + + + + @@ -83,6 +89,12 @@ PreserveNewest + + + Designer + MSBuild:Compile + + echo Copying plugin to Artemis.UI output directory diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushConfiguration.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushConfiguration.cs deleted file mode 100644 index cd6b6c2d9..000000000 --- a/src/Artemis.Plugins.LayerTypes.Brush/BrushConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Artemis.Core.Plugins.Interfaces; - -namespace Artemis.Plugins.LayerTypes.Brush -{ - public class BrushConfiguration : ILayerTypeConfiguration - { - public System.Windows.Media.Brush Brush { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElement.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElement.cs new file mode 100644 index 000000000..37153dd13 --- /dev/null +++ b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElement.cs @@ -0,0 +1,40 @@ +using System.Drawing; +using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Surface; +using Artemis.Core.Plugins.LayerElement; + +namespace Artemis.Plugins.LayerElements.Brush +{ + public class BrushLayerElement : LayerElement + { + public BrushLayerElement(Layer layer, BrushLayerElementSettings settings, LayerElementDescriptor descriptor) : base(layer, settings, descriptor) + { + Settings = settings ?? new BrushLayerElementSettings {Brush = new SolidBrush(Color.Red)}; + } + + public new BrushLayerElementSettings Settings { get; } + + public override LayerElementViewModel GetViewModel() + { + return new BrushLayerElementViewModel(this); + } + + public override void Update(double deltaTime) + { + } + + public override void RenderPreProcess(ArtemisSurface surface, Graphics graphics) + { + } + + public override void Render(ArtemisSurface surface, Graphics graphics) + { + if (Settings?.Brush != null) + graphics.FillRectangle(Settings.Brush, Layer.RenderRectangle); + } + + public override void RenderPostProcess(ArtemisSurface surface, Graphics graphics) + { + } + } +} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementProvider.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementProvider.cs new file mode 100644 index 000000000..3d124573b --- /dev/null +++ b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementProvider.cs @@ -0,0 +1,25 @@ +using Artemis.Core.Plugins.LayerElement; +using Artemis.Core.Plugins.Models; + +namespace Artemis.Plugins.LayerElements.Brush +{ + public class BrushLayerElementProvider : LayerElementProvider + { + public BrushLayerElementProvider(PluginInfo pluginInfo) : base(pluginInfo) + { + AddLayerElementDescriptor("Brush", "A brush of a specific type and colors", "Brush"); + } + + public override void EnablePlugin() + { + } + + public override void DisablePlugin() + { + } + + public override void Dispose() + { + } + } +} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementSettings.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementSettings.cs new file mode 100644 index 000000000..b274810e8 --- /dev/null +++ b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementSettings.cs @@ -0,0 +1,9 @@ +using Artemis.Core.Plugins.LayerElement; + +namespace Artemis.Plugins.LayerElements.Brush +{ + public class BrushLayerElementSettings : LayerElementSettings + { + public System.Drawing.Brush Brush { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementView.xaml b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementView.xaml new file mode 100644 index 000000000..8f7aa534d --- /dev/null +++ b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementView.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Setting title + Setting subtitle + + + + + + + + + Setting title + Setting subtitle + + + + + + + \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementViewModel.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementViewModel.cs new file mode 100644 index 000000000..ba3dab6a9 --- /dev/null +++ b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerElementViewModel.cs @@ -0,0 +1,14 @@ +using Artemis.Core.Plugins.LayerElement; + +namespace Artemis.Plugins.LayerElements.Brush +{ + public class BrushLayerElementViewModel : LayerElementViewModel + { + public BrushLayerElementViewModel(BrushLayerElement layerElement) : base(layerElement) + { + LayerElement = layerElement; + } + + public new BrushLayerElement LayerElement { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerType.cs b/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerType.cs deleted file mode 100644 index 26e8ba980..000000000 --- a/src/Artemis.Plugins.LayerTypes.Brush/BrushLayerType.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Drawing; -using Artemis.Core.Models.Profile; -using Artemis.Core.Models.Surface; -using Artemis.Core.Plugins.Abstract; -using Artemis.Core.Plugins.Models; -using QRCoder; - -namespace Artemis.Plugins.LayerTypes.Brush -{ - public class BrushLayerType : LayerType - { - public BrushLayerType(PluginInfo pluginInfo) : base(pluginInfo) - { - } - - public override void EnablePlugin() - { - var qrGenerator = new QRCodeGenerator(); - } - - public override void DisablePlugin() - { - } - - public override void Update(Layer layer) - { - var config = layer.LayerTypeConfiguration as BrushConfiguration; - if (config == null) - return; - - // Update the brush - } - - public override void Render(Layer device, ArtemisSurface surface, Graphics graphics) - { - } - - public override void Dispose() - { - } - } -} \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/Properties/AssemblyInfo.cs b/src/Artemis.Plugins.LayerTypes.Brush/Properties/AssemblyInfo.cs index 6a3d074b2..54e9088c8 100644 --- a/src/Artemis.Plugins.LayerTypes.Brush/Properties/AssemblyInfo.cs +++ b/src/Artemis.Plugins.LayerTypes.Brush/Properties/AssemblyInfo.cs @@ -4,7 +4,7 @@ using System.Runtime.InteropServices; // 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.Plugins.LayerTypes.Brush")] +[assembly: AssemblyTitle("Artemis.Plugins.LayerElements.Brush")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] diff --git a/src/Artemis.Plugins.LayerTypes.Brush/packages.config b/src/Artemis.Plugins.LayerTypes.Brush/packages.config index 1b85e127f..ca0c2406c 100644 --- a/src/Artemis.Plugins.LayerTypes.Brush/packages.config +++ b/src/Artemis.Plugins.LayerTypes.Brush/packages.config @@ -1,7 +1,7 @@  - + \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerTypes.Brush/plugin.json b/src/Artemis.Plugins.LayerTypes.Brush/plugin.json index 3f2ac043d..95eee07a0 100644 --- a/src/Artemis.Plugins.LayerTypes.Brush/plugin.json +++ b/src/Artemis.Plugins.LayerTypes.Brush/plugin.json @@ -1,10 +1,10 @@ { "Guid": "92a9d6ba-6f7a-4937-94d5-c1d715b4141a", - "Name": "Brush layer", + "Name": "Brush layer elements", "Version": { "Major": 1, "Minor": 0, "Build": 0 }, - "Main": "Artemis.Plugins.LayerTypes.Brush.dll" + "Main": "Artemis.Plugins.LayerElements.Brush.dll" } \ 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 b3858df98..775ac0455 100644 --- a/src/Artemis.Plugins.Modules.General/GeneralModule.cs +++ b/src/Artemis.Plugins.Modules.General/GeneralModule.cs @@ -8,6 +8,8 @@ using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Models; using Artemis.Core.Services.Storage.Interfaces; using Artemis.Plugins.Modules.General.ViewModels; +using RGB.NET.Core; +using Color = System.Drawing.Color; namespace Artemis.Plugins.Modules.General { @@ -45,6 +47,8 @@ namespace Artemis.Plugins.Modules.General public int[] Hues { get; set; } public int MovePercentage { get; set; } + public Dictionary DeviceBrushes { get; set; } + public override void EnablePlugin() { } @@ -65,16 +69,20 @@ namespace Artemis.Plugins.Modules.General MovePercentage++; if (MovePercentage > 100) MovePercentage = 0; + + base.Update(deltaTime); } public override void Render(double deltaTime, ArtemisSurface surface, Graphics graphics) { // Per-device coloring, slower - RenderPerDevice(surface, graphics); + // RenderPerDevice(surface, graphics); // Per-LED coloring, slowest // RenderPerLed(surface, graphics); + + base.Render(deltaTime, surface, graphics); } public void RenderFullSurface(ArtemisSurface surface, Graphics graphics) @@ -97,8 +105,6 @@ namespace Artemis.Plugins.Modules.General } } - public Dictionary DeviceBrushes { get; set; } - private Image RenderGradientForDevice(ArtemisDevice device) { var brush = new LinearGradientBrush(device.RenderRectangle, Color.Black, Color.Black, 0, false) @@ -119,7 +125,10 @@ namespace Artemis.Plugins.Modules.General var index = 0; foreach (var led in surface.Devices.SelectMany(d => d.Leds)) { - graphics.FillRectangle(new SolidBrush(ColorHelpers.ColorFromHSV(Hues[index], 1, 1)), led.AbsoluteRenderRectangle); + if (led.RgbLed.Id == LedId.HeadsetStand1) + graphics.FillRectangle(new SolidBrush(Color.Red), led.AbsoluteRenderRectangle); + else + graphics.FillRectangle(new SolidBrush(ColorHelpers.ColorFromHSV(Hues[index], 1, 1)), led.AbsoluteRenderRectangle); index++; } } diff --git a/src/Artemis.Storage/Entities/Profile/LayerElementEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerElementEntity.cs index 4c0145ef6..c1dac0d09 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerElementEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerElementEntity.cs @@ -4,6 +4,8 @@ namespace Artemis.Storage.Entities.Profile { public class LayerElementEntity { - public Guid Id { get; set; } + public Guid PluginGuid { get; set; } + public string LayerElementType { get; set; } + public string Configuration { get; set; } } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs index 378e9d7cf..59d1ed26c 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs @@ -15,7 +15,6 @@ namespace Artemis.Storage.Entities.Profile public Guid Id { get; set; } public Guid ParentId { get; set; } - public Guid LayerTypeGuid { get; set; } public int Order { get; set; } public string Name { get; set; } diff --git a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs index b130a9642..d0f559b16 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Artemis.Storage.Entities; using Artemis.Storage.Entities.Profile; namespace Artemis.Storage.Repositories.Interfaces diff --git a/src/Artemis.Storage/Repositories/Interfaces/ISurfaceRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/ISurfaceRepository.cs index e113cb17f..afbd7743b 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/ISurfaceRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/ISurfaceRepository.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using Artemis.Storage.Entities; using Artemis.Storage.Entities.Surface; namespace Artemis.Storage.Repositories.Interfaces diff --git a/src/Artemis.Storage/Repositories/PluginSettingRepository.cs b/src/Artemis.Storage/Repositories/PluginSettingRepository.cs index 3ea1564ff..a50de948f 100644 --- a/src/Artemis.Storage/Repositories/PluginSettingRepository.cs +++ b/src/Artemis.Storage/Repositories/PluginSettingRepository.cs @@ -31,7 +31,7 @@ namespace Artemis.Storage.Repositories { return _repository.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid); } - + public void Save(PluginSettingEntity pluginSettingEntity) { _repository.Upsert(pluginSettingEntity); diff --git a/src/Artemis.UI/App.xaml b/src/Artemis.UI/App.xaml index a41e55ad4..2497d359f 100644 --- a/src/Artemis.UI/App.xaml +++ b/src/Artemis.UI/App.xaml @@ -27,11 +27,11 @@ - + - + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index c7b7f18dd..d29501b6e 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -148,11 +148,14 @@ Designer + + + @@ -179,7 +182,6 @@ - @@ -226,6 +228,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -246,7 +252,7 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile @@ -254,10 +260,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - Designer MSBuild:Compile diff --git a/src/Artemis.UI/Converters/ColorToDrawingColorConverter.cs b/src/Artemis.UI/Converters/ColorToDrawingColorConverter.cs new file mode 100644 index 000000000..4299912ab --- /dev/null +++ b/src/Artemis.UI/Converters/ColorToDrawingColorConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Drawing; +using System.Globalization; +using System.Windows.Data; + +namespace Artemis.UI.Converters +{ + /// + /// + /// Converts into . + /// + [ValueConversion(typeof(Color), typeof(System.Windows.Media.Color))] + public class ColorToDrawingColorConverter : IValueConverter + { + /// + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Color drawingColor) + return System.Windows.Media.Color.FromArgb(drawingColor.A, drawingColor.R, drawingColor.G, drawingColor.B); + + return default(System.Windows.Media.Color); + } + + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is System.Windows.Media.Color mediaColor) + return Color.FromArgb(mediaColor.A, mediaColor.R, mediaColor.G, mediaColor.B); + + return default(Color); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs index ad577220c..cb36d7088 100644 --- a/src/Artemis.UI/Ninject/UiModule.cs +++ b/src/Artemis.UI/Ninject/UiModule.cs @@ -20,7 +20,7 @@ namespace Artemis.UI.Ninject { if (Kernel == null) throw new ArgumentNullException("Kernel shouldn't be null here."); - + // Bind all built-in VMs Kernel.Bind(x => { @@ -51,7 +51,7 @@ namespace Artemis.UI.Ninject Kernel.Bind().ToFactory(); Kernel.Bind().ToFactory(); Kernel.Bind().ToFactory(); - + // Bind profile editor VMs Kernel.Bind(x => { diff --git a/src/Artemis.UI/Screens/GradientEditor/GradientEditorView.xaml b/src/Artemis.UI/Screens/GradientEditor/GradientEditorView.xaml new file mode 100644 index 000000000..db4b7c8c7 --- /dev/null +++ b/src/Artemis.UI/Screens/GradientEditor/GradientEditorView.xaml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/GradientEditor/GradientEditorViewModel.cs b/src/Artemis.UI/Screens/GradientEditor/GradientEditorViewModel.cs new file mode 100644 index 000000000..473f40b9a --- /dev/null +++ b/src/Artemis.UI/Screens/GradientEditor/GradientEditorViewModel.cs @@ -0,0 +1,10 @@ +using System.Windows.Media; +using Stylet; + +namespace Artemis.UI.Screens.GradientEditor +{ + public class GradientEditorViewModel : Screen + { + public Color CurrentColor { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Dialogs/ProfileElementRenameView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Dialogs/ProfileElementRenameView.xaml index 3b61a050e..ec975ae0e 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Dialogs/ProfileElementRenameView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Dialogs/ProfileElementRenameView.xaml @@ -16,7 +16,7 @@ Margin="0 8 0 16" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Text="{Binding ElementName, UpdateSourceTrigger=PropertyChanged}" - Loaded="FrameworkElement_OnLoaded"/> + Loaded="FrameworkElement_OnLoaded" /> + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/Dialogs/AddLayerElementViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/Dialogs/AddLayerElementViewModel.cs new file mode 100644 index 000000000..9c4aec276 --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/Dialogs/AddLayerElementViewModel.cs @@ -0,0 +1,53 @@ +using System.Windows.Input; +using Artemis.Core.Models.Profile; +using Artemis.Core.Plugins.LayerElement; +using Artemis.Core.Services.Interfaces; +using Artemis.UI.ViewModels.Dialogs; +using Stylet; + +namespace Artemis.UI.Screens.Module.ProfileEditor.LayerElements.Dialogs +{ + public class AddLayerElementViewModel : DialogViewModelBase + { + private readonly ILayerService _layerService; + + + public AddLayerElementViewModel(IPluginService pluginService, ILayerService layerService, Layer layer) + { + _layerService = layerService; + Layer = layer; + + LayerElementDescriptors = new BindableCollection(); + var layerElementProviders = pluginService.GetPluginsOfType(); + foreach (var layerElementProvider in layerElementProviders) + LayerElementDescriptors.AddRange(layerElementProvider.LayerElementDescriptors); + } + + public Layer Layer { get; } + + public LayerElementDescriptor SelectedLayerElementDescriptor { get; set; } + public BindableCollection LayerElementDescriptors { get; set; } + public bool CanAccept => SelectedLayerElementDescriptor != null; + + public void Accept() + { + var layerElement = _layerService.InstantiateLayerElement(Layer, SelectedLayerElementDescriptor); + Session.Close(layerElement); + } + + public void Cancel() + { + Session.Close(); + } + + #region View event handlers + + public void ListBoxItemMouseClick(object sender, MouseButtonEventArgs args) + { + if (args.ClickCount > 1 && SelectedLayerElementDescriptor != null) + Accept(); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementView.xaml deleted file mode 100644 index c2f1efe5f..000000000 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementView.xaml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementViewModel.cs index 26d65f42c..62ad2762a 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementViewModel.cs @@ -1,6 +1,19 @@ -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerElements +using Artemis.Core.Models.Profile; +using Artemis.Core.Plugins.LayerElement; + +namespace Artemis.UI.Screens.Module.ProfileEditor.LayerElements { public class LayerElementViewModel { + public LayerElementViewModel(LayerElement layerElement) + { + Layer = layerElement.Layer; + LayerElement = layerElement; + LayerElementDescriptor = layerElement.Descriptor; + } + + public Layer Layer { get; set; } + public LayerElement LayerElement { get; set; } + public LayerElementDescriptor LayerElementDescriptor { get; set; } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsView.xaml index 9053f62a0..a48a84a99 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsView.xaml @@ -3,15 +3,69 @@ 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:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerElements" + xmlns:layerElements="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerElements" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:s="https://github.com/canton7/Stylet" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800"> - - - - Layer elements - - - - + d:DesignHeight="450" d:DesignWidth="800" + d:DataContext="{d:DesignInstance {x:Type layerElements:LayerElementsViewModel}}"> + + + + + + + + + + Layer elements + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsViewModel.cs index 52e9a1f79..815e67af3 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerElements/LayerElementsViewModel.cs @@ -1,6 +1,95 @@ -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerElements +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Abstract; +using Artemis.Core.Plugins.LayerElement; +using Artemis.UI.Screens.Module.ProfileEditor.LayerElements.Dialogs; +using Artemis.UI.Services.Interfaces; +using Stylet; + +namespace Artemis.UI.Screens.Module.ProfileEditor.LayerElements { public class LayerElementsViewModel : ProfileEditorPanelViewModel { + private readonly IDialogService _dialogService; + private readonly IProfileEditorService _profileEditorService; + private LayerElementViewModel _selectedLayerElement; + + public LayerElementsViewModel(IProfileEditorService profileEditorService, IDialogService dialogService) + { + _profileEditorService = profileEditorService; + _dialogService = dialogService; + + LayerElements = new BindableCollection(); + SelectedProfileElement = _profileEditorService.SelectedProfileElement; + PopulateLayerElements(); + + _profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged; + _profileEditorService.SelectedLayerElementChanged += OnSelectedLayerElementChanged; + } + + public ProfileElement SelectedProfileElement { get; private set; } + public BindableCollection LayerElements { get; set; } + + public LayerElementViewModel SelectedLayerElement + { + get => _selectedLayerElement; + set + { + _selectedLayerElement = value; + _profileEditorService.ChangeSelectedLayerElement(value?.LayerElement); + } + } + + public bool CanAddLayerElement => SelectedProfileElement is Layer; + public bool CanDeleteSelectedLayerElement => SelectedLayerElement != null; + + private void OnSelectedLayerElementChanged(object sender, EventArgs e) + { + _selectedLayerElement = LayerElements.FirstOrDefault(l => l.LayerElement == _profileEditorService.SelectedLayerElement); + NotifyOfPropertyChange(() => SelectedLayerElement); + } + + private void OnSelectedProfileElementChanged(object sender, EventArgs e) + { + SelectedProfileElement = _profileEditorService.SelectedProfileElement; + PopulateLayerElements(); + } + + private void PopulateLayerElements() + { + LayerElements.Clear(); + if (SelectedProfileElement is Layer layer) + { + foreach (var layerElement in layer.LayerElements) + LayerElements.Add(new LayerElementViewModel(layerElement)); + } + } + + public async void AddLayerElement() + { + var result = await _dialogService.ShowDialogAt( + "LayerElementsDialogHost", + new Dictionary {{"layer", (Layer) SelectedProfileElement}} + ); + + if (result is LayerElement layerElement) + LayerElements.Add(new LayerElementViewModel(layerElement)); + } + + public async void DeleteSelectedLayerElement() + { + if (SelectedLayerElement == null) + return; + + var result = await _dialogService.ShowConfirmDialogAt( + "LayerElementsDialogHost", + "Delete layer element", + "Are you sure you want to delete the selected layer element?" + ); + if (!result) + return; + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs index 831660ead..cdad6a569 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs @@ -8,7 +8,6 @@ using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Models; using Artemis.Core.Services; using Artemis.Core.Services.Storage.Interfaces; -using Artemis.UI.Events; using Artemis.UI.Screens.Module.ProfileEditor.Dialogs; using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions; using Artemis.UI.Screens.Module.ProfileEditor.ElementProperties; @@ -29,8 +28,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor public ProfileEditorViewModel(ProfileModule module, ICollection viewModels, IProfileEditorService profileEditorService, - IProfileService profileService, - IDialogService dialogService, + IProfileService profileService, + IDialogService dialogService, ISettingsService settingsService) { _profileEditorService = profileEditorService; @@ -81,8 +80,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor return; var oldProfile = Module.ActiveProfile; - Module.ChangeActiveProfile(profile); - + _profileService.ActivateProfile(Module, profile); + if (oldProfile != null) _profileService.UpdateProfile(oldProfile, false); if (profile != null) @@ -186,7 +185,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor _profileEditorService.ChangeSelectedProfile(SelectedProfile); if (!activeProfile.IsActivated) - Module.ChangeActiveProfile(activeProfile); + _profileService.ActivateProfile(Module, activeProfile); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeView.xaml index 86cad251d..72aca0e22 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeView.xaml @@ -25,7 +25,7 @@ - + vm.ProfileElement == _profileEditorService.SelectedProfileElement); + _selectedTreeItem = vms?.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement); NotifyOfPropertyChange(() => SelectedTreeItem); } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/TreeItem/FolderView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/TreeItem/FolderView.xaml index 8575bf087..2180909ce 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/TreeItem/FolderView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/TreeItem/FolderView.xaml @@ -37,9 +37,11 @@ - - - + + + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLedViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLedViewModel.cs index f8b99ca97..8d63bb0e7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLedViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLedViewModel.cs @@ -38,7 +38,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization public Geometry StrokeGeometry { get; private set; } public Color DisplayColor { get; private set; } - private void CreateLedGeometry() { switch (Led.RgbLed.Shape) diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs index 2520feb93..368d4aa9a 100644 --- a/src/Artemis.UI/Screens/RootViewModel.cs +++ b/src/Artemis.UI/Screens/RootViewModel.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Windows; @@ -15,7 +13,6 @@ using Artemis.UI.Screens.News; using Artemis.UI.Screens.Settings; using Artemis.UI.Screens.SurfaceEditor; using Artemis.UI.Screens.Workshop; -using MahApps.Metro.Controls; using Stylet; namespace Artemis.UI.Screens @@ -23,8 +20,8 @@ namespace Artemis.UI.Screens public class RootViewModel : Conductor { private readonly ICollection _artemisViewModels; - private readonly IModuleViewModelFactory _moduleViewModelFactory; private readonly IEventAggregator _eventAggregator; + private readonly IModuleViewModelFactory _moduleViewModelFactory; private readonly IPluginService _pluginService; private bool _lostFocus; diff --git a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs index b9690a93b..363b77661 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs +++ b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs @@ -332,7 +332,7 @@ namespace Artemis.UI.Screens.SurfaceEditor { if (IsPanKeyDown()) return; - + var selectedRect = new Rect(_mouseDragStartPoint, position); SelectionRectangle.Rect = selectedRect; diff --git a/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml b/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml index edef5de79..5a6d3dbdf 100644 --- a/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml +++ b/src/Artemis.UI/Screens/Workshop/WorkshopView.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Workshop" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> diff --git a/src/Artemis.UI/Services/Dialog/DialogService.cs b/src/Artemis.UI/Services/Dialog/DialogService.cs index 7771ef1a1..c9541798e 100644 --- a/src/Artemis.UI/Services/Dialog/DialogService.cs +++ b/src/Artemis.UI/Services/Dialog/DialogService.cs @@ -29,8 +29,8 @@ namespace Artemis.UI.Services.Dialog { new ConstructorArgument("header", header), new ConstructorArgument("text", text), - new ConstructorArgument("confirmText", confirmText), - new ConstructorArgument("cancelText", cancelText) + new ConstructorArgument("confirmText", confirmText.ToUpper()), + new ConstructorArgument("cancelText", cancelText.ToUpper()) }; var result = await ShowDialog(arguments); return (bool) result; @@ -42,8 +42,8 @@ namespace Artemis.UI.Services.Dialog { new ConstructorArgument("header", header), new ConstructorArgument("text", text), - new ConstructorArgument("confirmText", confirmText), - new ConstructorArgument("cancelText", cancelText) + new ConstructorArgument("confirmText", confirmText.ToUpper()), + new ConstructorArgument("cancelText", cancelText.ToUpper()) }; var result = await ShowDialogAt(identifier, arguments); return (bool) result; diff --git a/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs index 6a0187571..64e272465 100644 --- a/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs +++ b/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs @@ -1,6 +1,7 @@ using System; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.Abstract; +using Artemis.Core.Plugins.LayerElement; namespace Artemis.UI.Services.Interfaces { @@ -8,15 +9,18 @@ namespace Artemis.UI.Services.Interfaces { Profile SelectedProfile { get; } ProfileElement SelectedProfileElement { get; } + LayerElement SelectedLayerElement { get; } void ChangeSelectedProfile(Profile profile); void UpdateSelectedProfile(); void ChangeSelectedProfileElement(ProfileElement profileElement); void UpdateSelectedProfileElement(); + void ChangeSelectedLayerElement(LayerElement layerElement); event EventHandler SelectedProfileChanged; event EventHandler SelectedProfileUpdated; event EventHandler SelectedProfileElementChanged; event EventHandler SelectedProfileElementUpdated; + event EventHandler SelectedLayerElementChanged; } } \ No newline at end of file diff --git a/src/Artemis.UI/Services/ProfileEditorService.cs b/src/Artemis.UI/Services/ProfileEditorService.cs index d345fe013..1aa347fba 100644 --- a/src/Artemis.UI/Services/ProfileEditorService.cs +++ b/src/Artemis.UI/Services/ProfileEditorService.cs @@ -1,6 +1,7 @@ using System; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.Abstract; +using Artemis.Core.Plugins.LayerElement; using Artemis.Core.Services.Storage.Interfaces; using Artemis.UI.Services.Interfaces; @@ -17,6 +18,7 @@ namespace Artemis.UI.Services public Profile SelectedProfile { get; private set; } public ProfileElement SelectedProfileElement { get; private set; } + public LayerElement SelectedLayerElement { get; private set; } public void ChangeSelectedProfile(Profile profile) { @@ -42,10 +44,17 @@ namespace Artemis.UI.Services OnSelectedProfileElementUpdated(); } + public void ChangeSelectedLayerElement(LayerElement layerElement) + { + SelectedLayerElement = layerElement; + OnSelectedLayerElementChanged(); + } + public event EventHandler SelectedProfileChanged; public event EventHandler SelectedProfileUpdated; public event EventHandler SelectedProfileElementChanged; public event EventHandler SelectedProfileElementUpdated; + public event EventHandler SelectedLayerElementChanged; protected virtual void OnSelectedProfileElementUpdated() { @@ -66,5 +75,10 @@ namespace Artemis.UI.Services { SelectedProfileChanged?.Invoke(this, EventArgs.Empty); } + + protected virtual void OnSelectedLayerElementChanged() + { + SelectedLayerElementChanged?.Invoke(this, EventArgs.Empty); + } } } \ No newline at end of file diff --git a/src/Artemis.UI/packages.config b/src/Artemis.UI/packages.config index 00b1df5f3..73fe590d2 100644 --- a/src/Artemis.UI/packages.config +++ b/src/Artemis.UI/packages.config @@ -1,4 +1,5 @@  + diff --git a/src/Artemis.sln b/src/Artemis.sln index b4da0e2d6..71bccf436 100644 --- a/src/Artemis.sln +++ b/src/Artemis.sln @@ -19,7 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{E830 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.Modules.General", "Artemis.Plugins.Modules.General\Artemis.Plugins.Modules.General.csproj", "{E592F239-FAA0-4840-9C85-46E5867D06D5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.LayerTypes.Brush", "Artemis.Plugins.LayerTypes.Brush\Artemis.Plugins.LayerTypes.Brush.csproj", "{0F288A66-6EB0-4589-8595-E33A3A3EAEA2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.LayerElements.Brush", "Artemis.Plugins.LayerTypes.Brush\Artemis.Plugins.LayerElements.Brush.csproj", "{0F288A66-6EB0-4589-8595-E33A3A3EAEA2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Plugins.Devices.Corsair", "Artemis.Plugins.Devices.Corsair\Artemis.Plugins.Devices.Corsair.csproj", "{A779B2F8-C253-4C4B-8634-6EB8F594E96D}" EndProject