Editor UI widget that shows and edits per-tile data for a TilesetResource. It displays title, tile rect info, and a property sheet for the selected TileDefinition, and notifies a callback when tags change.
using Editor;
using Saandy.Tilemapper;
using Sandbox;
using System;
namespace Saandy.Editor.Tilemapper;
public sealed class TilesetTileDataWidget : Widget
{
private readonly TilesetResource _tileset;
private readonly Action _onChanged;
private int _selectedTileIndex = -1;
public float PreferredContentHeight => GetSelectedTile() == null ? 96.0f : 154.0f;
public TilesetTileDataWidget( Widget parent, TilesetResource tileset, Action onChanged ) : base( parent )
{
_tileset = tileset;
_onChanged = onChanged;
Name = "Tile Data";
MinimumHeight = 96;
MouseTracking = true;
HorizontalSizeMode = SizeMode.Flexible;
VerticalSizeMode = SizeMode.CanShrink;
Layout = Layout.Column();
Layout.Margin = 10;
Layout.Spacing = 8;
RefreshFromData();
}
protected override void OnPaint()
{
base.OnPaint();
Paint.ClearPen();
Paint.SetBrush( Color.Black.WithAlpha( 0.30f ) );
Paint.DrawRect( LocalRect, 4.0f );
Paint.SetPen( Color.White.WithAlpha( 0.13f ), 1.0f );
Paint.ClearBrush();
Paint.DrawRect( LocalRect.Shrink( 0.5f ), 4.0f );
}
public void SetSelectedTileIndex( int selectedTileIndex )
{
_selectedTileIndex = selectedTileIndex;
RefreshFromData();
}
public void RefreshFromData()
{
if ( Layout == null )
return;
Layout.Clear( true );
Layout.Margin = 10;
Layout.Spacing = 8;
_tileset?.EnsureTagSets();
var title = new Label( GetTitleText(), this );
title.SetStyles( "font-weight: 700; font-size: 16px;" );
Layout.Add( title );
var tile = GetSelectedTile();
if ( tile == null )
{
var hint = new Label( "Click a rect in the source image to edit per-tile data.", this );
hint.WordWrap = true;
hint.SetStyles( "color: #bbb;" );
Layout.Add( hint );
Update();
return;
}
tile.Tags ??= new TagSet();
var info = new Label( $"Rect: {tile.SourceRect.Left:0}, {tile.SourceRect.Top:0} {tile.SourceRect.Width:0}×{tile.SourceRect.Height:0}", this );
info.SetStyles( "color: #aaa; font-size: 12px;" );
Layout.Add( info );
var serializedTile = tile.GetSerialized();
var sheet = new ControlSheet();
sheet.AddObject( serializedTile, prop =>
{
if ( prop.HasAttribute<HideAttribute>() )
return false;
return prop.Name == nameof( TileDefinition.Tags );
} );
serializedTile.OnPropertyChanged += prop =>
{
if ( prop == null || prop.Name == nameof( TileDefinition.Tags ) )
_onChanged?.Invoke();
};
Layout.Add( sheet );
Update();
}
private string GetTitleText()
{
if ( _selectedTileIndex < 0 )
return "Tile Data";
return $"Tile Data - Tile {_selectedTileIndex}";
}
private TileDefinition GetSelectedTile()
{
if ( _tileset?.Tiles == null )
return null;
if ( _selectedTileIndex < 0 || _selectedTileIndex >= _tileset.Tiles.Count )
return null;
return _tileset.Tiles[_selectedTileIndex];
}
}