1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2025-12-12 17:48:31 +00:00

Reworked Layouts to be more versatile

This commit is contained in:
Darth Affe 2021-01-31 14:35:06 +01:00
parent 4a170e6af7
commit 6619539176
11 changed files with 223 additions and 122 deletions

View File

@ -13,11 +13,17 @@
<xsd:element name="Shape" type="xsd:string" />
<xsd:element name="Width" type="xsd:double" />
<xsd:element name="Height" type="xsd:double" />
<xsd:element name="ImageBasePath" type="xsd:string" />
<xsd:element name="DeviceImage" type="xsd:string" />
<xsd:element name="LedUnitWidth" type="xsd:double" />
<xsd:element name="LedUnitHeight" type="xsd:double" />
<xsd:element name="Leds">
<xsd:element name="CustomData">
<xsd:complexType>
<xsd:sequence>
<xsd:any />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Leds">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="Led">
@ -28,6 +34,13 @@
<xsd:element name="Y" type="xsd:string" />
<xsd:element name="Width" type="xsd:string" />
<xsd:element name="Height" type="xsd:string" />
<xsd:element name="CustomData">
<xsd:complexType>
<xsd:sequence>
<xsd:any />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="Id" type="xsd:string" use="required" />
</xsd:complexType>
@ -35,32 +48,7 @@
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="LedImageLayouts">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="LedImageLayout">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="LedImages">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="LedImage">
<xsd:complexType>
<xsd:attribute name="Id" type="xsd:string" use="required" />
<xsd:attribute name="Image" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="Layout" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xs:schema>

View File

@ -28,7 +28,7 @@ namespace RGB.NET.Core
/// <summary>
/// Gets the <see cref="Size"/> of the <see cref="IRGBDevice"/>.
/// </summary>
Size Size { get; }
Size Size { get; set; }
/// <summary>
/// Gets the actual <see cref="Size"/> of the <see cref="IRGBDevice"/>.
@ -87,6 +87,10 @@ namespace RGB.NET.Core
/// <param name="flushLeds">Specifies whether all <see cref="Led"/> (including clean ones) should be updated.</param>
void Update(bool flushLeds = false);
Led? AddLed(LedId ledId, Point location, Size size, object? customData = null);
Led? RemoveLed(LedId ledId);
#endregion
}

View File

@ -28,11 +28,8 @@ namespace RGB.NET.Core
/// Gets the model-name of the <see cref="IRGBDevice"/>.
/// </summary>
string Model { get; }
/// <summary>
/// Gets the URI of an image of the <see cref="IRGBDevice"/> or null if there is no image.
/// </summary>
Uri Image { get; set; }
object? LayoutMetadata { get; set; }
#endregion
}

View File

@ -169,6 +169,8 @@ namespace RGB.NET.Core
/// </summary>
public object? CustomData { get; }
public object? LayoutMetadata { get; set; }
#endregion
#region Constructors

View File

@ -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
/// </summary>
[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 <see cref="DeviceLayout"/>.
/// </summary>
[XmlElement("Width")]
public double? Width { get; set; }
public double Width { get; set; }
/// <summary>
/// Gets or sets the height of the <see cref="DeviceLayout"/>.
/// </summary>
[XmlElement("Height")]
public double? Height { get; set; }
public double Height { get; set; }
/// <summary>
/// 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;
/// <summary>
/// The path images for this device are collected in.
/// </summary>
[XmlElement("ImageBasePath")]
public string? ImageBasePath { get; set; }
/// <summary>
/// The image file for this device.
/// </summary>
[XmlElement("DeviceImage")]
public string? DeviceImage { get; set; }
[XmlArray("Leds")]
public List<LedLayout> InternalLeds { get; set; } = new();
/// <summary>
/// Gets or sets a list of <see cref="LedLayout"/> representing all the <see cref="Led"/> of the <see cref="DeviceLayout"/>.
/// </summary>
[XmlArray("Leds")]
public List<LedLayout> Leds { get; set; } = new();
[XmlIgnore]
public IEnumerable<ILedLayout> Leds => InternalLeds;
/// <summary>
/// Gets or sets a list of <see cref="LedImageLayout"/> representing the layouts for the images of all the <see cref="Led"/> of the <see cref="DeviceLayout"/>.
/// </summary>
[XmlArray("LedImageLayouts")]
public List<LedImageLayout> 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
/// </summary>
/// <param name="path">The path to the xml file.</param>
/// <returns>The deserialized <see cref="DeviceLayout"/>.</returns>
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<XmlNode>)?.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
}
}

View File

