diff --git a/Documentation/DeviceLayout.xsd b/Documentation/DeviceLayout.xsd
index 91ced39..d534089 100644
--- a/Documentation/DeviceLayout.xsd
+++ b/Documentation/DeviceLayout.xsd
@@ -13,11 +13,17 @@
-
-
-
+
+
+
+
+
+
+
+
+
@@ -28,6 +34,13 @@
+
+
+
+
+
+
+
@@ -35,32 +48,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/RGB.NET.Core/Devices/IRGBDevice.cs b/RGB.NET.Core/Devices/IRGBDevice.cs
index b979a1c..7103773 100644
--- a/RGB.NET.Core/Devices/IRGBDevice.cs
+++ b/RGB.NET.Core/Devices/IRGBDevice.cs
@@ -28,7 +28,7 @@ namespace RGB.NET.Core
///
/// Gets the of the .
///
- Size Size { get; }
+ Size Size { get; set; }
///
/// Gets the actual of the .
@@ -87,6 +87,10 @@ namespace RGB.NET.Core
/// Specifies whether all (including clean ones) should be updated.
void Update(bool flushLeds = false);
+ Led? AddLed(LedId ledId, Point location, Size size, object? customData = null);
+
+ Led? RemoveLed(LedId ledId);
+
#endregion
}
diff --git a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs
index 41379ff..8bf1d90 100644
--- a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs
+++ b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs
@@ -28,11 +28,8 @@ namespace RGB.NET.Core
/// Gets the model-name of the .
///
string Model { get; }
-
- ///
- /// Gets the URI of an image of the or null if there is no image.
- ///
- Uri Image { get; set; }
+
+ object? LayoutMetadata { get; set; }
#endregion
}
diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs
index 7613fb2..9766043 100644
--- a/RGB.NET.Core/Leds/Led.cs
+++ b/RGB.NET.Core/Leds/Led.cs
@@ -169,6 +169,8 @@ namespace RGB.NET.Core
///
public object? CustomData { get; }
+ public object? LayoutMetadata { get; set; }
+
#endregion
#region Constructors
diff --git a/RGB.NET.Layout/DeviceLayout.cs b/RGB.NET.Layout/DeviceLayout.cs
index dc87418..2f34028 100644
--- a/RGB.NET.Layout/DeviceLayout.cs
+++ b/RGB.NET.Layout/DeviceLayout.cs
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
+using System.Linq;
+using System.Xml;
using System.Xml.Serialization;
using RGB.NET.Core;
@@ -12,7 +14,7 @@ namespace RGB.NET.Layout
///
[Serializable]
[XmlRoot("Device")]
- public class DeviceLayout
+ public class DeviceLayout : IDeviceLayout
{
#region Properties & Fields
@@ -57,13 +59,13 @@ namespace RGB.NET.Layout
/// Gets or sets the width of the .
///
[XmlElement("Width")]
- public double? Width { get; set; }
+ public double Width { get; set; }
///
/// Gets or sets the height of the .
///
[XmlElement("Height")]
- public double? Height { get; set; }
+ public double Height { get; set; }
///
/// Gets or sets the width of one 'unit' used for the calculation of led positions and sizes.
@@ -79,29 +81,20 @@ namespace RGB.NET.Layout
[DefaultValue(19.0)]
public double LedUnitHeight { get; set; } = 19.0;
- ///
- /// The path images for this device are collected in.
- ///
- [XmlElement("ImageBasePath")]
- public string? ImageBasePath { get; set; }
-
- ///
- /// The image file for this device.
- ///
- [XmlElement("DeviceImage")]
- public string? DeviceImage { get; set; }
+ [XmlArray("Leds")]
+ public List InternalLeds { get; set; } = new();
///
/// Gets or sets a list of representing all the of the .
///
- [XmlArray("Leds")]
- public List Leds { get; set; } = new();
+ [XmlIgnore]
+ public IEnumerable Leds => InternalLeds;
- ///
- /// Gets or sets a list of representing the layouts for the images of all the of the .
- ///
- [XmlArray("LedImageLayouts")]
- public List LedImageLayouts { get; set; } = new();
+ [XmlElement("CustomData")]
+ public object? InternalCustomData { get; set; }
+
+ [XmlIgnore]
+ public object? CustomData { get; set; }
#endregion
@@ -112,7 +105,7 @@ namespace RGB.NET.Layout
///
/// The path to the xml file.
/// The deserialized .
- public static DeviceLayout? Load(string path)
+ public static DeviceLayout? Load(string path, Type? customDeviceDataType = null, Type? customLedDataType = null)
{
if (!File.Exists(path)) return null;
@@ -122,13 +115,18 @@ namespace RGB.NET.Layout
using StreamReader reader = new(path);
DeviceLayout? layout = serializer.Deserialize(reader) as DeviceLayout;
- if (layout?.Leds != null)
+ if (layout != null)
+ layout.CustomData = layout.GetCustomData(layout.InternalCustomData, customDeviceDataType);
+
+ if (layout?.InternalLeds != null)
{
LedLayout? lastLed = null;
- foreach (LedLayout led in layout.Leds)
+ foreach (LedLayout led in layout.InternalLeds)
{
led.CalculateValues(layout, lastLed);
lastLed = led;
+
+ led.CustomData = layout.GetCustomData(led.InternalCustomData, customLedDataType);
}
}
@@ -140,6 +138,23 @@ namespace RGB.NET.Layout
}
}
+ protected virtual object? GetCustomData(object? customData, Type? type)
+ {
+ XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable)?.FirstOrDefault()?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node
+ if ((node == null) || (type == null)) return null;
+
+ if (type == null) return null;
+
+ using MemoryStream ms = new();
+ using StreamWriter writer = new(ms);
+
+ writer.Write(node.OuterXml);
+ writer.Flush();
+ ms.Seek(0, SeekOrigin.Begin);
+
+ return new XmlSerializer(type).Deserialize(ms);
+ }
+
#endregion
}
}
diff --git a/RGB.NET.Layout/IDeviceLayout.cs b/RGB.NET.Layout/IDeviceLayout.cs
new file mode 100644
index 0000000..c06d9d9
--- /dev/null
+++ b/RGB.NET.Layout/IDeviceLayout.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using RGB.NET.Core;
+
+namespace RGB.NET.Layout
+{
+ public interface IDeviceLayout
+ {
+ ///
+ /// Gets or sets the name of the .
+ ///
+ string? Name { get; }
+
+ ///
+ /// Gets or sets the description of the .
+ ///
+ string? Description { get; }
+
+ ///
+ /// Gets or sets the of the .
+ ///
+ RGBDeviceType Type { get; }
+
+ ///
+ /// Gets or sets the vendor of the .
+ ///
+ string? Vendor { get; }
+
+ ///
+ /// Gets or sets the model of the .
+ ///
+ string? Model { get; }
+
+ ///
+ /// Gets or sets the of the .
+ ///
+ Shape Shape { get; }
+
+ ///
+ /// Gets or sets the width of the .
+ ///
+ double Width { get; }
+
+ ///
+ /// Gets or sets the height of the .
+ ///
+ double Height { get; }
+
+ ///
+ /// Gets or sets a list of representing all the of the .
+ ///
+ IEnumerable Leds { get; }
+
+ object? CustomData { get; }
+ }
+}
diff --git a/RGB.NET.Layout/ILedLayout.cs b/RGB.NET.Layout/ILedLayout.cs
new file mode 100644
index 0000000..3747a97
--- /dev/null
+++ b/RGB.NET.Layout/ILedLayout.cs
@@ -0,0 +1,44 @@
+using RGB.NET.Core;
+
+namespace RGB.NET.Layout
+{
+ public interface ILedLayout
+ {
+ ///
+ /// Gets or sets the Id of the .
+ ///
+ string? Id { get; }
+
+ ///
+ /// Gets or sets the of the .
+ ///
+ Shape Shape { get; }
+
+ ///
+ /// Gets or sets the vecor-data representing a custom-shape of the .
+ ///
+ string? ShapeData { get; }
+
+ ///
+ /// Gets the x-position of the .
+ ///
+ double X { get; }
+
+ ///
+ /// Gets the y-position of the .
+ ///
+ double Y { get; }
+
+ ///
+ /// Gets the width of the .
+ ///
+ double Width { get; }
+
+ ///
+ /// Gets the height of the .
+ ///
+ double Height { get; }
+
+ object? CustomData { get; }
+ }
+}
diff --git a/RGB.NET.Layout/LayoutExtension.cs b/RGB.NET.Layout/LayoutExtension.cs
new file mode 100644
index 0000000..ec88f27
--- /dev/null
+++ b/RGB.NET.Layout/LayoutExtension.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using RGB.NET.Core;
+
+namespace RGB.NET.Layout
+{
+ public static class LayoutExtension
+ {
+ public static void ApplyTo(this IDeviceLayout layout, IRGBDevice device, bool createMissingLeds = false, bool removeExcessiveLeds = false)
+ {
+ device.Size = new Size(layout.Width, layout.Height);
+ device.DeviceInfo.LayoutMetadata = layout.CustomData;
+
+ HashSet ledIds = new();
+ foreach (ILedLayout layoutLed in layout.Leds)
+ {
+ if (Enum.TryParse(layoutLed.Id, true, out LedId ledId))
+ {
+ ledIds.Add(ledId);
+
+ Led? led = device[ledId];
+ if ((led == null) && createMissingLeds)
+ led = device.AddLed(ledId, new Point(), new Size());
+
+ if (led != null)
+ {
+ led.Location = new Point(layoutLed.X, layoutLed.Y);
+ led.Size = new Size(layoutLed.Width, layoutLed.Height);
+ led.Shape = layoutLed.Shape;
+ led.ShapeData = layoutLed.ShapeData;
+ led.LayoutMetadata = layoutLed.CustomData;
+ }
+ }
+ }
+
+ if (removeExcessiveLeds)
+ {
+ List ledsToRemove = device.Select(led => led.Id).Where(id => !ledIds.Contains(id)).ToList();
+ foreach (LedId led in ledsToRemove)
+ device.RemoveLed(led);
+ }
+ }
+ }
+}
diff --git a/RGB.NET.Layout/LedImage.cs b/RGB.NET.Layout/LedImage.cs
deleted file mode 100644
index 997ac52..0000000
--- a/RGB.NET.Layout/LedImage.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Xml.Serialization;
-using RGB.NET.Core;
-
-namespace RGB.NET.Layout
-{
- ///
- /// Represents the serializable image-data of a specific .
- ///
- [Serializable]
- [XmlRoot("LedImage")]
- public class LedImage
- {
- ///
- /// Gets or sets the Id of the .
- ///
- [XmlAttribute("Id")]
- public string? Id { get; set; }
-
- ///
- /// Gets or sets the image of the .
- ///
- [XmlAttribute("Image")]
- public string? Image { get; set; }
- }
-}
diff --git a/RGB.NET.Layout/LedImageLayout.cs b/RGB.NET.Layout/LedImageLayout.cs
deleted file mode 100644
index 8c0b776..0000000
--- a/RGB.NET.Layout/LedImageLayout.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Xml.Serialization;
-using RGB.NET.Core;
-
-namespace RGB.NET.Layout
-{
- ///
- /// Represents the serializable collection of for a specific layout.
- ///
- [Serializable]
- [XmlRoot("LedImageLayout")]
- public class LedImageLayout
- {
- ///
- /// Gets or sets the layout of the .
- ///
- [XmlAttribute("Layout")]
- [DefaultValue(null)]
- public string? Layout { get; set; }
-
- ///
- /// Gets or sets a list of representing the images of all the of the represented layout.
- ///
- [XmlArray("LedImages")]
- public List LedImages { get; set; } = new();
- }
-}
diff --git a/RGB.NET.Layout/LedLayout.cs b/RGB.NET.Layout/LedLayout.cs
index 3447f61..3bab36c 100644
--- a/RGB.NET.Layout/LedLayout.cs
+++ b/RGB.NET.Layout/LedLayout.cs
@@ -11,7 +11,7 @@ namespace RGB.NET.Layout
///
[Serializable]
[XmlType("Led")]
- public class LedLayout
+ public class LedLayout : ILedLayout
{
#region Properties & Fields
@@ -61,6 +61,12 @@ namespace RGB.NET.Layout
[DefaultValue("1.0")]
public string DescriptiveHeight { get; set; } = "1.0";
+ [XmlElement("CustomData")]
+ public object? InternalCustomData { get; set; }
+
+ [XmlIgnore]
+ public object? CustomData { get; set; }
+
///
/// Gets or sets the of the .
///
@@ -74,25 +80,25 @@ namespace RGB.NET.Layout
public string? ShapeData { get; set; }
///
- /// Gets or sets the x-position of the .
+ /// Gets the x-position of the .
///
[XmlIgnore]
public double X { get; private set; }
///
- /// Gets or sets the y-position of the .
+ /// Gets the y-position of the .
///
[XmlIgnore]
public double Y { get; private set; }
///
- /// Gets or sets the width of the .
+ /// Gets the width of the .
///
[XmlIgnore]
public double Width { get; private set; }
///
- /// Gets or sets the height of the .
+ /// Gets the height of the .
///
[XmlIgnore]
public double Height { get; private set; }
@@ -106,7 +112,7 @@ namespace RGB.NET.Layout
///
/// The this belongs to.
/// The previously calculated.
- public void CalculateValues(DeviceLayout device, LedLayout? lastLed)
+ public virtual void CalculateValues(DeviceLayout device, LedLayout? lastLed)
{
if (!Enum.TryParse(DescriptiveShape, true, out Shape shape))
{
@@ -122,7 +128,7 @@ namespace RGB.NET.Layout
Y = GetLocationValue(DescriptiveY, lastLed?.Y ?? 0, Height, lastLed?.Height ?? 0);
}
- private double GetLocationValue(string value, double lastValue, double currentSize, double lastSize)
+ protected virtual double GetLocationValue(string value, double lastValue, double currentSize, double lastSize)
{
try
{
@@ -159,7 +165,7 @@ namespace RGB.NET.Layout
}
}
- private double GetSizeValue(string value, double unitSize)
+ protected virtual double GetSizeValue(string value, double unitSize)
{
try
{