Editor/LineMaterialPicker.cs
using System;
using System.Linq;
using Editor;
using Editor.TerrainEditor;
using Sandbox;
namespace TerrainLines;
internal sealed class LineMaterialPicker : TerrainMaterialList
{
private const string None = "None";
private readonly Terrain _terrain;
private readonly bool _allowNone;
private readonly Func<int> _selected;
private TerrainMaterial[] _materials = [];
private int _lastSelection = int.MinValue;
internal LineMaterialPicker( Widget parent, Terrain terrain, bool allowNone, Func<int> selected, Action<int> select ) : base( parent, terrain )
{
_terrain = terrain;
_allowNone = allowNone;
_selected = selected;
FixedHeight = 180;
AcceptDrops = false;
ItemContextMenu = null;
ItemSelected = value => select( value is TerrainMaterial material ? terrain.Storage.Materials.IndexOf( material ) : -1 );
Refresh();
}
// This is a picker; asset management and material reordering stay in the terrain inspector.
protected override bool OnDragItem( VirtualWidget item ) => false;
internal void Refresh()
{
if ( !_terrain.IsValid() || _terrain.Storage is null ) return;
var materials = _terrain.Storage.Materials.Take( 32 ).ToArray();
if ( !_materials.SequenceEqual( materials ) || _lastSelection == int.MinValue )
{
_materials = materials;
SetItems( _allowNone ? new object[] { None }.Concat( materials.Cast<object>() ) : materials.Cast<object>() );
_lastSelection = int.MinValue;
}
int index = _selected();
if ( index == _lastSelection ) return;
_lastSelection = index;
if ( index >= 0 && index < _materials.Length ) SelectItem( _materials[index] );
else if ( _allowNone ) SelectItem( None );
}
protected override string GetTooltip( object item ) => item is TerrainMaterial material ? material.ResourceName : None;
protected override void PaintItem( VirtualWidget item )
{
if ( item.Object is not string ) { base.PaintItem( item ); return; }
Paint.ClearPen();
Paint.SetBrush( item.Selected ? Theme.Blue.WithAlpha( 0.5f ) : Theme.ControlBackground );
Paint.DrawRect( item.Rect, 4 );
Paint.SetPen( Theme.Text );
Paint.SetDefaultFont();
Paint.DrawText( item.Rect, None, TextFlag.Center );
}
}