Files
sbox-public/game/addons/base/code/UI/Controls/BaseControl.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

118 lines
2.5 KiB
C#

using System;
namespace Sandbox.UI;
public class BaseControl : Panel
{
SerializedProperty _property;
public SerializedProperty Property
{
get => _property;
set
{
if ( _property == value ) return;
_property = value;
Rebuild();
}
}
/// <summary>
/// Called whenever SerializedProperty changes to another property and we think we probably need to rebuild
/// </summary>
public virtual void Rebuild()
{
}
int valueHash = 0;
public override void Tick()
{
base.Tick();
if ( HasFocus ) return;
if ( _property is null ) return;
var val = _property.GetValue<object>( default );
var hash = HashCode.Combine( val );
if ( hash == valueHash ) return;
valueHash = hash;
StateHasChanged();
}
public virtual bool SupportsMultiEdit => false;
/// <summary>
/// Create a BaseControl for a given SerializedProperty.
/// We'll look at BaseControls with [CustomEditor] attributes and see if any of them can handle this property.
/// </summary>
public static BaseControl CreateFor( SerializedProperty property )
{
ArgumentNullException.ThrowIfNull( property, nameof( property ) );
var type = property.PropertyType;
var allAttributes = Game.TypeLibrary.GetTypesWithAttribute<CustomEditorAttribute>( false )
.Where( x => x.Type.TargetType.IsAssignableTo( typeof( BaseControl ) ))
.ToArray();
var allEditors = allAttributes
.Select( x => new { score = x.Attribute.GetEditorScore( property ), editor = x } )
.Where( x => x.score > 0 )
.OrderByDescending( x => x.score )
.ToArray();
// Use the first editor we can successfully create
foreach ( var entry in allEditors )
{
var c = entry.editor.Type.Create<BaseControl>();
if ( c is not null )
{
if ( property.IsMultipleValues && !c.SupportsMultiEdit )
{
c.Delete( true );
return new MultiEditNotSupported( property );
}
c.Property = property;
return c;
}
}
// Nope - sorry, nothing for you
if ( property.IsMethod )
return null;
return new MissingEditor( property );
}
}
file class MultiEditNotSupported : BaseControl
{
Label label;
public MultiEditNotSupported( SerializedProperty property )
{
label = AddChild<Label>();
label.Text = "MultiEditNotSupported";
Property = property;
}
}
file class MissingEditor : BaseControl
{
Label label;
public MissingEditor( SerializedProperty property )
{
label = AddChild<Label>();
label.Text = $"No Editor Found For {property.PropertyType.Name}";
Property = property;
}
}