Editor/ParticleEffectManagerWidget.cs
using Editor;
using Sandbox.UI;
using Button = Editor.Button;
using ControlSheet = Editor.ControlSheet;
namespace Sandbox;
public class ParticleEffectManagerWidget : EditorTool<ParticleEffectsManager>
{
ParticleSystemToolWindow window;
public override void OnEnabled()
{
window = new ParticleSystemToolWindow();
AddOverlay( window, TextFlag.RightBottom, 10 );
}
public override void OnUpdate()
{
window.ToolUpdate();
}
public override void OnDisabled()
{
}
public override void OnSelectionChanged()
{
var effect = GetSelectedComponent<ParticleEffectsManager>();
window.OnSelectionChanged( effect );
}
class ParticleSystemToolWindow : WidgetWindow
{
private ParticleEffectsManager targetComponent;
Button PauseButton;
FloatSlider PlaybackSlider;
static bool IsClosed = false;
public ParticleSystemToolWindow()
{
ContentMargins = 0;
Layout = Layout.Column();
}
public void ToolUpdate()
{
if ( !targetComponent.IsValid() )
return;
var remappedTiming = targetComponent.PlaybackTime.Remap( 0, targetComponent.LongestDuration, 0, 1f );
PlaybackSlider.Value = remappedTiming;
}
public void OnSelectionChanged( ParticleEffectsManager effect )
{
targetComponent = effect;
Rebuild();
}
private void Rebuild()
{
Layout.Clear( true );
Layout.Margin = 0;
Icon = IsClosed ? "" : "shower";
IsGrabbable = !IsClosed;
MaximumWidth = 230;
UpdateTitle();
if ( IsClosed )
{
var closedRow = Layout.AddRow();
closedRow.Add( new IconButton( "shower", () => { IsClosed = false; Rebuild(); } ) { ToolTip = "Open", FixedHeight = HeaderHeight, FixedWidth = HeaderHeight, Background = Color.Transparent } );
return;
}
var headerRow = Layout.AddRow();
headerRow.AddStretchCell();
headerRow.Add( new IconButton( "close", CloseWindow ) { ToolTip = "Close", FixedHeight = HeaderHeight, FixedWidth = HeaderHeight, Background = Color.Transparent } );
var slider = new SliderControl();
var buttonRow = Layout.AddRow();
buttonRow.Spacing = 2;
buttonRow.AddStretchCell();
PauseButton = new Button( "Pause" )
{
Clicked = PauseToggle,
FixedWidth = 40
};
PlaybackSlider = new FloatSlider( this )
{
Minimum = 0,
Maximum = 1,
EditingStarted = () => TogglePlayback(),
EditingFinished = () => TogglePlayback(),
OnValueEdited = () =>
{
targetComponent.PlayBack = PlaybackSlider.Value;
},
};
buttonRow.Add( PauseButton );
buttonRow.Add( new Button( "Restart" ) { Clicked = Restart } );
buttonRow.AddStretchCell();
if ( targetComponent.IsValid() )
{
PauseButton.Text = targetComponent.IsPaused ? "Play" : "Pause";
var sheet = new ControlSheet();
var so = targetComponent.GetSerialized();
sheet.AddProperty( this, x => x.ParticleCount );
sheet.AddProperty( this, x => x.PlaybackTime );
Layout.Add( sheet );
}
var sliderRow = Layout.AddRow();
sliderRow.Add( PlaybackSlider );
Layout.Margin = 4;
}
private void TogglePlayback()
{
if(targetComponent.IsValid()) targetComponent.IsPlayBack = !targetComponent.IsPlayBack;
}
void Restart()
{
if ( !targetComponent.IsValid() )
return;
targetComponent.IsRestart = true;
}
void PauseToggle()
{
if ( !targetComponent.IsValid() )
return;
targetComponent.IsPaused = !targetComponent.IsPaused;
if ( PauseButton.IsValid() )
PauseButton.Text = targetComponent.IsPaused ? "Play" : "Pause";
}
public float PlaybackTime
{
get
{
if ( !targetComponent.IsValid() )
return 0.0f;
return targetComponent.PlaybackTime;
}
}
private int ParticleCount
{
get
{
if ( !targetComponent.IsValid() )
return 0;
return targetComponent.ParticleCount;
}
}
private void UpdateTitle()
{
if ( !IsClosed )
{
if ( targetComponent.IsValid() && targetComponent.GameObject.IsValid() )
{
WindowTitle = $"Particles - {targetComponent.GameObject.Name}";
}
else
{
WindowTitle = "Particles";
}
}
else
{
WindowTitle = "";
}
}
void CloseWindow()
{
IsClosed = true;
Rebuild();
Position = Parent.Size - 32;
}
}
}