Editor/Road/ArchRoadHandlers.cs
namespace Sunless.Architecture;
public sealed class ArchBridgeHandler : IArchHandler {
public ArchKind Kind => ArchKind.Bridge;
public bool Draw( ArchTool tool, ArchSelection picked ) {
return picked.Item is ArchBridgePart bridge
&& ArchRoadSpanHandler.Draw( tool, ArchGesture.On( ArchKind.Bridge, bridge.Id ), tool.Plan.RoadCarrying( bridge ),
bridge.From, bridge.To, ArchBridge.ShortestSpan, Color.Orange,
from => bridge.From = from, to => bridge.To = to );
}
}
public sealed class ArchTunnelHandler : IArchHandler {
public ArchKind Kind => ArchKind.Tunnel;
public bool Draw( ArchTool tool, ArchSelection picked ) {
return picked.Item is ArchTunnelPart tunnel
&& ArchRoadSpanHandler.Draw( tool, ArchGesture.On( ArchKind.Tunnel, tunnel.Id ), tool.Plan.RoadHolding( tunnel ),
tunnel.From, tunnel.To, ArchTunnel.ShortestBore, Color.Cyan,
from => tunnel.From = from, to => tunnel.To = to );
}
}
static class ArchRoadSpanHandler {
public static bool Draw( ArchTool tool, ArchGesture gesture, ArchRoadPart road, float from, float to, float shortest, Color tint,
Action<float> setFrom, Action<float> setTo ) {
if ( road is null || !tool.Resolved( road.Id, road.Curve ).IsUsable ) {
return false;
}
var curve = tool.Resolved( road.Id, road.Curve );
var changed = false;
var middle = (from + to) * 0.5f;
// The span travels whole: one delta moves both ends, so a bridge keeps its length wherever it is slid to.
if ( ArchShapeHandles.Slid( tool, gesture.At( "slide" ), curve, middle, out var delta, Gizmo.Colors.Blue ) ) {
setFrom( Math.Clamp( from + delta, 0f, curve.Length ) );
setTo( Math.Clamp( to + delta, 0f, curve.Length ) );
changed = true;
}
if ( ArchShapeHandles.Station( tool, gesture.At( "from" ), curve, from, out var landedFrom, tint ) ) {
setFrom( Math.Clamp( landedFrom, 0f, to - shortest ) );
changed = true;
}
if ( ArchShapeHandles.Station( tool, gesture.At( "to" ), curve, to, out var landedTo, tint ) ) {
setTo( Math.Clamp( landedTo, from + shortest, curve.Length ) );
changed = true;
}
return changed;
}
}