Преглед на файлове

Add many styles to SpinnerView (#2510)

* Add many styles to SpinnerView

* Add SpinnerStyles as a nested class

* Allow zero as valid spinner delay value

* Change from BorderStyle to LineStyle

* Rename SpinDelayInMilliseconds to just SpinDelay

---------

Co-authored-by: Tig <[email protected]>
Nutzzz преди 2 години
родител
ревизия
f280ded145

+ 0 - 75
Terminal.Gui/Views/SpinnerView.cs

@@ -1,75 +0,0 @@
-using System;
-
-namespace Terminal.Gui {
-
-	/// <summary>
-	/// A 1x1 <see cref="View"/> based on <see cref="Label"/> which displays a spinning
-	/// line character.
-	/// </summary>
-	/// <remarks>
-	/// By default animation only occurs when you call <see cref="View.SetNeedsDisplay()"/>.
-	/// Use <see cref="AutoSpin"/> to make the automate calls to <see cref="View.SetNeedsDisplay()"/>.
-	/// </remarks>
-	public class SpinnerView : Label {
-		private Rune [] _runes = new Rune [] { '|', '/', '\u2500', '\\' };
-		private int _currentIdx = 0;
-		private DateTime _lastRender = DateTime.MinValue;
-		private object _timeout;
-
-		/// <summary>
-		/// Gets or sets the number of milliseconds to wait between characters
-		/// in the spin.  Defaults to 250.
-		/// </summary>
-		/// <remarks>This is the maximum speed the spinner will rotate at.  You still need to
-		/// call <see cref="View.SetNeedsDisplay()"/> or <see cref="SpinnerView.AutoSpin"/> to
-		/// advance/start animation.</remarks>
-		public int SpinDelayInMilliseconds { get; set; } = 250;
-
-		/// <summary>
-		/// Creates a new instance of the <see cref="SpinnerView"/> class.
-		/// </summary>
-		public SpinnerView ()
-		{
-			Width = 1; Height = 1;
-		}
-
-		/// <inheritdoc/>
-		public override void Redraw (Rect bounds)
-		{
-			if (DateTime.Now - _lastRender > TimeSpan.FromMilliseconds (SpinDelayInMilliseconds)) {
-				_currentIdx = (_currentIdx + 1) % _runes.Length;
-				Text = "" + _runes [_currentIdx];
-				_lastRender = DateTime.Now;
-			}
-
-			base.Redraw (bounds);
-		}
-
-		/// <summary>
-		/// Automates spinning
-		/// </summary>
-		public void AutoSpin ()
-		{
-			if (_timeout != null) {
-				return;
-			}
-
-			_timeout = Application.MainLoop.AddTimeout (
-				TimeSpan.FromMilliseconds (SpinDelayInMilliseconds), (m) => {
-					Application.MainLoop.Invoke (this.SetNeedsDisplay);
-					return true;
-				});
-		}
-
-		/// <inheritdoc/>
-		protected override void Dispose (bool disposing)
-		{
-			if (_timeout != null) {
-				Application.MainLoop.RemoveTimeout (_timeout);
-				_timeout = null;
-			}
-
-			base.Dispose (disposing);
-		}
-	}
-}

+ 1699 - 0
Terminal.Gui/Views/SpinnerView/SpinnerStyle.cs

@@ -0,0 +1,1699 @@
+//------------------------------------------------------------------------------
+// SpinnerStyles below are derived from
+// <https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json>
+// MIT License
+// Copyright (c) Sindre Sorhus <[email protected]>
+// (https://sindresorhus.com)
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//------------------------------------------------------------------------------
+// Windows Terminal supports Unicode and Emoji characters, but by default
+// conhost shells (e.g., PowerShell and cmd.exe) do not. See
+// <https://spectreconsole.net/best-practices>.
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace Terminal.Gui {
+	/// <summary>
+	/// SpinnerStyles used in a <see cref="SpinnerView"/>.
+	/// </summary>
+	public abstract class SpinnerStyle {
+		const int DEFAULT_DELAY = 80;
+		const bool DEFAULT_BOUNCE = false;
+		const bool DEFAULT_SPECIAL = false;
+
+		/// <summary>
+		/// Gets or sets the number of milliseconds to wait between characters
+		/// in the spin.  Defaults to the SpinnerStyle's Interval value.
+		/// </summary>
+		/// <remarks>This is the maximum speed the spinner will rotate at.  You still need to
+		/// call <see cref="View.SetNeedsDisplay()"/> or <see cref="SpinnerView.AutoSpin"/> to
+		/// advance/start animation.</remarks>
+		public abstract int SpinDelay { get; }
+
+		/// <summary>
+		/// Gets or sets whether spinner should go back and forth through the Sequence rather than
+		/// going to the end and starting again at the beginning.
+		/// </summary>
+		public abstract bool SpinBounce { get; }
+
+		/// <summary>
+		/// Gets whether the current spinner style contains emoji or other special characters.
+		/// </summary>
+		public abstract bool HasSpecialCharacters { get; }
+
+		/// <summary>
+		/// Gets or sets the frames used to animate the spinner.
+		/// </summary>
+		public abstract string [] Sequence { get; }
+
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
+
+		// Placeholder when user has specified Delay and Sequence manually
+		public class Custom : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => Array.Empty<string> ();
+		}
+		public class Dots : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠋",
+			"⠙",
+			"⠹",
+			"⠸",
+			"⠼",
+			"⠴",
+			"⠦",
+			"⠧",
+			"⠇",
+			"⠏",
+			};
+		}
+		public class Dots2 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⣾",
+			"⣽",
+			"⣻",
+			"⢿",
+			"⡿",
+			"⣟",
+			"⣯",
+			"⣷",
+			};
+		}
+		public class Dots3 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠋",
+			"⠙",
+			"⠚",
+			"⠞",
+			"⠖",
+			"⠦",
+			"⠴",
+			"⠲",
+			"⠳",
+			"⠓",
+			};
+		}
+		public class Dots4 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠄",
+			"⠆",
+			"⠇",
+			"⠋",
+			"⠙",
+			"⠸",
+			"⠰",
+			"⠠",
+			};
+		}
+		public class Dots5 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠋",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠦",
+			"⠖",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠓",
+			"⠋",
+			};
+		}
+		public class Dots6 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠁",
+			"⠁",
+			"⠉",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠤",
+			"⠄",
+			"⠄",
+			};
+		}
+		public class Dots7 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠈",
+			"⠈",
+			"⠉",
+			"⠋",
+			"⠓",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠖",
+			"⠦",
+			"⠤",
+			"⠠",
+			"⠠",
+			};
+		}
+		public class Dots8 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠁",
+			"⠁",
+			"⠉",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠤",
+			"⠄",
+			"⠄",
+			"⠤",
+			"⠠",
+			"⠠",
+			"⠤",
+			"⠦",
+			"⠖",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠓",
+			"⠋",
+			"⠉",
+			"⠈",
+			"⠈",
+			};
+		}
+		public class Dots9 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⢹",
+			"⢺",
+			"⢼",
+			"⣸",
+			"⣇",
+			"⡧",
+			"⡗",
+			"⡏",
+			};
+		}
+		public class Dots10 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⢄",
+			"⢂",
+			"⢁",
+			"⡁",
+			"⡈",
+			"⡐",
+			"⡠",
+			};
+		}
+		public class Dots11 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠁",
+			"⠂",
+			"⠄",
+			"⡀",
+			"⢀",
+			"⠠",
+			"⠐",
+			"⠈",
+			};
+		}
+		public class Dots12 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⢀⠀",
+			"⡀⠀",
+			"⠄⠀",
+			"⢂⠀",
+			"⡂⠀",
+			"⠅⠀",
+			"⢃⠀",
+			"⡃⠀",
+			"⠍⠀",
+			"⢋⠀",
+			"⡋⠀",
+			"⠍⠁",
+			"⢋⠁",
+			"⡋⠁",
+			"⠍⠉",
+			"⠋⠉",
+			"⠋⠉",
+			"⠉⠙",
+			"⠉⠙",
+			"⠉⠩",
+			"⠈⢙",
+			"⠈⡙",
+			"⢈⠩",
+			"⡀⢙",
+			"⠄⡙",
+			"⢂⠩",
+			"⡂⢘",
+			"⠅⡘",
+			"⢃⠨",
+			"⡃⢐",
+			"⠍⡐",
+			"⢋⠠",
+			"⡋⢀",
+			"⠍⡁",
+			"⢋⠁",
+			"⡋⠁",
+			"⠍⠉",
+			"⠋⠉",
+			"⠋⠉",
+			"⠉⠙",
+			"⠉⠙",
+			"⠉⠩",
+			"⠈⢙",
+			"⠈⡙",
+			"⠈⠩",
+			"⠀⢙",
+			"⠀⡙",
+			"⠀⠩",
+			"⠀⢘",
+			"⠀⡘",
+			"⠀⠨",
+			"⠀⢐",
+			"⠀⡐",
+			"⠀⠠",
+			"⠀⢀",
+			"⠀⡀",
+			};
+		}
+		public class Dots8Bit : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠀",
+			"⠁",
+			"⠂",
+			"⠃",
+			"⠄",
+			"⠅",
+			"⠆",
+			"⠇",
+			"⡀",
+			"⡁",
+			"⡂",
+			"⡃",
+			"⡄",
+			"⡅",
+			"⡆",
+			"⡇",
+			"⠈",
+			"⠉",
+			"⠊",
+			"⠋",
+			"⠌",
+			"⠍",
+			"⠎",
+			"⠏",
+			"⡈",
+			"⡉",
+			"⡊",
+			"⡋",
+			"⡌",
+			"⡍",
+			"⡎",
+			"⡏",
+			"⠐",
+			"⠑",
+			"⠒",
+			"⠓",
+			"⠔",
+			"⠕",
+			"⠖",
+			"⠗",
+			"⡐",
+			"⡑",
+			"⡒",
+			"⡓",
+			"⡔",
+			"⡕",
+			"⡖",
+			"⡗",
+			"⠘",
+			"⠙",
+			"⠚",
+			"⠛",
+			"⠜",
+			"⠝",
+			"⠞",
+			"⠟",
+			"⡘",
+			"⡙",
+			"⡚",
+			"⡛",
+			"⡜",
+			"⡝",
+			"⡞",
+			"⡟",
+			"⠠",
+			"⠡",
+			"⠢",
+			"⠣",
+			"⠤",
+			"⠥",
+			"⠦",
+			"⠧",
+			"⡠",
+			"⡡",
+			"⡢",
+			"⡣",
+			"⡤",
+			"⡥",
+			"⡦",
+			"⡧",
+			"⠨",
+			"⠩",
+			"⠪",
+			"⠫",
+			"⠬",
+			"⠭",
+			"⠮",
+			"⠯",
+			"⡨",
+			"⡩",
+			"⡪",
+			"⡫",
+			"⡬",
+			"⡭",
+			"⡮",
+			"⡯",
+			"⠰",
+			"⠱",
+			"⠲",
+			"⠳",
+			"⠴",
+			"⠵",
+			"⠶",
+			"⠷",
+			"⡰",
+			"⡱",
+			"⡲",
+			"⡳",
+			"⡴",
+			"⡵",
+			"⡶",
+			"⡷",
+			"⠸",
+			"⠹",
+			"⠺",
+			"⠻",
+			"⠼",
+			"⠽",
+			"⠾",
+			"⠿",
+			"⡸",
+			"⡹",
+			"⡺",
+			"⡻",
+			"⡼",
+			"⡽",
+			"⡾",
+			"⡿",
+			"⢀",
+			"⢁",
+			"⢂",
+			"⢃",
+			"⢄",
+			"⢅",
+			"⢆",
+			"⢇",
+			"⣀",
+			"⣁",
+			"⣂",
+			"⣃",
+			"⣄",
+			"⣅",
+			"⣆",
+			"⣇",
+			"⢈",
+			"⢉",
+			"⢊",
+			"⢋",
+			"⢌",
+			"⢍",
+			"⢎",
+			"⢏",
+			"⣈",
+			"⣉",
+			"⣊",
+			"⣋",
+			"⣌",
+			"⣍",
+			"⣎",
+			"⣏",
+			"⢐",
+			"⢑",
+			"⢒",
+			"⢓",
+			"⢔",
+			"⢕",
+			"⢖",
+			"⢗",
+			"⣐",
+			"⣑",
+			"⣒",
+			"⣓",
+			"⣔",
+			"⣕",
+			"⣖",
+			"⣗",
+			"⢘",
+			"⢙",
+			"⢚",
+			"⢛",
+			"⢜",
+			"⢝",
+			"⢞",
+			"⢟",
+			"⣘",
+			"⣙",
+			"⣚",
+			"⣛",
+			"⣜",
+			"⣝",
+			"⣞",
+			"⣟",
+			"⢠",
+			"⢡",
+			"⢢",
+			"⢣",
+			"⢤",
+			"⢥",
+			"⢦",
+			"⢧",
+			"⣠",
+			"⣡",
+			"⣢",
+			"⣣",
+			"⣤",
+			"⣥",
+			"⣦",
+			"⣧",
+			"⢨",
+			"⢩",
+			"⢪",
+			"⢫",
+			"⢬",
+			"⢭",
+			"⢮",
+			"⢯",
+			"⣨",
+			"⣩",
+			"⣪",
+			"⣫",
+			"⣬",
+			"⣭",
+			"⣮",
+			"⣯",
+			"⢰",
+			"⢱",
+			"⢲",
+			"⢳",
+			"⢴",
+			"⢵",
+			"⢶",
+			"⢷",
+			"⣰",
+			"⣱",
+			"⣲",
+			"⣳",
+			"⣴",
+			"⣵",
+			"⣶",
+			"⣷",
+			"⢸",
+			"⢹",
+			"⢺",
+			"⢻",
+			"⢼",
+			"⢽",
+			"⢾",
+			"⢿",
+			"⣸",
+			"⣹",
+			"⣺",
+			"⣻",
+			"⣼",
+			"⣽",
+			"⣾",
+			"⣿",
+			};
+		}
+		public class Line : SpinnerStyle {
+			public override int SpinDelay => 130;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			 "-",
+			@"\",
+			 "|",
+			 "/",
+			};
+		}
+		public class Line2 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠂",
+			"-",
+			"–",
+			"—",
+			};
+		}
+		public class Pipe : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"┤",
+			"┘",
+			"┴",
+			"└",
+			"├",
+			"┌",
+			"┬",
+			"┐",
+			};
+		}
+		public class SimpleDots : SpinnerStyle {
+			public override int SpinDelay => 400;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			".  ",
+			".. ",
+			"...",
+			"   ",
+			};
+		}
+		public class SimpleDotsScrolling : SpinnerStyle {
+			public override int SpinDelay => 200;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			".  ",
+			".. ",
+			"...",
+			" ..",
+			"  .",
+			"   ",
+			};
+		}
+		public class Star : SpinnerStyle {
+			public override int SpinDelay => 70;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"✶",
+			"✸",
+			"✹",
+			"✺",
+			"✹",
+			"✷",
+			};
+		}
+		public class Star2 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"+",
+			"x",
+			"*",
+			};
+		}
+		public class Flip : SpinnerStyle {
+			public override int SpinDelay => 70;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"_",
+			"_",
+			"_",
+			"-",
+			"`",
+			"`",
+			"'",
+			"´",
+			"-",
+			"_",
+			"_",
+			"_",
+			};
+		}
+		public class Hamburger : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"☱",
+			"☲",
+			"☴",
+			};
+		}
+		public class GrowVertical : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▁",
+			"▃",
+			"▄",
+			"▅",
+			"▆",
+			"▇",
+			};
+		}
+		public class GrowHorizontal : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▏",
+			"▎",
+			"▍",
+			"▌",
+			"▋",
+			"▊",
+			"▉",
+			};
+		}
+		public class Balloon : SpinnerStyle {
+			public override int SpinDelay => 140;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			" ",
+			".",
+			"o",
+			"O",
+			"@",
+			"*",
+			" ",
+			};
+		}
+		public class Balloon2 : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			".",
+			".",
+			"o",
+			"O",
+			"°",
+			};
+		}
+		public class Noise : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▓",
+			"▒",
+			"░",
+			};
+		}
+		public class Bounce : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⠁",
+			"⠂",
+			"⠄",
+			};
+		}
+		public class BoxBounce : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▖",
+			"▘",
+			"▝",
+			"▗",
+			};
+		}
+		public class BoxBounce2 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▌",
+			"▀",
+			"▐",
+			"▄",
+			};
+		}
+		public class Triangle : SpinnerStyle {
+			public override int SpinDelay => 50;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◢",
+			"◣",
+			"◤",
+			"◥",
+			};
+		}
+		public class Arc : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◜",
+			"◠",
+			"◝",
+			"◞",
+			"◡",
+			"◟",
+			};
+		}
+		public class Circle : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◡",
+			"⊙",
+			"◠",
+			};
+		}
+		public class SquareCorners : SpinnerStyle {
+			public override int SpinDelay => 180;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◰",
+			"◳",
+			"◲",
+			"◱",
+			};
+		}
+		public class CircleQuarters : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◴",
+			"◷",
+			"◶",
+			"◵",
+			};
+		}
+		public class CircleHalves : SpinnerStyle {
+			public override int SpinDelay => 50;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◐",
+			"◓",
+			"◑",
+			"◒",
+			};
+		}
+		public class Squish : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"╫",
+			"╪",
+			};
+		}
+		public class Toggle : SpinnerStyle {
+			public override int SpinDelay => 250;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⊶",
+			"⊷",
+			};
+		}
+		public class Toggle2 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▫",
+			"▪",
+			};
+		}
+		public class Toggle3 : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"□",
+			"■",
+			};
+		}
+		public class Toggle4 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"■",
+			"□",
+			"▪",
+			"▫",
+			};
+		}
+		public class Toggle5 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▮",
+			"▯",
+			};
+		}
+		public class Toggle6 : SpinnerStyle {
+			public override int SpinDelay => 300;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"ဝ",
+			"၀",
+			};
+		}
+		public class Toggle7 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⦾",
+			"⦿",
+			};
+		}
+		public class Toggle8 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◍",
+			"◌",
+			};
+		}
+		public class Toggle9 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"◉",
+			"◎",
+			};
+		}
+		public class Toggle10 : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"㊂",
+			"㊀",
+			"㊁",
+			};
+		}
+		public class Toggle11 : SpinnerStyle {
+			public override int SpinDelay => 50;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"⧇",
+			"⧆",
+			};
+		}
+		public class Toggle12 : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"☗",
+			"☖",
+			};
+		}
+		public class Toggle13 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"=",
+			"*",
+			"-",
+			};
+		}
+		public class Arrow : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"←",
+			"↖",
+			"↑",
+			"↗",
+			"→",
+			"↘",
+			"↓",
+			"↙",
+			};
+		}
+		public class Arrow2 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"⬆️ ",
+			"↗️ ",
+			"➡️ ",
+			"↘️ ",
+			"⬇️ ",
+			"↙️ ",
+			"⬅️ ",
+			"↖️ ",
+			};
+		}
+		public class Arrow3 : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▹▹▹▹▹",
+			"▸▹▹▹▹",
+			"▹▸▹▹▹",
+			"▹▹▸▹▹",
+			"▹▹▹▸▹",
+			"▹▹▹▹▸",
+			};
+		}
+		public class BouncingBar : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"[    ]",
+			"[=   ]",
+			"[==  ]",
+			"[=== ]",
+			"[ ===]",
+			"[  ==]",
+			"[   =]",
+			"[    ]",
+			};
+		}
+		public class BouncingBall : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"(●     )",
+			"( ●    )",
+			"(  ●   )",
+			"(   ●  )",
+			"(    ● )",
+			"(     ●)",
+			};
+		}
+		public class Smiley : SpinnerStyle {
+			public override int SpinDelay => 200;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"😄 ",
+			"😝 ",
+			};
+		}
+		public class Monkey : SpinnerStyle {
+			public override int SpinDelay => 300;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🙈 ",
+			"🙈 ",
+			"🙉 ",
+			"🙊 ",
+			};
+		}
+		public class Hearts : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"💛 ",
+			"💙 ",
+			"💜 ",
+			"💚 ",
+			"❤️ ",
+			};
+		}
+		public class Clock : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🕛 ",
+			"🕐 ",
+			"🕑 ",
+			"🕒 ",
+			"🕓 ",
+			"🕔 ",
+			"🕕 ",
+			"🕖 ",
+			"🕗 ",
+			"🕘 ",
+			"🕙 ",
+			"🕚 ",
+			};
+		}
+		public class Earth : SpinnerStyle {
+			public override int SpinDelay => 180;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🌍 ",
+			"🌎 ",
+			"🌏 ",
+			};
+		}
+		public class Material : SpinnerStyle {
+			public override int SpinDelay => 17;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"███████▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"████████▁▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"██████████▁▁▁▁▁▁▁▁▁▁",
+			"███████████▁▁▁▁▁▁▁▁▁",
+			"█████████████▁▁▁▁▁▁▁",
+			"██████████████▁▁▁▁▁▁",
+			"██████████████▁▁▁▁▁▁",
+			"▁██████████████▁▁▁▁▁",
+			"▁██████████████▁▁▁▁▁",
+			"▁██████████████▁▁▁▁▁",
+			"▁▁██████████████▁▁▁▁",
+			"▁▁▁██████████████▁▁▁",
+			"▁▁▁▁█████████████▁▁▁",
+			"▁▁▁▁██████████████▁▁",
+			"▁▁▁▁██████████████▁▁",
+			"▁▁▁▁▁██████████████▁",
+			"▁▁▁▁▁██████████████▁",
+			"▁▁▁▁▁██████████████▁",
+			"▁▁▁▁▁▁██████████████",
+			"▁▁▁▁▁▁██████████████",
+			"▁▁▁▁▁▁▁█████████████",
+			"▁▁▁▁▁▁▁█████████████",
+			"▁▁▁▁▁▁▁▁████████████",
+			"▁▁▁▁▁▁▁▁████████████",
+			"▁▁▁▁▁▁▁▁▁███████████",
+			"▁▁▁▁▁▁▁▁▁███████████",
+			"▁▁▁▁▁▁▁▁▁▁██████████",
+			"▁▁▁▁▁▁▁▁▁▁██████████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁████████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
+			"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
+			"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
+			"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
+			"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
+			"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
+			"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"██████▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"████████▁▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"█████████▁▁▁▁▁▁▁▁▁▁▁",
+			"███████████▁▁▁▁▁▁▁▁▁",
+			"████████████▁▁▁▁▁▁▁▁",
+			"████████████▁▁▁▁▁▁▁▁",
+			"██████████████▁▁▁▁▁▁",
+			"██████████████▁▁▁▁▁▁",
+			"▁██████████████▁▁▁▁▁",
+			"▁██████████████▁▁▁▁▁",
+			"▁▁▁█████████████▁▁▁▁",
+			"▁▁▁▁▁████████████▁▁▁",
+			"▁▁▁▁▁████████████▁▁▁",
+			"▁▁▁▁▁▁███████████▁▁▁",
+			"▁▁▁▁▁▁▁▁█████████▁▁▁",
+			"▁▁▁▁▁▁▁▁█████████▁▁▁",
+			"▁▁▁▁▁▁▁▁▁█████████▁▁",
+			"▁▁▁▁▁▁▁▁▁█████████▁▁",
+			"▁▁▁▁▁▁▁▁▁▁█████████▁",
+			"▁▁▁▁▁▁▁▁▁▁▁████████▁",
+			"▁▁▁▁▁▁▁▁▁▁▁████████▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
+			};
+		}
+		public class Moon : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🌑 ",
+			"🌒 ",
+			"🌓 ",
+			"🌔 ",
+			"🌕 ",
+			"🌖 ",
+			"🌗 ",
+			"🌘 ",
+			};
+		}
+		public class Runner : SpinnerStyle {
+			public override int SpinDelay => 140;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🚶 ",
+			"🏃 ",
+			};
+		}
+		public class Pong : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▐⠂       ▌",
+			"▐⠈       ▌",
+			"▐ ⠂      ▌",
+			"▐ ⠠      ▌",
+			"▐  ⡀     ▌",
+			"▐  ⠠     ▌",
+			"▐   ⠂    ▌",
+			"▐   ⠈    ▌",
+			"▐    ⠂   ▌",
+			"▐    ⠠   ▌",
+			"▐     ⡀  ▌",
+			"▐     ⠠  ▌",
+			"▐      ⠂ ▌",
+			"▐      ⠈ ▌",
+			"▐       ⠂▌",
+			"▐       ⠠▌",
+			"▐       ⡀▌",
+			"▐      ⠠ ▌",
+			"▐      ⠂ ▌",
+			"▐     ⠈  ▌",
+			"▐     ⠂  ▌",
+			"▐    ⠠   ▌",
+			"▐    ⡀   ▌",
+			"▐   ⠠    ▌",
+			"▐   ⠂    ▌",
+			"▐  ⠈     ▌",
+			"▐  ⠂     ▌",
+			"▐ ⠠      ▌",
+			"▐ ⡀      ▌",
+			"▐⠠       ▌",
+			};
+		}
+		public class Shark : SpinnerStyle {
+			public override int SpinDelay => 120;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			@"▐|\____________▌",
+			@"▐_|\___________▌",
+			@"▐__|\__________▌",
+			@"▐___|\_________▌",
+			@"▐____|\________▌",
+			@"▐_____|\_______▌",
+			@"▐______|\______▌",
+			@"▐_______|\_____▌",
+			@"▐________|\____▌",
+			@"▐_________|\___▌",
+			@"▐__________|\__▌",
+			@"▐___________|\_▌",
+			@"▐____________|\▌",
+			 "▐____________/|▌",
+			 "▐___________/|_▌",
+			 "▐__________/|__▌",
+			 "▐_________/|___▌",
+			 "▐________/|____▌",
+			 "▐_______/|_____▌",
+			 "▐______/|______▌",
+			 "▐_____/|_______▌",
+			 "▐____/|________▌",
+			 "▐___/|_________▌",
+			 "▐__/|__________▌",
+			 "▐_/|___________▌",
+			 "▐/|____________▌",
+			};
+		}
+		public class Dqpb : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"d",
+			"q",
+			"p",
+			"b",
+			};
+		}
+		public class Weather : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"☀️ ",
+			"☀️ ",
+			"☀️ ",
+			"🌤 ",
+			"⛅️ ",
+			"🌥 ",
+			"☁️ ",
+			"🌧 ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"⛈ ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"☁️ ",
+			"🌥 ",
+			"⛅️ ",
+			"🌤 ",
+			"☀️ ",
+			"☀️ ",
+			};
+		}
+		public class Christmas : SpinnerStyle {
+			public override int SpinDelay => 400;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🌲",
+			"🎄",
+			};
+		}
+		public class Grenade : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"،   ",
+			"′   ",
+			" ´ ",
+			" ‾ ",
+			"  ⸌",
+			"  ⸊",
+			"  |",
+			"  ⁎",
+			"  ⁕",
+			" ෴ ",
+			"  ⁓",
+			"   ",
+			"   ",
+			"   ",
+			};
+		}
+		public class Points : SpinnerStyle {
+			public override int SpinDelay => 125;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"∙∙∙",
+			"●∙∙",
+			"∙●∙",
+			"∙∙●",
+			"∙∙∙",
+			};
+		}
+		public class Layer : SpinnerStyle {
+			public override int SpinDelay => 150;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"-",
+			"=",
+			"≡",
+			};
+		}
+		public class BetaWave : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"ρββββββ",
+			"βρβββββ",
+			"ββρββββ",
+			"βββρβββ",
+			"ββββρββ",
+			"βββββρβ",
+			"ββββββρ",
+			};
+		}
+		public class FingerDance : SpinnerStyle {
+			public override int SpinDelay => 160;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🤘 ",
+			"🤟 ",
+			"🖖 ",
+			"✋ ",
+			"🤚 ",
+			"👆 "
+			};
+		}
+		public class FistBump : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🤜\u3000\u3000\u3000\u3000🤛 ",
+			"🤜\u3000\u3000\u3000\u3000🤛 ",
+			"🤜\u3000\u3000\u3000\u3000🤛 ",
+			"\u3000🤜\u3000\u3000🤛\u3000 ",
+			"\u3000\u3000🤜🤛\u3000\u3000 ",
+			"\u3000🤜✨🤛\u3000\u3000 ",
+			"🤜\u3000✨\u3000🤛\u3000 "
+			};
+		}
+		public class SoccerHeader : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			" 🧑⚽️       🧑 ",
+			"🧑  ⚽️      🧑 ",
+			"🧑   ⚽️     🧑 ",
+			"🧑    ⚽️    🧑 ",
+			"🧑     ⚽️   🧑 ",
+			"🧑      ⚽️  🧑 ",
+			"🧑       ⚽️🧑  ",
+			};
+		}
+		public class MindBlown : SpinnerStyle {
+			public override int SpinDelay => 160;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"😐 ",
+			"😐 ",
+			"😮 ",
+			"😮 ",
+			"😦 ",
+			"😦 ",
+			"😧 ",
+			"😧 ",
+			"🤯 ",
+			"💥 ",
+			"✨ ",
+			"\u3000 ",
+			"\u3000 ",
+			"\u3000 "
+			};
+		}
+		public class Speaker : SpinnerStyle {
+			public override int SpinDelay => 160;
+			public override bool SpinBounce => true;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🔈 ",
+			"🔉 ",
+			"🔊 ",
+			};
+		}
+		public class OrangePulse : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🔸 ",
+			"🔶 ",
+			"🟠 ",
+			"🟠 ",
+			"🔶 "
+			};
+		}
+		public class BluePulse : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🔹 ",
+			"🔷 ",
+			"🔵 ",
+			"🔵 ",
+			"🔷 "
+			};
+		}
+		public class OrangeBluePulse : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🔸 ",
+			"🔶 ",
+			"🟠 ",
+			"🟠 ",
+			"🔶 ",
+			"🔹 ",
+			"🔷 ",
+			"🔵 ",
+			"🔵 ",
+			"🔷 "
+			};
+		}
+		public class TimeTravelClock : SpinnerStyle {
+			public override int SpinDelay => 100;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => true;
+			public override string [] Sequence => new string []
+			{
+			"🕛 ",
+			"🕚 ",
+			"🕙 ",
+			"🕘 ",
+			"🕗 ",
+			"🕖 ",
+			"🕕 ",
+			"🕔 ",
+			"🕓 ",
+			"🕒 ",
+			"🕑 ",
+			"🕐 "
+			};
+		}
+		public class Aesthetic : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▰▱▱▱▱▱▱",
+			"▰▰▱▱▱▱▱",
+			"▰▰▰▱▱▱▱",
+			"▰▰▰▰▱▱▱",
+			"▰▰▰▰▰▱▱",
+			"▰▰▰▰▰▰▱",
+			"▰▰▰▰▰▰▰",
+			"▰▱▱▱▱▱▱",
+			};
+		}
+		public class Aesthetic2 : SpinnerStyle {
+			public override int SpinDelay => DEFAULT_DELAY;
+			public override bool SpinBounce => DEFAULT_BOUNCE;
+			public override bool HasSpecialCharacters => DEFAULT_SPECIAL;
+			public override string [] Sequence => new string []
+			{
+			"▰▱▱▱▱▱▱",
+			"▰▰▱▱▱▱▱",
+			"▰▰▰▱▱▱▱",
+			"▰▰▰▰▱▱▱",
+			"▰▰▰▰▰▱▱",
+			"▰▰▰▰▰▰▱",
+			"▰▰▰▰▰▰▰",
+			"▱▰▰▰▰▰▰",
+			"▱▱▰▰▰▰▰",
+			"▱▱▱▰▰▰▰",
+			"▱▱▱▱▰▰▰",
+			"▱▱▱▱▱▰▰",
+			"▱▱▱▱▱▱▰",
+			"▱▱▱▱▱▱▱",
+			};
+		}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
+	}
+}

