Editor/Sprite/SpriteEditor/AnimationList/AnimationList.cs
using Editor;
using Sandbox;
using System.Collections.Generic;
using System.Linq;
namespace SpriteTools.SpriteEditor.AnimationList;
public class AnimationList : Widget
{
public SpriteResource Sprite { get; set; }
public MainWindow MainWindow { get; }
List<AnimationButton> Animations = new();
ScrollArea scrollArea;
Layout content;
public AnimationList(MainWindow mainWindow) : base(null)
{
MainWindow = mainWindow;
Name = "Animations";
WindowTitle = "Animations";
SetWindowIcon("directions_walk");
Layout = Layout.Column();
scrollArea = new ScrollArea(this);
scrollArea.Canvas = new Widget();
scrollArea.Canvas.Layout = Layout.Column();
scrollArea.Canvas.VerticalSizeMode = SizeMode.CanGrow;
scrollArea.Canvas.HorizontalSizeMode = SizeMode.Flexible;
// Add content list
content = Layout.Column();
content.Margin = 4;
content.AddStretchCell();
scrollArea.Canvas.Layout.Add(content);
// Add component button
var row = scrollArea.Canvas.Layout.AddRow();
row.AddStretchCell();
row.Margin = 16;
var button = row.Add(new Button.Primary("Create New Animation", "add"));
button.MinimumWidth = 300;
button.Clicked = CreateAnimationPopup;
row.AddStretchCell();
scrollArea.Canvas.Layout.AddStretchCell();
Layout.Add(scrollArea);
SetSizeMode(SizeMode.Default, SizeMode.CanShrink);
UpdateAnimationList();
MainWindow.OnAssetLoaded += UpdateAnimationList;
MainWindow.OnAnimationChanges += UpdateAnimationList;
}
public override void OnDestroyed()
{
base.OnDestroyed();
MainWindow.OnAssetLoaded -= UpdateAnimationList;
MainWindow.OnAnimationChanges -= UpdateAnimationList;
}
void CreateAnimationPopup()
{
var popup = new PopupWidget(MainWindow);
popup.Layout = Layout.Column();
popup.Layout.Margin = 16;
popup.Layout.Spacing = 8;
popup.Layout.Add(new Label($"What would you like to name the animation?"));
var entry = new LineEdit(popup);
var button = new Button.Primary("Create");
button.MouseClick = () =>
{
if (!string.IsNullOrEmpty(entry.Text) && !MainWindow.Sprite.Animations.Any(a => a.Name.ToLowerInvariant() == entry.Text.ToLowerInvariant()))
{
CreateAnimation(entry.Text);
UpdateAnimationList();
}
else
{
ShowNamingError(entry.Text);
}
popup.Visible = false;
};
entry.ReturnPressed += button.MouseClick;
popup.Layout.Add(entry);
var bottomBar = popup.Layout.AddRow();
bottomBar.AddStretchCell();
bottomBar.Add(button);
popup.Position = Editor.Application.CursorPosition;
popup.Visible = true;
entry.Focus();
}
[EditorEvent.Hotload]
public void UpdateAnimationList()
{
content?.Clear(true);
Animations?.Clear();
var animations = MainWindow?.Sprite?.Animations;
if (animations is not null)
{
foreach (var animation in animations)
{
var button = content.Add(new AnimationButton(this, MainWindow, animation));
button.MouseClick = () => SelectAnimation(button);
Animations.Add(button);
}
}
}
void CreateAnimation(string name)
{
var anim = new SpriteAnimation(name);
anim.LoopMode = SpriteResource.LoopMode.Forward;
MainWindow.PushUndo($"Create Animation {name}");
MainWindow.Sprite.Animations.Add(anim);
MainWindow.PushRedo();
}
void SelectAnimation(AnimationButton button)
{
MainWindow.SelectedAnimation = button.Animation;
MainWindow.OnAnimationSelected?.Invoke();
}
public static void ShowNamingError(string name)
{
if (string.IsNullOrEmpty(name))
{
var confirm = new PopupWindow("Invalid name ''", "You cannot give an animation an empty name", "OK");
confirm.Show();
}
else
{
var confirm = new PopupWindow($"Invalid name '{name}'", "You cannot give two animations the same name", "OK");
confirm.Show();
}
}
}