Editor context action for stairs in the architecture editor. It finds a stair part under the cursor and populates a context menu with options to change balustrade (StairGuard), wall handrail, top landing railing, and underside (StairUnder), applying changes via context.Tool.Commit.
namespace Sunless.Architecture;
public sealed class ArchStairContextAction : IArchContextAction
{
public ArchKind Kind => ArchKind.Stair;
public bool Build( ArchContextActionContext context )
{
var hit = ArchPick.HitsAt( context.Tool.LayerTree, context.Tool.Kit, context.Level, context.Point )
.FirstOrDefault( candidate => candidate.Layer.Kind == ArchKind.Stair );
var node = context.Tool.LayerTree.Find( hit?.Layer.ItemId ?? 0 );
if ( node?.Payload is not ArchStairPart stair || node.Room?.Stairs.Contains( stair ) != true )
{
return false;
}
var sides = context.Menu.AddMenu( $"{stair.Name} balustrade", "fence" );
foreach ( var value in Enum.GetValues<StairGuard>() )
{
var captured = value;
var option = sides.AddOption( captured.ToString(), null,
() => { stair.Guard = captured; context.Tool.Commit( "Stair Balustrade" ); } );
option.Checkable = true;
option.Checked = stair.Guard == captured;
}
var wallRail = sides.AddOption( "Handrail on walled sides", null,
() => { stair.WallRail = !stair.WallRail; context.Tool.Commit( "Stair Wall Rail" ); } );
wallRail.Checkable = true;
wallRail.Checked = stair.WallRail;
var guard = context.Menu.AddOption( "Top landing railing", "vertical_align_top",
() => { stair.WellGuard = !stair.WellGuard; context.Tool.Commit( "Stair Well Guard" ); } );
guard.Checkable = true;
guard.Checked = stair.WellGuard;
var under = context.Menu.AddMenu( $"{stair.Name} underside", "door_front" );
foreach ( var value in Enum.GetValues<StairUnder>() )
{
var captured = value;
var option = under.AddOption( captured.ToString(), null,
() => { stair.Under = captured; context.Tool.Commit( "Stair Underside" ); } );
option.Checkable = true;
option.Checked = stair.Under == captured;
}
context.Menu.AddSeparator();
return true;
}
}