+ 219 - 0
Terminal.Gui/Views/SpinnerView/SpinnerView.cs

@@ -0,0 +1,219 @@
+//------------------------------------------------------------------------------
+// Windows Terminal supports Unicode and Emoji characters, but by default
+// conhost shells (e.g., PowerShell and cmd.exe) do not. See
+// <https://spectreconsole.net/best-practices>.
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace Terminal.Gui {
+	/// <summary>
+	/// A <see cref="View"/> which displays (by default) a spinning line character.
+	/// </summary>
+	/// <remarks>
+	/// By default animation only occurs when you call <see cref="View.SetNeedsDisplay()"/>.
+	/// Use <see cref="AutoSpin"/> to make the automate calls to <see cref="View.SetNeedsDisplay()"/>.
+	/// </remarks>
+	public class SpinnerView : View {
+		private const int DEFAULT_DELAY = 130;
+		private static readonly SpinnerStyle DEFAULT_STYLE = new SpinnerStyle.Line ();
+
+		private SpinnerStyle _style = DEFAULT_STYLE;
+		private int _delay = DEFAULT_STYLE.SpinDelay;
+		private bool _bounce = DEFAULT_STYLE.SpinBounce;
+		private string [] _sequence = DEFAULT_STYLE.Sequence;
+		private bool _bounceReverse = false;
+		private int _currentIdx = 0;
+		private DateTime _lastRender = DateTime.MinValue;
+		private object _timeout;
+
+		/// <summary>
+		/// Gets or sets the Style used to animate the spinner.
+		/// </summary>
+		public SpinnerStyle Style { get => _style; set => SetStyle (value); }
+
+		/// <summary>
+		/// Gets or sets the animation frames used to animate the spinner.
+		/// </summary>
+		public string [] Sequence { get => _sequence; set => SetSequence (value); }
+
+		/// <summary>
+		/// Gets or sets the number of milliseconds to wait between characters
+		/// in the animation.
+		/// </summary>
+		/// <remarks>This is the maximum speed the spinner will rotate at.  You still need to
+		/// call <see cref="View.SetNeedsDisplay()"/> or <see cref="SpinnerView.AutoSpin"/> to
+		/// advance/start animation.</remarks>
+		public int SpinDelay { get => _delay; set => SetDelay (value); }
+
+		/// <summary>
+		/// Gets or sets whether spinner should go back and forth through the frames rather than
+		/// going to the end and starting again at the beginning.
+		/// </summary>
+		public bool SpinBounce { get => _bounce; set => SetBounce (value); }
+
+		/// <summary>
+		/// Gets or sets whether spinner should go through the frames in reverse order.
+		/// If SpinBounce is true, this sets the starting order.
+		/// </summary>
+		public bool SpinReverse { get; set; } = false;
+
+		/// <summary>
+		/// Gets whether the current spinner style contains emoji or other special characters.
+		/// Does not check Custom sequences.
+		/// </summary>
+		public bool HasSpecialCharacters { get => _style.HasSpecialCharacters; }
+
+		/// <summary>
+		/// Gets whether the current spinner style contains only ASCII characters.  Also checks Custom sequences.
+		/// </summary>
+		public bool IsAsciiOnly { get => GetIsAsciiOnly (); }
+
+		/// <summary>
+		/// Creates a new instance of the <see cref="SpinnerView"/> class.
+		/// </summary>
+		public SpinnerView ()
+		{
+			Width = 1;
+			Height = 1;
+			_delay = DEFAULT_DELAY;
+			_bounce = false;
+			SpinReverse = false;
+			SetStyle (DEFAULT_STYLE);
+		}
+
+		private void SetStyle (SpinnerStyle style)
+		{
+			if (style is not null) {
+				_style = style;
+				_sequence = style.Sequence;
+				_delay = style.SpinDelay;
+				_bounce = style.SpinBounce;
+				Width = GetSpinnerWidth ();
+			}
+		}
+
+		private void SetSequence (string [] frames)
+		{
+			if (frames is not null && frames.Length > 0) {
+				_style = new SpinnerStyle.Custom ();
+				_sequence = frames;
+				Width = GetSpinnerWidth ();
+			}
+		}
+
+		private void SetDelay (int delay)
+		{
+			if (delay > -1) {
+				_delay = delay;
+			}
+		}
+
+		private void SetBounce (bool bounce)
+		{
+			_bounce = bounce;
+		}
+
+		private int GetSpinnerWidth ()
+		{
+			int max = 0;
+			if (_sequence is not null && _sequence.Length > 0) {
+				foreach (string frame in _sequence) {
+					if (frame.Length > max) {
+						max = frame.Length;
+					}
+				}
+			}
+			return max;
+		}
+
+		private bool GetIsAsciiOnly ()
+		{
+			if (HasSpecialCharacters) {
+				return false;
+			}
+			if (_sequence is not null && _sequence.Length > 0) {
+				foreach (string frame in _sequence) {
+					foreach (char c in frame) {
+						if (!char.IsAscii (c)) {
+							return false;
+						}
+					}
+				}
+				return true;
+			}
+			return true;
+		}
+
+		/// <inheritdoc/>
+		public override void Redraw (Rect bounds)
+		{
+			if (DateTime.Now - _lastRender > TimeSpan.FromMilliseconds (SpinDelay)) {
+				//_currentIdx = (_currentIdx + 1) % Sequence.Length;
+				if (Sequence is not null && Sequence.Length > 1) {
+					int d = 1;
+					if ((_bounceReverse && !SpinReverse) || (!_bounceReverse && SpinReverse)) {
+						d = -1;
+					}
+					_currentIdx += d;
+
+					if (_currentIdx >= Sequence.Length) {
+						if (SpinBounce) {
+							if (SpinReverse) {
+								_bounceReverse = false;
+							} else {
+								_bounceReverse = true;
+							}
+							_currentIdx = Sequence.Length - 1;
+						} else {
+							_currentIdx = 0;
+						}
+					}
+					if (_currentIdx < 0) {
+						if (SpinBounce) {
+							if (SpinReverse) {
+								_bounceReverse = true;
+							} else {
+								_bounceReverse = false;
+							}
+							_currentIdx = 1;
+						} else {
+							_currentIdx = Sequence.Length - 1;
+						}
+					}
+					Text = "" + Sequence [_currentIdx]; //.EnumerateRunes;
+				}
+				_lastRender = DateTime.Now;
+			}
+
+			base.Redraw (bounds);
+		}
+
+		/// <summary>
+		/// Automates spinning
+		/// </summary>
+		public void AutoSpin ()
+		{
+			if (_timeout != null) {
+				return;
+			}
+
+			_timeout = Application.MainLoop.AddTimeout (
+				TimeSpan.FromMilliseconds (SpinDelay), (m) => {
+					Application.MainLoop.Invoke (this.SetNeedsDisplay);
+					return true;
+				});
+		}
+
+		/// <inheritdoc/>
+		protected override void Dispose (bool disposing)
+		{
+			if (_timeout != null) {
+				Application.MainLoop.RemoveTimeout (_timeout);
+				_timeout = null;
+			}
+
+			base.Dispose (disposing);
+		}
+	}
+}

