129 lines
3.8 KiB
C#
129 lines
3.8 KiB
C#
using System.Numerics;
|
|
|
|
namespace Dashboard
|
|
{
|
|
public record struct LayoutUnits(LayoutUnit All)
|
|
{
|
|
public LayoutUnit XUnit
|
|
{
|
|
get => (LayoutUnit)(((int)All & 0xF) >> 0);
|
|
set => All = (LayoutUnit)(((int)All & ~(0xF << 0)) | ((int)value << 0));
|
|
}
|
|
|
|
public LayoutUnit YUnit
|
|
{
|
|
get => (LayoutUnit)(((int)All & 0xF) >> 4);
|
|
set => All = (LayoutUnit)(((int)All & ~(0xF << 4)) | ((int)value << 4));
|
|
}
|
|
|
|
public LayoutUnit ZUnit
|
|
{
|
|
get => (LayoutUnit)(((int)All & 0xF) >> 8);
|
|
set => All = (LayoutUnit)(((int)All & ~(0xF << 8)) | ((int)value << 8));
|
|
}
|
|
|
|
public LayoutUnit WUnit
|
|
{
|
|
get => (LayoutUnit)(((int)All & 0xF) >> 12);
|
|
set => All = (LayoutUnit)(((int)All & ~(0xF << 12)) | ((int)value << 12));
|
|
}
|
|
}
|
|
|
|
public record struct Metric(LayoutUnit Units, float Value)
|
|
{
|
|
public float Compute(float dpi, float rel, float star)
|
|
{
|
|
switch (Units)
|
|
{
|
|
case LayoutUnit.Auto:
|
|
return -1;
|
|
case LayoutUnit.Millimeter:
|
|
float mm2Px = dpi / 25.4f;
|
|
return Value * mm2Px;
|
|
case LayoutUnit.Pixel:
|
|
return Value;
|
|
case LayoutUnit.Point:
|
|
float pt2Px = 72 / dpi;
|
|
return Value * pt2Px;
|
|
case LayoutUnit.Percent:
|
|
return rel * Value;
|
|
case LayoutUnit.Star:
|
|
return star * Value;
|
|
default:
|
|
throw new Exception("Unrecognized unit.");
|
|
}
|
|
}
|
|
}
|
|
|
|
public record struct Metric2D(LayoutUnits Units, Vector2 Value)
|
|
{
|
|
public float X
|
|
{
|
|
get => Value.X;
|
|
set => Value = new Vector2(value, Value.Y);
|
|
}
|
|
|
|
public LayoutUnit XUnits
|
|
{
|
|
get => Units.XUnit;
|
|
set => Units = Units with { XUnit = value };
|
|
}
|
|
|
|
public float Y
|
|
{
|
|
get => Value.Y;
|
|
set => Value = new Vector2(Value.X, value);
|
|
}
|
|
|
|
public LayoutUnit YUnits
|
|
{
|
|
get => Units.YUnit;
|
|
set => Units = Units with { YUnit = value };
|
|
}
|
|
}
|
|
|
|
public record struct BoxMetric(LayoutUnit Units, Box2d Value);
|
|
|
|
public record struct AdvancedMetric(LayoutUnit Unit, float Value)
|
|
{
|
|
public AdvancedMetric Convert(LayoutUnit target, float dpi, float rel, int stars)
|
|
{
|
|
if (Unit == target)
|
|
return this;
|
|
|
|
float pixels = Unit switch {
|
|
LayoutUnit.Pixel => Value,
|
|
LayoutUnit.Point => Value * (72f / dpi),
|
|
LayoutUnit.Millimeter => Value * (28.3464566929f / dpi),
|
|
LayoutUnit.Star => Value * rel / stars,
|
|
LayoutUnit.Percent => Value * rel / 100,
|
|
_ => throw new Exception(),
|
|
};
|
|
|
|
float value = target switch {
|
|
LayoutUnit.Pixel => pixels,
|
|
LayoutUnit.Point => Value * (dpi / 72f),
|
|
// MeasurementUnit.Millimeter =>
|
|
};
|
|
|
|
return new AdvancedMetric(target, value);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Value} {Unit.ToShortString()}";
|
|
}
|
|
|
|
public static bool TryParse(ReadOnlySpan<char> str, out AdvancedMetric metric)
|
|
{
|
|
metric = default;
|
|
return false;
|
|
}
|
|
|
|
public static AdvancedMetric Parse(ReadOnlySpan<char> str) =>
|
|
TryParse(str, out AdvancedMetric metric)
|
|
? metric
|
|
: throw new Exception($"Could not parse the value '{str}'.");
|
|
}
|
|
}
|