using Noesis; using System; using System.Diagnostics; using StoryboardTag = System.Tuple; namespace StellarConquest.Presentation.Unity.UI { public static class FrameworkElementExtensionMethods { public static TimeSpan ScreenSlowFadeTime = TimeSpan.FromMilliseconds(400); public static TimeSpan ScreenFastFadeTime = TimeSpan.FromMilliseconds(125); public static void StopStoryboard(this FrameworkElement frameworkElement) { if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); } } public static Storyboard FadeOscillate(this FrameworkElement frameworkElement, FrameworkElement parent, TimeSpan duration, float fromOpacity, float toOpacity) { string key = "FadeOscillate" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } DoubleAnimation doubleAnimation = new DoubleAnimation(); doubleAnimation.Duration = new Duration(duration); doubleAnimation.From = fromOpacity; doubleAnimation.To = toOpacity; //doubleAnimation.EasingFunction = new SineEase() { EasingMode = EasingMode.EaseInOut }; Storyboard storyboard = new Storyboard(); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 1); storyboard.RepeatBehavior = RepeatBehavior.Forever; storyboard.AutoReverse = true; storyboard.Duration = doubleAnimation.Duration; storyboard.Children.Add(doubleAnimation); Storyboard.SetTarget(doubleAnimation, frameworkElement); Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("Opacity")); storyboard.Begin(); return storyboard; } public static void FadeInScreen(this FrameworkElement frameworkElement, FrameworkElement parent, Action completed = null) { FadeIn(frameworkElement, parent, ScreenSlowFadeTime, completed); } public static void FadeIn(this FrameworkElement frameworkElement, FrameworkElement parent, TimeSpan duration, Action completed = null) { frameworkElement.Opacity = 0; string key = "Fade" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } if (parent.Resources.Contains(key)) { UnityEngine.Debug.LogWarning("Resource already exists"); return; } DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(duration); animation.AutoReverse = false; animation.FillBehavior = FillBehavior.Stop; Storyboard storyboard = new Storyboard(); storyboard.AutoReverse = false; storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 1); Storyboard.SetTarget(animation, frameworkElement); Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); animation.From = frameworkElement.Opacity; animation.To = 1; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); frameworkElement.Tag = null; frameworkElement.Opacity = 1.0f; completed?.Invoke(); }; storyboard.Begin(); } public static void FadeOutScreen(this FrameworkElement frameworkElement, FrameworkElement parent, Action completed = null) { FadeOut(frameworkElement, parent, ScreenFastFadeTime, completed); } public static void FadeOut(this FrameworkElement frameworkElement, FrameworkElement parent, TimeSpan duration, Action completed = null) { frameworkElement.Opacity = 1; string key = "Fade" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(duration); animation.AutoReverse = false; animation.FillBehavior = FillBehavior.Stop; Storyboard storyboard = new Storyboard(); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 0); storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); Storyboard.SetTarget(animation, frameworkElement); Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); animation.From = frameworkElement.Opacity; animation.To = 0; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); frameworkElement.Opacity = 0; frameworkElement.Tag = null; completed?.Invoke(); }; storyboard.Begin(); } public static void FadeTo(this FrameworkElement frameworkElement, FrameworkElement parent, TimeSpan duration, float value, Action completed = null) { string key = "Fade" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } if (parent.Resources.Contains(key)) { UnityEngine.Debug.LogWarning("Resource already exists"); return; } DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(duration); animation.AutoReverse = false; animation.FillBehavior = FillBehavior.Stop; Storyboard storyboard = new Storyboard(); storyboard.AutoReverse = false; storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 1); Storyboard.SetTarget(animation, frameworkElement); Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); animation.From = frameworkElement.Opacity; animation.To = value; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); frameworkElement.Tag = null; frameworkElement.Opacity = value; completed?.Invoke(); }; storyboard.Begin(); } public static bool IsFadeActive(this FrameworkElement frameworkElement) { return frameworkElement.Tag != null; } public static void Start(this ProgressBar progressBar, FrameworkElement parent, float startValue, float endValue, TimeSpan duration, Action completed = null) { StopStoryboard(progressBar); string key = "ProgressBar" + progressBar.GetHashCode(); DoubleAnimation animation = new DoubleAnimation(); //animation.EnableDependentAnimation = true; animation.Duration = new Duration(duration); Storyboard storyboard = new Storyboard(); storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); Storyboard.SetTarget(animation, progressBar); Storyboard.SetTargetProperty(animation, new PropertyPath("Value")); animation.From = startValue; animation.To = endValue; animation.FillBehavior = FillBehavior.Stop; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); completed?.Invoke(); }; progressBar.Tag = storyboard; parent.Resources.Add(key, storyboard); storyboard.Begin(); } public static void Unblur(this FrameworkElement frameworkElement, FrameworkElement parent, TimeSpan duration, Action completed = null) { if (!(frameworkElement.Effect is BlurEffect blurEffect)) return; string key = "Blur" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } float from = blurEffect.Radius; DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(duration); animation.AutoReverse = false; animation.FillBehavior = FillBehavior.Stop; Storyboard storyboard = new Storyboard(); storyboard.AutoReverse = false; storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 1); Storyboard.SetTarget(animation, frameworkElement); Storyboard.SetTargetProperty(animation, new PropertyPath("Effect.Radius")); animation.From = from; animation.To = 0; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); frameworkElement.Tag = null; blurEffect.Radius = 0; frameworkElement.Effect = null; completed?.Invoke(); }; storyboard.Begin(); } public static void Blur(this FrameworkElement frameworkElement, FrameworkElement parent, float radius, TimeSpan duration, Action completed = null) { if (!(frameworkElement.Effect is BlurEffect blurEffect)) { blurEffect = new BlurEffect(); frameworkElement.Effect = blurEffect; } string key = "Blur" + frameworkElement.GetHashCode(); if (frameworkElement.Tag is StoryboardTag tag) { tag.Item1.Stop(); parent.Resources.Remove(key); } float from = blurEffect.Radius; DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(duration); animation.AutoReverse = false; animation.FillBehavior = FillBehavior.Stop; Storyboard storyboard = new Storyboard(); storyboard.AutoReverse = false; storyboard.Duration = animation.Duration; storyboard.FillBehavior = FillBehavior.Stop; storyboard.Children.Add(animation); parent.Resources.Add(key, storyboard); frameworkElement.Tag = new StoryboardTag(storyboard, 1); Storyboard.SetTarget(animation, frameworkElement); Storyboard.SetTargetProperty(animation, new PropertyPath("Effect.Radius")); animation.From = from; animation.To = radius; storyboard.Completed += (sender2, e2) => { parent.Resources.Remove(key); frameworkElement.Tag = null; blurEffect.Radius = radius; completed?.Invoke(); }; storyboard.Begin(); } } }