Editor dock panel for the Advanced Mapping Tools addon. Shows a property sheet for array and mirror settings and runs Arrange.Array or Arrange.Mirror on the current scene selection.
namespace AdvancedMappingTools;
/// <summary>
/// The settings of the arrange panel. Kept for the session, so the next array uses the same.
/// </summary>
public sealed class ArrangeSettings
{
[Property, Group( "Array" ), Range( 1, 256, slider: false ), WideMode, Description( "How many copies come after the original." )]
public int Copies { get; set; } = 3;
[Property, Group( "Array" ), WideMode, Description( "How far each copy is from the one before, in world units." )]
public Vector3 Offset { get; set; } = new( 256, 0, 0 );
[Property, Group( "Array" ), Title( "Turn Per Copy" ), Range( -180, 180, slider: false ), WideMode, Description( "Degrees each copy turns more than the one before, around its own position." )]
public float Yaw { get; set; } = 0.0f;
[Property, Group( "Mirror" ), WideMode]
public MirrorAxis Axis { get; set; } = MirrorAxis.X;
}
/// <summary>
/// Copies in a row and mirror images of the selected objects.
/// Open it from the View menu of the editor and dock it wherever you like.
/// </summary>
[Dock( "Editor", "Davelix Arrange", "content_copy" )]
public sealed class ArrangePanel : Widget
{
static readonly ArrangeSettings Settings = new();
public ArrangePanel( Widget parent ) : base( parent )
{
Layout = Layout.Column();
Layout.Margin = 4;
var scroll = Layout.Add( new ScrollArea( this ), 1 );
var sheet = new ToolSidebarWidget( scroll );
scroll.Canvas = sheet;
PropertySheet.Fill( sheet, Settings.GetSerialized(), "Array" );
var actions = sheet.AddGroup( "Apply" );
actions.Add( new ListButton( "Array Selected", "view_week" ) { ToolTip = "Copies of every selected object, one undo step.", Clicked = ArraySelected } );
actions.Add( new ListButton( "Mirror Selected", "flip" ) { ToolTip = "Reflects selected objects drawn with a builder across their own middle.", Clicked = MirrorSelected } );
sheet.Layout.AddStretchCell();
}
static List<GameObject> Selected() =>
SceneEditorSession.Active is null ? [] : [.. SceneEditorSession.Active.Selection.OfType<GameObject>()];
static void ArraySelected()
{
var made = Arrange.Array( Selected(), Settings.Copies, Settings.Offset, Settings.Yaw );
if ( made.Count == 0 ) Log.Warning( "Select one or more objects first." );
}
static void MirrorSelected()
{
var selected = Selected();
if ( selected.Count == 0 )
{
Log.Warning( "Select one or more objects first." );
return;
}
foreach ( var go in selected )
{
if ( Arrange.Mirror( go, Settings.Axis ) is string problem ) Log.Warning( problem );
}
}
}