Switch-Toolbox/Switch_Toolbox_Library/Forms/Animation/KeyedAnimTimeline.cs
KillzXGaming 27a7469201 Start to implement layout animation mode.
This mode will allow properties to be keyed when finished.
Animated panes can properly be picked if moved.
Improve the fov for perspective view.
2019-10-19 17:36:16 -04:00

266 lines
9.8 KiB
C#

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);
}
}
}