Editor/InteriorLayoutBuilder/RoomLayoutTool.FloorCutouts.cs
using System;
using System.Linq;
using Editor;
using Sandbox;
namespace ReusableRoomLayout;
public sealed partial class RoomLayoutTool
{
private RoomLayoutFloorCutout SelectedFloorCutout()
{
return selectedFloorCutoutId == 0
? null
: document.FloorCutouts.FirstOrDefault( cutout => cutout.Id == selectedFloorCutoutId );
}
private void HandleFloorCutoutMouse( Vector2 cursor, bool selectedLayoutAtCursor )
{
if ( Gizmo.WasLeftMousePressed )
{
if ( TryFindFloorCutout( cursor, out var cutout ) )
{
SelectFloorCutout( cutout );
movingFloorCutout = true;
BeginLayoutEdit();
dragStart = cursor;
moveStartBounds = cutout.Bounds;
return;
}
if ( selectedLayoutAtCursor )
{
return;
}
selectedRoomId = 0;
selectedDoorId = 0;
selectedWindowId = 0;
selectedCorridorId = 0;
selectedFloorCutoutId = 0;
drawingFloorCutout = true;
dragStart = cursor;
dragCurrent = cursor;
}
if ( drawingFloorCutout )
{
dragCurrent = cursor;
if ( Gizmo.WasLeftMouseReleased )
{
CommitDrawnFloorCutout();
}
return;
}
if ( movingFloorCutout )
{
MoveSelectedFloorCutoutByDrag( cursor );
if ( Gizmo.WasLeftMouseReleased )
{
movingFloorCutout = false;
CommitLayoutEdit();
}
}
}
private void CommitDrawnFloorCutout()
{
var bounds = SnapRect( RoomLayoutRect.FromPoints( dragStart, dragCurrent ) );
drawingFloorCutout = false;
if ( bounds.Width < document.Settings.GridSize || bounds.Height < document.Settings.GridSize )
{
return;
}
var cutout = new RoomLayoutFloorCutout
{
Id = document.AllocateId(),
Floor = activeFloor,
Name = $"Floor Cutout {document.FloorCutouts.Count + 1}",
Bounds = bounds
};
PushLayoutUndo();
document.FloorCutouts.Add( cutout );
SelectFloorCutout( cutout );
CommitLayoutChange();
}
private void MoveSelectedFloorCutoutByDrag( Vector2 cursor )
{
if ( SelectedFloorCutout() is not { } cutout )
{
movingFloorCutout = false;
return;
}
var delta = cursor - dragStart;
cutout.Bounds = SnapRect( moveStartBounds.MovedBy( delta ) );
}
private void SelectFloorCutout( RoomLayoutFloorCutout cutout )
{
selectedRoomId = 0;
selectedDoorId = 0;
selectedWindowId = 0;
selectedCorridorId = 0;
selectedFloorCutoutId = cutout.Id;
SetActiveFloorFromSelection();
}
private bool TryFindFloorCutout( Vector2 point, out RoomLayoutFloorCutout cutout )
{
cutout = document.FloorCutouts.LastOrDefault( candidate => IsActiveFloor( candidate ) && candidate.Bounds.Contains( point ) );
return cutout is not null;
}
}