using Editor; using Sandbox; using Sandbox.Helpers; using System.Collections.Generic; using System.Linq; namespace SFXR.Editor; [CustomEditor( typeof( List ) )] public class SFXRNotesListControlWidget : ControlWidget { private SerializedCollection Collection; private Layout Content; private Button addButton; public override bool SupportsMultiEdit => false; SFXRSequencer Sequencer; public SFXRNotesListControlWidget( SerializedProperty property ) : base( property ) { SetSizeMode( SizeMode.Ignore, SizeMode.Ignore ); base.Layout = Layout.Column(); base.Layout.Spacing = 2f; if ( property.TryGetAsObject( out var obj ) && obj is SerializedCollection collection ) { if ( property.Parent.Targets.First() is SFXRSequencer sequencer ) { Sequencer = sequencer; } Collection = collection; Collection.OnEntryAdded = Rebuild; Collection.OnEntryRemoved = Rebuild; Content = Layout.Column(); base.Layout.Add( Content ); Layout layout = base.Layout.AddRow(); layout.Margin = 8; layout.AddStretchCell(); addButton = layout.Add( new Button( "Add Note" ) { ToolTip = "Add new note", } ); addButton.MinimumWidth = 200; addButton.Clicked = () => AddEntry(); layout.AddStretchCell(); Rebuild(); } } public void Rebuild() { Content.Clear( deleteWidgets: true ); Content.Margin = 0f; Layout layout = Layout.Column(); layout.Spacing = 2f; int num = 0; int count = Collection.Count(); for ( int i = 0; i < count; i++ ) { var item = Collection.ElementAt( i ); int index = num; var itemLayout = Layout.Row(); itemLayout.Spacing = 4f; // try to get object if ( item.TryGetAsObject( out var obj ) ) { var thing = new SFXRNoteSheet( obj ); itemLayout.Add( thing ); } else { var thing = ControlWidget.Create( item ); thing.MinimumHeight = 100; itemLayout.Add( thing ); } var buttonLayout = Layout.Column(); if ( i > 0 ) { buttonLayout.Add( new IconButton( "arrow_upward", delegate { MoveUp( index ); } ) { Background = Color.Transparent, FixedWidth = ControlWidget.ControlRowHeight, FixedHeight = ControlWidget.ControlRowHeight, ToolTip = "Move note up" } ); } else { buttonLayout.AddSpacingCell( 25 ); } buttonLayout.Add( new IconButton( "delete", delegate { RemoveEntry( index ); } ) { Background = Color.Red, FixedWidth = ControlWidget.ControlRowHeight, FixedHeight = ControlWidget.ControlRowHeight, ToolTip = "Delete note" } ); if ( i < count - 1 ) { buttonLayout.Add( new IconButton( "arrow_downward", delegate { MoveDown( index ); } ) { Background = Color.Transparent, FixedWidth = ControlWidget.ControlRowHeight, FixedHeight = ControlWidget.ControlRowHeight, ToolTip = "Move note down" } ); } else { buttonLayout.AddSpacingCell( 25 ); } itemLayout.Add( buttonLayout ); layout.Add( itemLayout ); num++; } MinimumHeight = 50 + (num * 105); Content.Add( layout ); Content.Margin = ((num > 0) ? 3 : 0); } private void AddEntry() { Collection.Add( new SFXRSequencer.Note() ); } private void RemoveEntry( int index ) { Collection.RemoveAt( index ); } private void MoveUp( int index ) { // Move the index up in Sequencer.Notes list if ( index > 0 ) { var note = Sequencer.Notes[index]; Sequencer.Notes.RemoveAt( index ); Sequencer.Notes.Insert( index - 1, note ); } Rebuild(); } private void MoveDown( int index ) { // Move the index down in Sequencer.Notes list if ( index < Sequencer.Notes.Count - 1 ) { var note = Sequencer.Notes[index]; Sequencer.Notes.RemoveAt( index ); Sequencer.Notes.Insert( index + 1, note ); } Rebuild(); } protected override void OnPaint() { } public void AddEffectDialog( Button source ) { var s = new SFXREffectTypeSelector( this ); s.OnSelect += ( t ) => AddEffect( t ); s.OpenAt( source.ScreenRect.BottomLeft, animateOffset: new Vector2( 0, -4 ) ); s.FixedWidth = source.Width; } void AddEffect( TypeDescription type ) { if ( !type.TargetType.IsAssignableTo( typeof( SFXREffect ) ) ) { Log.Error( $"Type {type.TargetType} is not assignable to {typeof( SFXREffect )}" ); return; } SFXREffect effect = type.Create(); Collection.Add( effect ); Log.Info( effect ); } }