Editor/Tileset/TilesetTools/LayerControl/TilesetLayerListControl.cs
using Sandbox;
using Editor;
using System.Collections.Generic;
using System.Linq;
using System;
namespace SpriteTools.TilesetTool;
[CustomEditor(typeof(List<TilesetComponent.Layer>))]
public class TilesetLayerListControl : ControlWidget
{
public override bool SupportsMultiEdit => false;
public override bool IncludeLabel => false;
internal List<TilesetLayerControl> LayerControls = new();
Layout content;
ScrollArea scrollArea;
public TilesetLayerListControl(SerializedProperty property) : base(property)
{
Layout = Layout.Column();
if (property.IsNull)
{
property.SetValue(new List<TilesetComponent.Layer>());
}
scrollArea = new ScrollArea(this);
scrollArea.Canvas = new Widget();
scrollArea.Canvas.Layout = Layout.Column();
scrollArea.Canvas.VerticalSizeMode = SizeMode.CanShrink;
scrollArea.Canvas.HorizontalSizeMode = SizeMode.CanGrow;
scrollArea.MinimumHeight = 157;
scrollArea.MaximumHeight = 157;
scrollArea.FixedHeight = 157;
Layout.Add(scrollArea);
// Content list
content = Layout.Column();
content.Margin = 4;
content.AddStretchCell();
scrollArea.Canvas.Layout.Add(content);
// Add button
if (TilesetTool.Active is not null)
{
var row = Layout.AddRow();
row.AddStretchCell();
row.Margin = 16;
var btnAdd = row.Add(new Button.Primary("Create New Layer", "add"));
btnAdd.HorizontalSizeMode = SizeMode.CanGrow;
btnAdd.Clicked = CreateNewLayer;
row.AddStretchCell();
var btnBake = row.Add(new Button("Bake Selected Layer", "palette"));
btnBake.HorizontalSizeMode = SizeMode.CanGrow;
btnBake.Clicked = BakeSelectedLayerPopup;
row.AddStretchCell();
}
scrollArea.Canvas.Layout.AddStretchCell();
SetSizeMode(SizeMode.Default, SizeMode.CanShrink);
UpdateList();
}
protected override void OnPaint()
{
Paint.SetBrush(Theme.ControlBackground);
Paint.SetPen(Theme.ControlBackground);
Paint.DrawRect(scrollArea.LocalRect, 4);
}
public void UpdateList()
{
content.Clear(true);
LayerControls.Clear();
var layers = SerializedProperty.GetValue<List<TilesetComponent.Layer>>();
var collisionLayer = layers.FirstOrDefault(x => x.IsCollisionLayer);
int index = 0;
foreach (var layer in layers)
{
var button = content.Add(new TilesetLayerControl(this, layer));
if (collisionLayer is null && index == 0) button.icoCollisionLayer.Visible = true;
else if (layer == collisionLayer) button.icoCollisionLayer.Visible = true;
button.MouseClick = () => SelectLayer(layer);
LayerControls.Add(button);
index++;
}
}
void CreateNewLayer()
{
var layers = SerializedProperty.GetValue<List<TilesetComponent.Layer>>();
layers.Add(new TilesetComponent.Layer());
SerializedProperty.SetValue(layers);
UpdateList();
if (EditorToolManager.CurrentModeName == nameof(TilesetTool))
{
TilesetTool.Active.SelectedLayer = layers.Last();
TilesetTool.Active.UpdateInspector?.Invoke();
}
}
void BakeSelectedLayerPopup()
{
var layer = TilesetTool.Active?.SelectedLayer;
if (layer is null) return;
var confirm = new PopupWindow(
$"Bake Selected Layer",
$"Are you sure you want to Bake the Tiles on Layer \"{layer.Name}\"?\nThis will detach all placed tiles from their tile resource references.", "No",
new Dictionary<string, Action>() { { "Yes", BakeSelectedLayer } }
);
confirm.Show();
}
void BakeSelectedLayer()
{
var layer = TilesetTool.Active?.SelectedLayer;
if (layer is null) return;
var tileset = layer?.TilesetResource;
if (tileset is null) return;
foreach (var tile in layer.Tiles)
{
var tileRef = tileset.GetTileFromId(tile.Value.TileId);
if (tileRef is null) continue;
tile.Value.TileId = default;
tile.Value.CellPosition = default;
tile.Value.BakedPosition = tileRef.Position + tile.Value.CellPosition;
}
}
public void SelectLayer(TilesetComponent.Layer layer)
{
if (TilesetTool.Active is null) return;
TilesetTool.Active.SelectedLayer = layer;
TilesetTool.Active.UpdateInspector?.Invoke();
}
public void DeleteLayer(TilesetComponent.Layer layer)
{
bool isSelected = TilesetTool.Active.SelectedLayer == layer;
var layers = SerializedProperty.GetValue<List<TilesetComponent.Layer>>();
layers.Remove(layer);
SerializedProperty.SetValue(layers);
UpdateList();
if (EditorToolManager.CurrentModeName == nameof(TilesetTool) && isSelected)
{
TilesetTool.Active.SelectedLayer = layers.FirstOrDefault();
TilesetTool.Active.UpdateInspector?.Invoke();
}
}
}