using Editor; using Sandbox; using System.Numerics; using VeloX.Audio; using static VeloX.EngineStream; namespace VeloX; internal class LayerObjectWidget : ControlObjectWidget { private SerializedProperty Index; private SerializedCollection Controllers; private class ControllerWidget : ControlObjectWidget { public ControllerWidget( LayerObjectWidget parent, SerializedProperty property ) : base( property, true ) { PaintBackground = false; Layout = Layout.Row(); HorizontalSizeMode = (SizeMode)3; //SetStyles( "background-color: #123; color: white; font-weight: 600;" ); SerializedObject.TryGetProperty( nameof( Controller.InputParameter ), out var inputType ); Layout.Add( EnumControlWidget.Create( inputType ), 1 ); SerializedObject.TryGetProperty( nameof( Controller.InputRange ), out var inputRange ); Layout.Add( ValueRangeWidget.Create( inputRange ), 12 ); SerializedObject.TryGetProperty( nameof( Controller.OutputParameter ), out var outputType ); Layout.Add( EnumControlWidget.Create( outputType ), 1 ); SerializedObject.TryGetProperty( nameof( Controller.OutputRange ), out var outputRange ); Layout.Add( ValueRangeWidget.Create( outputRange ), 12 ); var removeButton = new IconButton( "clear", () => parent.RemoveEntry( property ) ) { ToolTip = "Remove", Background = Theme.ControlBackground, FixedWidth = Theme.RowHeight, FixedHeight = Theme.RowHeight }; Layout.Add( removeButton ); } } void RemoveEntry( SerializedProperty index ) { Controllers.Remove( index ); Rebuild(); } private SerializedCollection layers; SimulatedEngineWidget SimulatedEngine; public LayerObjectWidget( SerializedProperty property, SerializedProperty index, SerializedCollection layers, SimulatedEngineWidget SimulatedEngine ) : base( property, true ) { this.SimulatedEngine = SimulatedEngine; SetStyles( "background-color: #;" ); this.layers = layers; Index = index; Layout = Layout.Column(); Layout.SizeConstraint = SizeConstraint.SetMaximumSize; Layout.Alignment = TextFlag.Top; Layout.Margin = 4; Layout.Spacing = 4; Rebuild(); } protected override void PaintUnder() { base.PaintUnder(); if ( SimulatedEngine is null ) return; if ( SimulatedEngine.Player is null ) return; var layer = SimulatedEngine.Player.Stream.Layers[Index.GetValue()]; if ( SimulatedEngine.Player.EngineSounds.TryGetValue( layer, out var handle ) ) { Paint.SetBrush( Color.Gray ); Rect localRect = base.LocalRect; var newVolume = localRect.Width * handle.Volume; Paint.DrawRect( new( 0, 0, newVolume, localRect.Height ) ); Update(); } } public void Rebuild() { using var _ = SuspendUpdates.For( this ); Layout.Clear( true ); VerticalSizeMode = SizeMode.CanShrink; var layout = Layout.AddRow(); layout.Alignment = TextFlag.Top; var id = layout.Add( StringControlWidget.Create( Index ), 1 ).HorizontalSizeMode = SizeMode.Flexible; layout.Add( ResourceControlWidget.Create( SerializedObject.GetProperty( nameof( Layer.AudioPath ) ) ), 3 ).HorizontalSizeMode = SizeMode.Flexible; var ctlrs = Layout.AddColumn(); ctlrs.Spacing = 2; ctlrs.Margin = 4; var hints = ctlrs.AddRow(); hints.Add( new Label( "Input Type" ), 3 ); hints.Add( new Label( "Input Min" ), 2 ); hints.Add( new Label( "Input Max" ), 2 ); hints.Add( new Label( "Output Type" ), 3 ); hints.Add( new Label( "Output Min" ), 2 ); hints.Add( new Label( "Output Max" ), 2 ); if ( !SerializedObject.TryGetProperty( nameof( Layer.Controllers ), out var constrollers ) ) return; if ( !constrollers.TryGetAsObject( out var so ) || so is not SerializedCollection sc ) return; Controllers = sc; Controllers.OnEntryAdded = Rebuild; Controllers.OnEntryRemoved = Rebuild; foreach ( var controller in sc ) { ctlrs.Add( new ControllerWidget( this, controller ) ); } var footer = ctlrs.AddRow(); var controls = footer.AddRow(); controls.Alignment = TextFlag.Left; controls.Spacing = 4; var useRedline = SerializedObject.GetProperty( nameof( Layer.UseRedline ) ); controls.Add( new BoolControlWidget( useRedline ) ); controls.Add( new Label( useRedline.Description ) ); var isMuted = SerializedObject.GetProperty( nameof( Layer.IsMuted ) ); controls.Add( new BoolControlWidget( isMuted ) ); controls.Add( new Label( isMuted.DisplayName ) ); var cont = footer.AddRow(); cont.Spacing = 4; cont.Alignment = TextFlag.Right; cont.Add( new Button( "Add Controller" ) ).Clicked = () => { Controllers.Add( null ); }; cont.Add( new Button( "Remove Layer" ) ).Clicked = () => { layers.RemoveAt( Index.GetValue() ); }; } }