UI/Components/InspectorSheet.razor
@using Sandbox.UI;
@inherits Panel
@namespace HC3.UI
<root>
@foreach ( var property in Properties )
{
if ( !property.TryGetAttribute<InspectableAttribute>( out var attrib ) )
continue;
var propertyType = property.PropertyType;
if ( property.IsNullable )
{
if ( property.IsNull )
continue;
propertyType = property.NullableType;
}
property.TryGetAttribute<MinMaxAttribute>( out var minmaxAttrib );
<div class="row">
@if ( property.TryGetAttribute<IconAttribute>( out var iconAttr ) )
{
<i>@iconAttr.Value</i>
}
<label class="name">@property.DisplayName</label>
@if ( propertyType == typeof( bool ) )
{
<SwitchControl Value=@(property.GetValue<bool>()) OnValueChanged=@((bool v) =>property.SetValue<bool>(v))/>
}
else if ( propertyType == typeof( Color ) )
{
<div class="color-swatch" style=@($"background-color: {property.GetValue<Color>().Hex}") onclick=@(() => PickColor(property))></div>
}
else if ( propertyType == typeof( Resource ) )
{
<DropDown Options=@(ResourceUtils.GetOptions<Resource>()) Value=@(property.GetValue<Resource>()?.ResourcePath ?? "none") ValueChanged=@((string path) => property.SetValue( ResourceLibrary.Get<Resource>( path ))) />
}
else if ( propertyType.IsEnum )
{
<DropDown Value=@(property.GetValue<object>()) BuildOptions=@(() => BuildEnumOptionsFrom( property ))/>
}
else
{
<TextEntry
MinValue=@minmaxAttrib?.MinValue
MaxValue=@minmaxAttrib?.MaxValue
[email protected]
Numeric=@(propertyType != typeof(string))
Value=@(property.GetValue<string>())
OnTextEdited=@((string x) => { property.SetValue<string>(x); }) />
}
</div>
}
</root>
@code
{
[Property] public IEnumerable<SerializedProperty> Properties { get; set; }
/// <summary>
/// Build enum options from a serialized property
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
public static List<Option> BuildEnumOptionsFrom( SerializedProperty property )
{
var options = new List<Option>();
var enumDesc = TypeLibrary.GetEnumDescription(property.PropertyType);
foreach ( var x in enumDesc )
{
options.Add( new( x.Title, x.ObjectValue ) );
}
return options;
}
/// <summary>Should these properties be visible?
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public static bool ShouldShow( IEnumerable<SerializedProperty> properties )
{
var props = new List<SerializedProperty>();
foreach ( var x in properties )
{
if ( !x.TryGetAttribute<InspectableAttribute>( out var attrib ) )
continue;
var propertyType = x.PropertyType;
if ( x.IsNullable )
{
if ( x.IsNull )
continue;
}
props.Add( x );
}
return props.Count > 0;
}
ColorPicker _colorPicker;
/// <summary>
/// Open a colour picker for this property that sets the SerializedProperty value on change
/// </summary>
/// <param name="property"></param>
void PickColor( SerializedProperty property )
{
_colorPicker?.Close();
_colorPicker = new ColorPicker(property.GetValue<Color>(),
color =>
{
property.SetValue<Color>( color );
StateHasChanged();
}
);
var window = WindowManager.Instance.Focused;
if ( window.IsValid() )
{
window.OpenSubwindow( _colorPicker );
}
}
}