Extensions/ComponentExtensions.cs
using System;
using System.Collections.Generic;
namespace Duccsoft.ImGui;
public static class ComponentExtensions
{
public static void ImGuiInspector( this Component component )
{
void PrintProperties( List<PropertyDescription> properties )
{
for ( int i = 0; i < properties.Count; i++ )
{
ImGui.PushID( i );
ImGuiProperty( component, properties[i] );
ImGui.PopID();
}
}
if ( !component.IsValid() )
return;
var typeDesc = ImGuiSystem.Current.GetTypeDescription( component.GetType() );
var properties = ImGuiSystem.Current.GetProperties( component.GetType() );
if ( ImGui.CurrentWindow is not null )
{
PrintProperties( properties );
}
else
{
if ( ImGui.Begin( typeDesc.ClassName ) )
{
PrintProperties( properties );
}
ImGui.End();
}
}
private static Dictionary<Type, Action<Component, PropertyDescription>> _propertyPrintStrategy = new()
{
{ typeof(float), ImGuiFloatProperty },
{ typeof(int), ImGuiIntProperty },
{ typeof(bool), ImGuiBoolProperty },
{ typeof(Vector2), ImGuiVector2Property },
{ typeof(Vector3), ImGuiVector3Property },
{ typeof(Vector4), ImGuiVector4Property },
};
public static void ImGuiProperty( this Component component, PropertyDescription prop )
{
if ( !component.IsValid() || prop is null )
return;
if ( !_propertyPrintStrategy.TryGetValue( prop.PropertyType, out var strategy ) )
return;
strategy( component, prop );
}
private static void ImGuiFloatProperty( Component component, PropertyDescription prop )
{
var range = prop.GetCustomAttribute<RangeAttribute>();
if ( range is not null )
{
ImGuiSliderFloatProperty( component, prop, range.Min, range.Max );
}
else
{
// TODO: Draw DragFloat
}
}
private static void ImGuiSliderFloatProperty( Component component, PropertyDescription prop, float min, float max )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (float)prop.GetValue( component );
ImGui.SliderFloat( prop.Name, ref value, min, max, "F3" );
prop.SetValue( component, value );
}
private static void ImGuiIntProperty( Component component, PropertyDescription prop )
{
var range = prop.GetCustomAttribute<RangeAttribute>();
if ( range is not null )
{
ImGuiSliderIntProperty( component, prop, (int)range.Min, (int)range.Max );
}
else
{
ImGuiDragIntProperty( component, prop );
}
}
private static void ImGuiSliderIntProperty( Component component, PropertyDescription prop, int min, int max )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (int)prop.GetValue( component );
ImGui.SliderInt( prop.Name, ref value, min, max );
prop.SetValue( component, value );
}
private static void ImGuiDragIntProperty( Component component, PropertyDescription prop )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (int)prop.GetValue( component );
ImGui.DragInt( prop.Name, ref value, 0.2f );
prop.SetValue( component, value );
}
private static void ImGuiBoolProperty( Component component, PropertyDescription prop )
{
var value = (bool)prop.GetValue( component );
ImGui.Checkbox( prop.Name, ref value );
prop.SetValue( component, value );
}
private static void ImGuiVector2Property( Component component, PropertyDescription prop )
{
var range = prop.GetCustomAttribute<RangeAttribute>();
if ( range is not null )
{
ImGuiSliderFloat2Property( component, prop, range.Min, range.Max );
}
else
{
// TODO: Add DragFloat2
}
}
private static void ImGuiSliderFloat2Property( Component component, PropertyDescription prop, float min, float max )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (Vector2)prop.GetValue( component );
ImGui.SliderFloat2( prop.Name, ref value, min, max );
prop.SetValue( component, value );
}
private static void ImGuiVector3Property( Component component, PropertyDescription prop )
{
var range = prop.GetCustomAttribute<RangeAttribute>();
if ( range is not null )
{
ImGuiSliderFloat3Property( component, prop, range.Min, range.Max );
}
else
{
// TODO: Add DragFloat3
}
}
private static void ImGuiSliderFloat3Property( Component component, PropertyDescription prop, float min, float max )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (Vector3)prop.GetValue( component );
ImGui.SliderFloat3( prop.Name, ref value, min, max );
prop.SetValue( component, value );
}
private static void ImGuiVector4Property( Component component, PropertyDescription prop )
{
var range = prop.GetCustomAttribute<RangeAttribute>();
if ( range is not null )
{
ImGuiSliderFloat4Property( component, prop, range.Min, range.Max );
}
else
{
// TODO: Add DragFloat4
}
}
private static void ImGuiSliderFloat4Property( Component component, PropertyDescription prop, float min, float max )
{
ImGui.Text( prop.Name ); ImGui.SameLine();
var value = (Vector4)prop.GetValue( component );
ImGui.SliderFloat4( prop.Name, ref value, min, max );
prop.SetValue( component, value );
}
}