Switch-Toolbox/Switch_Toolbox_Library/Forms/Animation/KeyedAnimTimeline.cs

267 lines
9.8 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Toolbox.Library.Animations;
namespace Toolbox.Library.Forms
{
public class KeyedAnimTimeline : TimeLine
{
public EventHandler OnNodeSelected;
public string GroupTarget = "";
public bool DisplayKeys = true;
private STAnimation activeAnimation;
public STAnimation ActiveAnimation
{
get { return activeAnimation; }
set
{
activeAnimation = value;
PopulateTree();
}
}
protected static int lineHeight = TextRenderer.MeasureText("§", font).Height;
protected int scrollY = 0;
private int trackCount = 0;
private TreeView NodeTree;
private Splitter splitter;
private ImageList imgList = new ImageList();
public KeyedAnimTimeline()
{
imgList = new ImageList()
{
ImageSize = new Size(24, 24),
ColorDepth = ColorDepth.Depth32Bit,
};
}
public void ReloadEditorView()
{
imgList.Images.Add("AnimationGroup", Properties.Resources.AnimationGroup);
imgList.Images.Add("AnimationTrack", Properties.Resources.AnimationTrack);
imgList.Images.Add("AnimationTrackR", Properties.Resources.AnimationTrackR);
imgList.Images.Add("AnimationTrackG", Properties.Resources.AnimationTrackG);
imgList.Images.Add("AnimationTrackB", Properties.Resources.AnimationTrackB);
imgList.Images.Add("AnimationTrackA", Properties.Resources.AnimationTrackA);
imgList.Images.Add("AnimationTrackX", Properties.Resources.AnimationTrackX);
imgList.Images.Add("AnimationTrackY", Properties.Resources.AnimationTrackY);
imgList.Images.Add("AnimationTrackZ", Properties.Resources.AnimationTrackZ);
imgList.Images.Add("AnimationTrackW", Properties.Resources.AnimationTrackW);
NodeTree = new TreeView();
NodeTree.ImageList = imgList;
NodeTree.Dock = DockStyle.Left;
// NodeTree.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left;
NodeTree.Height = this.Height;
NodeTree.Width = 300;
NodeTree.BackColor = FormThemes.BaseTheme.FormBackColor;
NodeTree.ForeColor = FormThemes.BaseTheme.FormForeColor;
NodeTree.AfterSelect += NodeTree_OnAfterNodeSelect;
NodeTree.BeforeExpand += NodeTree_OnExpand;
NodeTree.AfterExpand += NodeTree_OnExpand;
NodeTree.BeforeCollapse += NodeTree_OnExpand;
NodeTree.AfterCollapse += NodeTree_OnExpand;
Controls.Add(NodeTree);
splitter = new Splitter();
splitter.Dock = DockStyle.Left;
splitter.LocationChanged += SpitterLocationChanged;
Controls.Add(splitter);
margin = NodeTree.Width;
}
private void PopulateTree()
{
if (ActiveAnimation == null || NodeTree == null || !DisplayKeys) return;
NodeTree.Nodes.Clear();
foreach (var group in ActiveAnimation.AnimGroups)
{
if (GroupTarget != string.Empty && group.Name != GroupTarget)
continue;
if (group.Category != string.Empty)
{
var categoryNode = AddCategoryNode(NodeTree.Nodes, group.Category);
AddGroup(categoryNode.Nodes, group);
}
else
AddGroup(NodeTree.Nodes, group);
}
}
private TreeNode AddCategoryNode(TreeNodeCollection nodes, string name)
{
foreach (TreeNode node in nodes)
if (node.Text == name) return node;
var newNode = new TreeNode(name);
NodeTree.Nodes.Add(newNode);
return newNode;
}
private void AddGroup(TreeNodeCollection nodes, STAnimGroup group)
{
TreeNode groupNode = new TreeNode(group.Name)
{ Tag = group, ImageKey = "AnimationGroup", };
nodes.Add(groupNode);
foreach (var subGroup in group.SubAnimGroups)
AddGroup(groupNode.Nodes, subGroup);
foreach (var track in group.GetTracks())
{
if (!track.HasKeys)
continue;
string imageKey = "AnimationTrack";
if (track.Name.EndsWith("R")) imageKey = "AnimationTrackR";
if (track.Name.EndsWith("G")) imageKey = "AnimationTrackG";
if (track.Name.EndsWith("B")) imageKey = "AnimationTrackB";
if (track.Name.EndsWith("A")) imageKey = "AnimationTrackA";
if (track.Name.EndsWith("X")) imageKey = "AnimationTrackX";
if (track.Name.EndsWith("Y")) imageKey = "AnimationTrackY";
if (track.Name.EndsWith("Z")) imageKey = "AnimationTrackZ";
if (track.Name.EndsWith("W")) imageKey = "AnimationTrackW";
TreeNode trackNode = new TreeNode(track.Name)
{ Tag = track, ImageKey = imageKey, SelectedImageKey = imageKey, };
groupNode.Nodes.Add(trackNode);
}
}
private void NodeTree_OnExpand(object sender, EventArgs e)
{
this.Invalidate();
}
private void NodeTree_OnAfterNodeSelect(object sender, TreeViewEventArgs e)
{
OnNodeSelected?.Invoke(sender, e);
this.Invalidate();
}
private void SpitterLocationChanged(object sender, EventArgs e)
{
margin = splitter.Location.X;
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
if (!DisplayKeys)
{
base.OnPaint(e);
return;
}
e.Graphics.FillRectangle(brush3, new Rectangle(0, 0, margin, Height));
e.Graphics.SetClip(new Rectangle(0, barHeight, Width, Height - barHeight));
bool v = false;
int y = -scrollY - 10;
trackCount = 0;
if (ActiveAnimation != null)
{
foreach (var node in TreeViewExtensions.Collect(NodeTree.Nodes))
{
if (node.Parent != null && node.Tag is STAnimationTrack && node.Parent.IsVisible && node.Parent.IsExpanded)
{
var track = node.Tag as STAnimationTrack;
if (!track.HasKeys)
continue;
for (int i = 1; i < track.KeyFrames.Count; i++)
{
int l = Math.Max(-20, (int)((
track.KeyFrames[i - 1].Frame
- frameLeft) * (Width - 40 - margin) / (frameRight - frameLeft)));
int r = (int)((
track.KeyFrames[i].Frame
- frameLeft) * (Width - 40 - margin) / (frameRight - frameLeft));
if (v = !v)
{
var keyColor = new SolidBrush(Color.Yellow);
switch (node.ImageKey)
{
case "AnimationTrackR":
case "AnimationTrackX":
keyColor = new SolidBrush(Color.Red);
break;
case "AnimationTrackG":
case "AnimationTrackY":
keyColor = new SolidBrush(Color.Green);
break;
case "AnimationTrackB":
case "AnimationTrackZ":
keyColor = new SolidBrush(Color.Blue);
break;
case "AnimationTrackA":
case "AnimationTrackW":
keyColor = new SolidBrush(Color.Gray);
break;
}
if (node.IsSelected)
keyColor = new SolidBrush(Color.White);
e.Graphics.FillEllipse(keyColor, new Rectangle(l + margin + 20, barHeight + y, 5, lineHeight));
}
}
}
if (node.IsVisible)
y += NodeTree.ItemHeight;
}
}
base.OnPaint(e);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.X < margin)
{
scrollY = Math.Max(Math.Min(trackCount * lineHeight + barHeight - Height, scrollY - e.Delta / 2), 0);
Refresh();
}
else
base.OnMouseWheel(e);
}
protected override void OnResize(EventArgs e)
{
scrollY = Math.Max(Math.Min(trackCount * lineHeight + barHeight - Height, scrollY), 0);
base.OnResize(e);
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// KeyedAnimTimeline
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.Name = "KeyedAnimTimeline";
this.ResumeLayout(false);
}
}
}