53 lines
2.4 KiB
C#
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;
|
|
}
|
|
}
|