using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Diagnostics; using Toolbox.Library.Forms; using Toolbox.Library.Animations; namespace Toolbox.Library { public enum AnimPlayerState { Playing, Pause, Stop, } public partial class STAnimationPanel : STUserControl { public EventHandler OnNodeSelected { get { return animationTrackBar.OnNodeSelected; } set { animationTrackBar.OnNodeSelected = value; } } public bool DisplayKeys { get { return animationTrackBar.DisplayKeys; } set { animationTrackBar.DisplayKeys = value; } } private OpenTK.GLControl _viewport; public virtual OpenTK.GLControl Viewport { get { if (_viewport == null) _viewport = GetActiveViewport(); return _viewport; } } private OpenTK.GLControl GetActiveViewport() { var viewport = LibraryGUI.GetActiveViewport(); if (viewport == null) return null; return viewport.GL_Control; } public void SetViewport(OpenTK.GLControl control) { _viewport = control; } public EventHandler AnimationPlaying; public AnimPlayerState AnimationPlayerState = AnimPlayerState.Stop; public bool IsLooping { get { return loopChkBox.Checked; } set { loopChkBox.Checked = value; } } public bool IsPlaying { get { return AnimationPlayerState == AnimPlayerState.Playing; } } private static STAnimationPanel _instance; public static STAnimationPanel Instance { get { return _instance == null ? _instance = new STAnimationPanel() : _instance; } } //Animation Functions public int AnimationSpeed = 60; public float Frame = 0; // Frame rate control public bool isOpen = true; public float FrameCount; public float StartFrame; private List currentAnimations = new List(); public void AddAnimation(STAnimation animation, bool reset = true) { if (animation == null) return; if (reset) Reset(); currentAnimations.Add(animation); float frameCount = uint.MinValue; float startFrame = uint.MaxValue; for (int i = 0; i < currentAnimations.Count; i++) { frameCount = Math.Max(frameCount, currentAnimations[i].FrameCount); startFrame = Math.Min(startFrame, currentAnimations[i].StartFrame); } if (frameCount != uint.MinValue && frameCount > startFrame) FrameCount = frameCount; else FrameCount = 1; if (startFrame != uint.MaxValue && frameCount > startFrame) StartFrame = startFrame; else StartFrame = 0; ResetModels(); animation.Reset(); totalFrame.Maximum = (decimal)FrameCount; totalFrame.Value = (decimal)FrameCount; currentFrameUpDown.Maximum = (decimal)FrameCount; currentFrameUpDown.Minimum = (decimal)StartFrame; animationTrackBar.FrameCount = (float)FrameCount; animationTrackBar.StartTime = (int)StartFrame; animationTrackBar.ActiveAnimation = animation; currentFrameUpDown.Value = (decimal)StartFrame; SetAnimationsToFrame(0); UpdateViewport(); } public void Reset() { currentAnimations.Clear(); Frame = 0; FrameCount = 1; StartFrame = 0; ResetModels(); totalFrame.Maximum = (decimal)FrameCount; totalFrame.Value = (decimal)FrameCount; currentFrameUpDown.Maximum = (decimal)FrameCount; currentFrameUpDown.Minimum = (decimal)StartFrame; animationTrackBar.FrameCount = (float)FrameCount; animationTrackBar.StartTime = (int)StartFrame; currentFrameUpDown.Value = (decimal)StartFrame; } public void ResetModels() { if (Viewport == null) return; foreach (var anim in currentAnimations) { if (anim is STSkeletonAnimation) { ((STSkeletonAnimation)anim).GetActiveSkeleton()?.reset(); } } } public STAnimationPanel() { InitializeComponent(); BackColor = FormThemes.BaseTheme.FormBackColor; ForeColor = FormThemes.BaseTheme.FormForeColor; DisplayKeys = false; animationTrackBar.BackColor = FormThemes.BaseTheme.FormBackColor; animationTrackBar.ForeColor = FormThemes.BaseTheme.FormForeColor; animationTrackBar.FrameChanged += new EventHandler(animationTrackBar_ValueChanged); /* animationTrackBar.ThumbInnerColor = FormThemes.BaseTheme.TimelineThumbColor; animationTrackBar.ThumbOuterColor = FormThemes.BaseTheme.TimelineThumbColor; this.animationTrackBar.BarInnerColor = FormThemes.BaseTheme.FormBackColor; this.animationTrackBar.BarPenColorBottom = FormThemes.BaseTheme.FormBackColor; this.animationTrackBar.BarPenColorTop = FormThemes.BaseTheme.FormBackColor; this.animationTrackBar.ElapsedInnerColor = FormThemes.BaseTheme.FormBackColor; this.animationTrackBar.ElapsedPenColorBottom = FormThemes.BaseTheme.FormBackColor; this.animationTrackBar.ElapsedPenColorTop = FormThemes.BaseTheme.FormBackColor; */ panel1.BackColor = FormThemes.BaseTheme.FormBackColor; animationPlayBtn.BackColor = FormThemes.BaseTheme.FormBackColor; button2.BackColor = FormThemes.BaseTheme.FormBackColor; animationPlayBtn.ForeColor = FormThemes.BaseTheme.FormForeColor; button2.ForeColor = FormThemes.BaseTheme.FormForeColor; frameSpeedUD.ForeColor = FormThemes.BaseTheme.FormForeColor; frameSpeedUD.BackColor = FormThemes.BaseTheme.FormBackColor; totalFrame.ForeColor = FormThemes.BaseTheme.FormForeColor; totalFrame.BackColor = FormThemes.BaseTheme.FormBackColor; currentFrameUpDown.ForeColor = FormThemes.BaseTheme.FormForeColor; currentFrameUpDown.BackColor = FormThemes.BaseTheme.FormBackColor; frameSpeedUD.Minimum = 1; frameSpeedUD.Value = 60; frameSpeedUD.Maximum = 120; SetupTimer(); this.LostFocus += new System.EventHandler(AnimationPanel_LostFocus); } private void Play() { AnimationPlayerState = AnimPlayerState.Playing; UpdateAnimationUI(); animationTrackBar.Play(); animationTimer.Start(); } private void Pause() { AnimationPlayerState = AnimPlayerState.Stop; UpdateAnimationUI(); animationTrackBar.Stop(); animationTimer.Stop(); } private void Stop() { currentFrameUpDown.Value = (decimal)StartFrame; AnimationPlayerState = AnimPlayerState.Stop; UpdateAnimationUI(); animationTimer.Stop(); } private void UpdateAnimationUI() { animationPlayBtn.BackgroundImage = IsPlaying ? Properties.Resources.stop : Properties.Resources.arrowR; } private void UpdateAnimationFrame() { if (IsPlaying) { if (currentFrameUpDown.InvokeRequired) { currentFrameUpDown.BeginInvoke((Action)(() => { AdvanceNextFrame(); })); } else { AdvanceNextFrame(); } } } private Timer animationTimer; private void SetupTimer() { animationTimer = new Timer { Interval = (int)(1000.0f / 60.0f) }; animationTimer.Tick += new EventHandler(animationTimer_Tick); } private void AdvanceNextFrame() { if (animationTrackBar.CurrentFrame == animationTrackBar.FrameCount - 1) { if (IsLooping) { //Reset the min setting as animations can potentically be switched currentFrameUpDown.Minimum = (decimal)StartFrame; currentFrameUpDown.Value = (decimal)StartFrame; } else Stop(); } else if (!animationTrackBar.Locked) { if (currentFrameUpDown.Value < totalFrame.Value) currentFrameUpDown.Value++; } currentFrameUpDown.Refresh(); totalFrame.Refresh(); } private void animationPlayBtn_Click(object sender, EventArgs e) { if (currentAnimations.Count == 0 || FrameCount <= StartFrame) return; if (AnimationPlayerState == AnimPlayerState.Playing) Pause(); else Play(); } private void totalFrame_ValueChanged(object sender, EventArgs e) { if (currentAnimations.Count == 0) return; if (totalFrame.Value < (decimal)StartFrame + 1) { totalFrame.Value = (decimal)StartFrame + 1; } else { animationTrackBar.CurrentFrame = StartFrame; animationTrackBar.FrameCount = FrameCount; } } private void UpdateViewport() { if (IsDisposed || Viewport == null || Viewport.IsDisposed || Viewport.Disposing) return; if (Viewport.InvokeRequired) { Viewport.Invoke((MethodInvoker)delegate { // Running on the UI thread Viewport.Invalidate(); }); } else Viewport.Invalidate(); } private void nextButton_Click(object sender, EventArgs e) { if (animationTrackBar.CurrentFrame < animationTrackBar.FrameCount) animationTrackBar.CurrentFrame++; } private void prevButton_Click(object sender, EventArgs e) { if (animationTrackBar.CurrentFrame > 0) animationTrackBar.CurrentFrame--; } private void animationTrackBar_Scroll(object sender, EventArgs e) { } private void animationTrackBar_ValueChanged(object sender, EventArgs e) { if (currentAnimations.Count == 0 || totalFrame.Value <= (decimal)StartFrame) return; currentFrameUpDown.Value = (decimal)animationTrackBar.CurrentFrame; } private void OnFrameAdvanced() { UpdateViewport(); SetAnimationsToFrame(animationTrackBar.CurrentFrame); if (!IsPlaying) UpdateViewport(); } private void animationTimer_Tick(object sender, EventArgs e) { UpdateAnimationFrame(); } private void SetAnimationsToFrame(float frameNum) { if (Viewport == null || currentAnimations.Count == 0) return; foreach (var anim in currentAnimations) { if (frameNum < anim.StartFrame || frameNum > anim.FrameCount) continue; float animFrameNum = frameNum; anim.SetFrame(animFrameNum); AnimationPlaying?.Invoke(anim, new EventArgs()); anim.NextFrame(); //Add frames to the playing animation anim.Frame += frameNum; //Reset it when it reaches the total frame count if (anim.Frame >= anim.FrameCount && anim.Loop) { anim.Frame = anim.StartFrame; } } } private void currentFrameUpDown_ValueChanged(object sender, EventArgs e) { if (currentFrameUpDown.Value > totalFrame.Value) currentFrameUpDown.Value = totalFrame.Value; //Check locked state current frame will change during playing if (!animationTrackBar.Locked) { animationTrackBar.CurrentFrame = (int)currentFrameUpDown.Value; } OnFrameAdvanced(); } public override void OnControlClosing() { isOpen = false; Dispose(); ClosePanel(); } private void AnimationPanel_Load(object sender, EventArgs e) { if (Viewport != null) Viewport.VSync = Runtime.enableVSync; } private void AnimationPanel_Enter(object sender, EventArgs e) { } private void AnimationPanel_LostFocus(object sender, EventArgs e) { } private void AnimationPanel_Click(object sender, EventArgs e) { } private void AnimationPanel_Leave(object sender, EventArgs e) { } public void ClosePanel() { ResetModels(); currentAnimations.Clear(); isOpen = false; Dispose(); } private void panel1_Paint(object sender, PaintEventArgs e) { } private void colorSlider1_Scroll(object sender, ScrollEventArgs e) { } private void frameSpeedUD_ValueChanged(object sender, EventArgs e) { if (animationTimer != null) animationTimer.Interval = (int)(1000.0f / (float)frameSpeedUD.Value); } } }