@ -0,0 +1,55 @@
using System.Collections.Generic;
using RGB.NET.Core;
namespace RGB.NET.Layout
{
public interface IDeviceLayout
{
/// <summary>
/// Gets or sets the name of the <see cref="IDeviceLayout"/>.
/// </summary>
string? Name { get; }
/// <summary>
/// Gets or sets the description of the <see cref="IDeviceLayout"/>.
/// </summary>
string? Description { get; }
/// <summary>
/// Gets or sets the <see cref="RGBDeviceType"/> of the <see cref="IDeviceLayout"/>.
/// </summary>
RGBDeviceType Type { get; }
/// <summary>
/// Gets or sets the vendor of the <see cref="IDeviceLayout"/>.
/// </summary>
string? Vendor { get; }
/// <summary>
/// Gets or sets the model of the <see cref="IDeviceLayout"/>.
/// </summary>
string? Model { get; }
/// <summary>
/// Gets or sets the <see cref="Core.Shape"/> of the <see cref="IDeviceLayout"/>.
/// </summary>
Shape Shape { get; }
/// <summary>
/// Gets or sets the width of the <see cref="IDeviceLayout"/>.
/// </summary>
double Width { get; }
/// <summary>
/// Gets or sets the height of the <see cref="IDeviceLayout"/>.
/// </summary>
double Height { get; }
/// <summary>
/// Gets or sets a list of <see cref="ILedLayout"/> representing all the <see cref="Led"/> of the <see cref="IDeviceLayout"/>.
/// </summary>
IEnumerable<ILedLayout> Leds { get; }
object? CustomData { get; }
}
}

View File

@ -0,0 +1,44 @@
using RGB.NET.Core;
namespace RGB.NET.Layout
{
public interface ILedLayout
{
/// <summary>
/// Gets or sets the Id of the <see cref="LedLayout"/>.
/// </summary>
string? Id { get; }
/// <summary>
/// Gets or sets the <see cref="RGB.NET.Core.Shape"/> of the <see cref="LedLayout"/>.
/// </summary>
Shape Shape { get; }
/// <summary>
/// Gets or sets the vecor-data representing a custom-shape of the <see cref="LedLayout"/>.
/// </summary>
string? ShapeData { get; }
/// <summary>
/// Gets the x-position of the <see cref="LedLayout"/>.
/// </summary>
double X { get; }
/// <summary>
/// Gets the y-position of the <see cref="LedLayout"/>.
/// </summary>
double Y { get; }
/// <summary>
/// Gets the width of the <see cref="LedLayout"/>.
/// </summary>
double Width { get; }
/// <summary>
/// Gets the height of the <see cref="LedLayout"/>.
/// </summary>
double Height { get; }
object? CustomData { get; }
}
}

View File

@ -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<LedId> 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<LedId> ledsToRemove = device.Select(led => led.Id).Where(id => !ledIds.Contains(id)).ToList();
foreach (LedId led in ledsToRemove)
device.RemoveLed(led);
}
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Xml.Serialization;
using RGB.NET.Core;
namespace RGB.NET.Layout
{
/// <summary>
/// Represents the serializable image-data of a specific <see cref="Led"/>.
/// </summary>
[Serializable]
[XmlRoot("LedImage")]
public class LedImage
{
/// <summary>
/// Gets or sets the Id of the <see cref="LedImage"/>.
/// </summary>
[XmlAttribute("Id")]
public string? Id { get; set; }
/// <summary>
/// Gets or sets the image of the <see cref="LedImage"/>.
/// </summary>
[XmlAttribute("Image")]
public string? Image { get; set; }
}
}

View File

@ -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
{
/// <summary>
/// Represents the serializable collection of <see cref="LedImage"/> for a specific layout.
/// </summary>
[Serializable]
[XmlRoot("LedImageLayout")]
public class LedImageLayout
{
/// <summary>
/// Gets or sets the layout of the <see cref="LedImage"/>.
/// </summary>
[XmlAttribute("Layout")]
[DefaultValue(null)]
public string? Layout { get; set; }
/// <summary>
/// Gets or sets a list of <see cref="LedImage"/> representing the images of all the <see cref="Led"/> of the represented layout.
/// </summary>
[XmlArray("LedImages")]
public List<LedImage> LedImages { get; set; } = new();
}
}

View File

@ -11,7 +11,7 @@ namespace RGB.NET.Layout
/// </summary>
[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; }
/// <summary>
/// Gets or sets the <see cref="RGB.NET.Core.Shape"/> of the <see cref="LedLayout"/>.
/// </summary>
@ -74,25 +80,25 @@ namespace RGB.NET.Layout
public string? ShapeData { get; set; }
/// <summary>
/// Gets or sets the x-position of the <see cref="LedLayout"/>.
/// Gets the x-position of the <see cref="LedLayout"/>.
/// </summary>
[XmlIgnore]
public double X { get; private set; }
/// <summary>
/// Gets or sets the y-position of the <see cref="LedLayout"/>.
/// Gets the y-position of the <see cref="LedLayout"/>.
/// </summary>
[XmlIgnore]
public double Y { get; private set; }
/// <summary>
/// Gets or sets the width of the <see cref="LedLayout"/>.
/// Gets the width of the <see cref="LedLayout"/>.
/// </summary>
[XmlIgnore]
public double Width { get; private set; }
/// <summary>
/// Gets or sets the height of the <see cref="LedLayout"/>.
/// Gets the height of the <see cref="LedLayout"/>.
/// </summary>
[XmlIgnore]
public double Height { get; private set; }
@ -106,7 +112,7 @@ namespace RGB.NET.Layout
/// </summary>
/// <param name="device">The <see cref="DeviceLayout"/> this <see cref="LedLayout"/> belongs to.</param>
/// <param name="lastLed">The <see cref="LedLayout"/> previously calculated.</param>
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
{