Lumi/companion/src/Lumi.Companion.App/LumiIconFactory.cs
2026-07-22 11:39:05 +02:00

53 lines
2.4 KiB
C#

using Avalonia.Controls;
namespace Lumi.Companion.App;
internal static class LumiIconFactory
{
public static WindowIcon Create(TrayHealth health)
{
const int size = 32;
var color = health switch
{
TrayHealth.Operating => (R: (byte)35, G: (byte)132, B: (byte)91),
TrayHealth.Degraded => (R: (byte)169, G: (byte)102, B: (byte)18),
TrayHealth.Failed => (R: (byte)189, G: (byte)77, B: (byte)77),
_ => (R: (byte)79, G: (byte)182, B: (byte)194)
};
var pixels = new byte[size * size * 4];
for (var y = 0; y < size; y++)
for (var x = 0; x < size; x++)
{
var target = ((size - 1 - y) * size + x) * 4;
var rounded = InsideRoundedSquare(x, y, size, 7);
var diamond = Math.Abs(x - 15.5) / 11.5 + Math.Abs(y - 15.5) / 11.5 <= 1;
pixels[target] = diamond && rounded ? (byte)255 : color.B;
pixels[target + 1] = diamond && rounded ? (byte)255 : color.G;
pixels[target + 2] = diamond && rounded ? (byte)255 : color.R;
pixels[target + 3] = rounded ? (byte)255 : (byte)0;
}
using var stream = new MemoryStream();
using var writer = new BinaryWriter(stream, System.Text.Encoding.UTF8, leaveOpen: true);
writer.Write((ushort)0); writer.Write((ushort)1); writer.Write((ushort)1);
writer.Write((byte)size); writer.Write((byte)size); writer.Write((byte)0); writer.Write((byte)0);
writer.Write((ushort)1); writer.Write((ushort)32);
var imageBytes = 40 + pixels.Length + size * 4;
writer.Write(imageBytes); writer.Write(22);
writer.Write(40); writer.Write(size); writer.Write(size * 2); writer.Write((ushort)1); writer.Write((ushort)32);
writer.Write(0); writer.Write(pixels.Length); writer.Write(0); writer.Write(0); writer.Write(0); writer.Write(0);
writer.Write(pixels); writer.Write(new byte[size * 4]);
stream.Position = 0;
return new WindowIcon(stream);
}
private static bool InsideRoundedSquare(int x, int y, int size, int radius)
{
if (x >= radius && x < size - radius || y >= radius && y < size - radius) return true;
var cx = x < radius ? radius : size - radius - 1;
var cy = y < radius ? radius : size - radius - 1;
var dx = x - cx; var dy = y - cy;
return dx * dx + dy * dy <= radius * radius;
}
}