+ 14 - 10
UICatalog/Scenarios/Progress.cs

@@ -3,7 +3,6 @@ using System;
 using System.Threading;
 using Terminal.Gui;
 using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace UICatalog.Scenarios {
 	// 
@@ -11,7 +10,7 @@ namespace UICatalog.Scenarios {
 	//
 	[ScenarioMetadata (Name: "Progress", Description: "Shows off ProgressBar and Threading.")]
 	[ScenarioCategory ("Controls")]
-	[ScenarioCategory ("Threading"), ScenarioCategory ("ProgressBar")]
+	[ScenarioCategory ("Threading"), ScenarioCategory ("Progress")]
 	public class Progress : Scenario {
 
 		class ProgressDemo : FrameView {
@@ -79,25 +78,29 @@ namespace UICatalog.Scenarios {
 				ActivityProgressBar = new ProgressBar () {
 					X = Pos.Right (LeftFrame) + 1,
 					Y = Pos.Bottom (startButton) + 1,
-					Width = Dim.Fill (),
+					Width = Dim.Fill () - 1,
 					Height = 1,
 					Fraction = 0.25F,
 					ColorScheme = Colors.Error
 				};
 				Add (ActivityProgressBar);
 
-				Spinner = new SpinnerView {
-					X = Pos.Right (ActivityProgressBar),
+				Spinner = new SpinnerView () {
+					Style = new SpinnerStyle.Dots2 (),
+					SpinReverse = true,
 					Y = ActivityProgressBar.Y,
-					Visible = false,
-
+					Visible = false
 				};
+				ActivityProgressBar.Width = Dim.Fill () - Spinner.Width;
+				Spinner.X = Pos.Right (ActivityProgressBar);
+
+
 				Add (Spinner);
 
 				PulseProgressBar = new ProgressBar () {
 					X = Pos.Right (LeftFrame) + 1,
 					Y = Pos.Bottom (ActivityProgressBar) + 1,
-					Width = Dim.Fill (),
+					Width = Dim.Fill () - Spinner.Width,
 					Height = 1,
 					ColorScheme = Colors.Error
 				};
@@ -122,7 +125,7 @@ namespace UICatalog.Scenarios {
 				StartBtnClick?.Invoke ();
 				Application.MainLoop.Invoke(()=>{
 					Spinner.Visible = true;
-					ActivityProgressBar.Width = Dim.Fill(1);
+					ActivityProgressBar.Width = Dim.Fill () - Spinner.Width;
 					this.LayoutSubviews();
 				});
 			}
@@ -134,13 +137,14 @@ namespace UICatalog.Scenarios {
 
 				Application.MainLoop.Invoke(()=>{
 					Spinner.Visible = false;
-					ActivityProgressBar.Width = Dim.Fill();
+					ActivityProgressBar.Width = Dim.Fill () - Spinner.Width;
 					this.LayoutSubviews();
 				});
 			}
 
 			internal void Pulse ()
 			{
+				Spinner.Visible = true;
 				if (PulseBtnClick != null) {
 					PulseBtnClick?.Invoke ();
 

+ 1 - 1
UICatalog/Scenarios/ProgressBarStyles.cs

@@ -6,7 +6,7 @@ using Terminal.Gui;
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "ProgressBar Styles", Description: "Shows the ProgressBar Styles.")]
 	[ScenarioCategory ("Controls")]
-	[ScenarioCategory ("ProgressBar")]
+	[ScenarioCategory ("Progress")]
 	[ScenarioCategory ("Threading")]
 
 	public class ProgressBarStyles : Scenario {

+ 183 - 0
UICatalog/Scenarios/SpinnerStyles.cs

@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Terminal.Gui;
+
+namespace UICatalog.Scenarios {
+	[ScenarioMetadata (Name: "SpinnerView Styles", Description: "Shows the SpinnerView Styles.")]
+	[ScenarioCategory ("Controls")]
+	[ScenarioCategory ("Progress")]
+
+	public class SpinnerViewStyles : Scenario {
+		class Property {
+			public string Name { get; set; }
+		}
+
+		public override void Setup ()
+		{
+			const int DEFAULT_DELAY = 130;
+			const string DEFAULT_CUSTOM = @"-\|/";
+			var styleDict = new Dictionary<int, KeyValuePair<string, Type>> ();
+			int i = 0;
+			foreach (var style in typeof (SpinnerStyle).GetNestedTypes ()) {
+				styleDict.Add (i, new KeyValuePair<string, Type> (style.Name, style));
+				i++;
+			}
+
+			var preview = new View () {
+				X = Pos.Center (),
+				Y = 0,
+				Width = 22,
+				Height = 3,
+				//Title = "Preview",
+				BorderStyle = LineStyle.Single
+			};
+			Win.Add (preview);
+
+			var spinner = new SpinnerView () {
+				X = Pos.Center (),
+				Y = 0
+			};
+			preview.Add (spinner);
+			spinner.AutoSpin ();
+
+			var ckbAscii = new CheckBox ("Ascii Only", false) {
+				X = Pos.Center () - 7,
+				Y = Pos.Bottom (preview),
+				Enabled = false,
+				Checked = true
+			};
+			Win.Add (ckbAscii);
+
+			var ckbNoSpecial = new CheckBox ("No Special", false) {
+				X = Pos.Center () + 7,
+				Y = Pos.Bottom (preview),
+				Enabled = false,
+				Checked = true
+			};
+			Win.Add (ckbNoSpecial);
+
+			var ckbReverse = new CheckBox ("Reverse", false) {
+				X = Pos.Center () - 22,
+				Y = Pos.Bottom (preview) + 1,
+				Checked = false
+			};
+			Win.Add (ckbReverse);
+
+			var ckbBounce = new CheckBox ("Bounce", false) {
+				X = Pos.Right (ckbReverse) + 2,
+				Y = Pos.Bottom (preview) + 1,
+				Checked = false
+			};
+			Win.Add (ckbBounce);
+
+			var delayLabel = new Label ("Delay:") {
+				X = Pos.Right (ckbBounce) + 2,
+				Y = Pos.Bottom (preview) + 1
+			};
+			Win.Add (delayLabel);
+			var delayField = new TextField (DEFAULT_DELAY.ToString ()) {
+				X = Pos.Right (delayLabel),
+				Y = Pos.Bottom (preview) + 1,
+				Width = 5
+			};
+			Win.Add (delayField);
+			delayField.TextChanged += (s, e) => {
+				if (ushort.TryParse (delayField.Text.ToString (), out var i))
+					spinner.SpinDelay = i;
+			};
+
+			var customLabel = new Label ("Custom:") {
+				X = Pos.Right (delayField) + 2,
+				Y = Pos.Bottom (preview) + 1
+			};
+			Win.Add (customLabel);
+			var customField = new TextField (DEFAULT_CUSTOM) {
+				X = Pos.Right (customLabel),
+				Y = Pos.Bottom (preview) + 1,
+				Width = 12
+			};
+			Win.Add (customField);
+
+			var styleArray = styleDict.Select (e => NStack.ustring.Make (e.Value.Key.ToString ())).ToArray ();
+			if (styleArray.Length < 1)
+				return;
+
+			var styles = new ListView () {
+				X = Pos.Center (),
+				Y = Pos.Bottom (preview) + 2,
+				Height = Dim.Fill (),
+				Width = Dim.Fill (1)
+			};
+			styles.SetSource (styleArray);
+			styles.SelectedItem = 0; // SpinnerStyle.Custom;
+			Win.Add (styles);
+			SetCustom ();
+
+			customField.TextChanged += (s, e) => {
+				if (customField.Text.Length > 0) {
+					if (styles.SelectedItem != 0)
+						styles.SelectedItem = 0; // SpinnerStyle.Custom
+					SetCustom ();
+				}
+			};
+
+			styles.SelectedItemChanged += (s, e) => {
+				if (e.Item == 0) { // SpinnerStyle.Custom
+					if (customField.Text.Length < 1)
+						customField.Text = DEFAULT_CUSTOM;
+					if (delayField.Text.Length < 1)
+						delayField.Text = DEFAULT_DELAY.ToString ();
+					SetCustom ();
+				} else {
+					spinner.Visible = true;
+					spinner.Style = (SpinnerStyle)Activator.CreateInstance(styleDict [e.Item].Value);
+					delayField.Text = spinner.SpinDelay.ToString ();
+					ckbBounce.Checked = spinner.SpinBounce;
+					ckbNoSpecial.Checked = !spinner.HasSpecialCharacters;
+					ckbAscii.Checked = spinner.IsAsciiOnly;
+					ckbReverse.Checked = false;
+				}
+			};
+
+			ckbReverse.Toggled += (s, e) => {
+				spinner.SpinReverse = (bool)!e.OldValue;
+			};
+
+			ckbBounce.Toggled += (s, e) => {
+				spinner.SpinBounce = (bool)!e.OldValue;
+			};
+
+			Application.Top.Unloaded += Top_Unloaded;
+
+			void SetCustom ()
+			{
+				if (customField.Text.Length > 0) {
+					spinner.Visible = true;
+					if (ushort.TryParse (delayField.Text.ToString (), out var d))
+						spinner.SpinDelay = d;
+					else {
+						delayField.Text = DEFAULT_DELAY.ToString ();
+						spinner.SpinDelay = DEFAULT_DELAY;
+					}
+					var str = new List<string> ();
+					foreach (var c in customField.Text.ToString ().ToCharArray ()) {
+						str.Add (c.ToString ());
+					}
+					spinner.Sequence = str.ToArray ();
+				} else {
+					spinner.Visible = false;
+				}
+			}
+
+			void Top_Unloaded (object sender, EventArgs args)
+			{
+				if (spinner != null) {
+					spinner.Dispose ();
+					spinner = null;
+				}
+				Application.Top.Unloaded -= Top_Unloaded;
+			}
+		}
+	}
+}

+ 7 - 7
UnitTests/Views/SpinnerViewTests.cs

@@ -42,19 +42,19 @@ namespace Terminal.Gui.ViewsTests {
 
 			view.Redraw (view.Bounds);
 
-			var expected = "/";
+			var expected = @"\";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
 			view.SetNeedsDisplay ();
 			view.Redraw (view.Bounds);
 
-			expected = "/";
+			expected = @"\";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
 			view.SetNeedsDisplay ();
 			view.Redraw (view.Bounds);
 
-			expected = "/";
+			expected = @"\";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
 			Task.Delay (400).Wait();
@@ -62,24 +62,24 @@ namespace Terminal.Gui.ViewsTests {
 			view.SetNeedsDisplay ();
 			view.Redraw (view.Bounds);
 
-			expected = "";
+			expected = "|";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 		}
 		[Fact, AutoInitShutdown]
 		public void TestSpinnerView_NoThrottle ()
 		{
 			var view = GetSpinnerView ();
-			view.SpinDelayInMilliseconds = 0;
+			view.SpinDelay = 0;
 
 			view.Redraw (view.Bounds);
 
-			var expected = @"─";
+			var expected = "|";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
 			view.SetNeedsDisplay ();
 			view.Redraw (view.Bounds);
 
-			expected = @"\";
+			expected = "/";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 		}