Files
Dashboard/Dashboard.Common/Measure.cs

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}'.");
}
}