Editor/Porch/ArchPorchInteractions.cs
namespace Sunless.Architecture;
public sealed class ArchPorchHandler : IArchHandler {
public ArchKind Kind => ArchKind.Porch;
public bool Draw( ArchTool tool, ArchSelection picked ) {
if ( picked.Item is not ArchPorchPart porch ) {
return false;
}
var outline = ArchPorch.Footprint( porch );
var middle = Middle( outline );
var gesture = ArchGesture.On( ArchKind.Porch, porch.Id );
var changed = false;
if ( ArchShapeHandles.Height( tool, gesture.At( "head" ), middle, porch.BaseHeight + porch.HeadHeight, out var head, Gizmo.Colors.Roll ) ) {
porch.HeadHeight = MathF.Max( 24f, head - porch.BaseHeight );
changed = true;
}
if ( ArchShapeHandles.Height( tool, gesture.At( "deck" ), middle, porch.BaseHeight, out var deck, Gizmo.Colors.Pitch ) ) {
porch.BaseHeight = deck;
changed = true;
}
return changed;
}
static Vector2 Middle( IReadOnlyList<Vector2> outline ) {
if ( outline is not { Count: > 0 } ) {
return Vector2.Zero;
}
ArchFootprint.Bounds( outline, out var min, out var max );
return (min + max) * 0.5f;
}
}
public sealed class ArchPorchPicker : IArchPicker {
public ArchKind Kind => ArchKind.Porch;
public void Under( ArchPicking picking ) {
if ( picking.Node.Payload is not ArchPorchPart porch ) {
return;
}
ArchPorch.Bounds( porch, out var min, out var max );
if ( ArchFootprint.Contains( ArchFootprint.Rect( min, max ), picking.Point ) ) {
picking.Hit( ArchHitChannel.Volume, 0f, true );
}
}
}
public sealed class ArchPorchExtentProvider : IArchExtentProvider {
public ArchKind Kind => ArchKind.Porch;
public ArchExtent Measure( object payload, ArchExtentContext context ) {
var extent = new ArchExtent();
if ( payload is not ArchPorchPart porch ) {
return extent;
}
foreach ( var leg in porch.Legs ) {
extent.Add( ArchFootprint.Rect( leg.Min, leg.Max ), porch.GradeHeight - 8f, porch.BaseHeight + porch.HeadHeight + 48f );
}
return extent;
}
}