Files
sbox-public/engine/Sandbox.Tools/ControlWidget/VectorControlWidget.cs
Garry Newman d95169d8fa Unit Test Cleanup (#5064)
* Move all unit tests to Engine/Tests
* Fix Margin.EdgeSubtract
* Fix Capsule.Contains
* EnvironmentVariables.Remove if it's null
* Fixed ray trace never returning startedsolid
* Fix HistoryList.Navigate on empty list
* Fix GameObject.WorldPosition accepting NaNs
* Fix flex: initial expanding to the wrong grow/shrink
* Translation.TryConvert shouldn't throw on invalid enum strings
* Skip sound file tests on machines with no audio device
2026-06-12 13:23:50 +01:00

121 lines
3.3 KiB
C#

namespace Editor;
[CustomEditor( typeof( Vector2 ) )]
[CustomEditor( typeof( Vector3 ) )]
[CustomEditor( typeof( Vector4 ) )]
public class VectorControlWidget : ControlWidget
{
SerializedObject obj;
SerializedProperty Property;
FloatControlWidget FirstControl;
readonly bool canToggleUniform;
bool uniform;
public override bool SupportsMultiEdit => true;
public VectorControlWidget( SerializedProperty property ) : base( property )
{
Property = property;
property.TryGetAsObject( out obj );
if ( obj is null )
{
Log.Warning( $"Error when trying to get {property} as object" );
return;
}
canToggleUniform = property.TryGetAttribute<UniformAttribute>( out var uniformAttr );
uniform = canToggleUniform && EditorCookie.Get( UniformCookieKey, uniformAttr.Default );
Layout = Layout.Row();
Layout.Spacing = 2;
BuildFields();
}
string UniformCookieKey => $"vector.uniform.{Property.Parent?.TypeName}.{Property.Name}";
void BuildFields()
{
Layout.Clear( true );
if ( uniform )
{
FirstControl = TryAddField( new UniformVectorProperty( obj ), Theme.Blue, null );
FirstControl.Icon = "zoom_out_map";
return;
}
FirstControl = TryAddField( obj.GetProperty( "x" ), Theme.Red, "X" );
TryAddField( obj.GetProperty( "y" ), Theme.Green, "Y" );
TryAddField( obj.GetProperty( "z" ), Theme.Blue, "Z" );
TryAddField( obj.GetProperty( "w" ), Theme.Yellow, "W" );
}
private FloatControlWidget TryAddField( SerializedProperty prop, Color color, string text )
{
if ( prop is null ) return null;
var control = Layout.Add( new FloatControlWidget( prop ) { HighlightColor = color, Label = text } );
control.MinimumWidth = Theme.RowHeight;
control.HorizontalSizeMode = SizeMode.CanGrow | SizeMode.Expand;
control.MakeRanged( Property );
return control;
}
public override void OnLabelContextMenu( ContextMenu menu )
{
if ( !canToggleUniform ) return;
var o = menu.AddOption( "Uniform", "zoom_out_map", () =>
{
uniform = !uniform;
EditorCookie.Set( UniformCookieKey, uniform );
BuildFields();
} );
o.Checkable = true;
o.Checked = uniform;
menu.AddSeparator();
}
public override void StartEditing()
{
FirstControl?.StartEditing();
}
protected override void OnPaint()
{
// nothing
}
}
internal sealed class UniformVectorProperty( SerializedObject components ) : SerializedProperty.Proxy
{
protected override SerializedProperty ProxyTarget => components.GetProperty( "x" );
public override string DisplayName => components.ParentProperty?.DisplayName ?? ProxyTarget?.DisplayName;
public override string Description => components.ParentProperty?.Description ?? ProxyTarget?.Description;
public override bool IsMultipleValues => ProxyTarget?.IsMultipleValues ?? false;
public override bool IsMultipleDifferentValues => ProxyTarget?.IsMultipleDifferentValues ?? false;
public override void SetValue<T>( T value )
{
components.GetProperty( "x" )?.SetValue( value );
components.GetProperty( "y" )?.SetValue( value );
components.GetProperty( "z" )?.SetValue( value );
components.GetProperty( "w" )?.SetValue( value );
}
internal override void NoteStartEdit( SerializedProperty childProperty ) => ProxyTarget?.NoteStartEdit( childProperty );
internal override void NoteFinishEdit( SerializedProperty childProperty ) => ProxyTarget?.NoteFinishEdit( childProperty );
}