Script for automating a large assortment of AME related actions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
7.9 KiB

9 months ago
  1. using System;
  2. using System.Linq;
  3. namespace Ameliorated.ConsoleUtils
  4. {
  5. public static partial class ConsoleTUI
  6. {
  7. public static Frame OpenFrame;
  8. public partial class Frame
  9. {
  10. private int _displayWidth;
  11. private int _sidePadding;
  12. /// <summary>
  13. /// Sets the visual "frame" to be used later.
  14. /// </summary>
  15. /// <param name="header">The header to be displayed just under the top of the frame.</param>
  16. /// <param name="ignoreHeader">
  17. /// Indicates whether an exception should be raised if the header cannot be aligned with the
  18. /// frame.
  19. /// </param>
  20. /// <exception cref="MethodAccessException">Function was called before a TUI initialization.</exception>
  21. public Frame(string header, bool throwOnMisalignedHeader = true)
  22. {
  23. if (!IsInitialized) throw new MethodAccessException("Console TUI must be initialized before calling other TUI functions.");
  24. if (header.Split(new[]
  25. { "\r\n", "\n" }, StringSplitOptions.None).Any(x => x.Length > InitializedWidth)) throw new ArgumentException("Header must not be longer than the window width.");
  26. int frameWidth;
  27. if (InitializedWidth.IsEven())
  28. {
  29. if (!header.Length.IsEven() && throwOnMisalignedHeader) throw new ArgumentException("Header length should be even while window width is even.");
  30. frameWidth = (.725 * InitializedWidth).RoundToEven();
  31. } else
  32. {
  33. if (header.Length.IsEven() && throwOnMisalignedHeader) throw new ArgumentException("Header length should be odd while window width is odd.");
  34. frameWidth = (.725 * InitializedWidth).RoundToOdd();
  35. }
  36. Header = header;
  37. FrameWidth = frameWidth;
  38. DisplayWidth = frameWidth - SidePadding * 2;
  39. DisplayOffset = (InitializedWidth - DisplayWidth) / 2;
  40. }
  41. public string Header { get; set; }
  42. public char FrameChar { get; set; } = '_';
  43. public int FrameWidth { get; set; }
  44. public int SidePadding
  45. {
  46. get => _sidePadding;
  47. set
  48. {
  49. _sidePadding = value;
  50. DisplayWidth = FrameWidth - value * 2;
  51. DisplayOffset = (InitializedWidth - DisplayWidth) / 2;
  52. }
  53. }
  54. public int DisplayWidth
  55. {
  56. get => _displayWidth;
  57. set
  58. {
  59. _displayWidth = value;
  60. DisplayOffset = (InitializedWidth - value) / 2;
  61. }
  62. }
  63. internal int DisplayOffset { get; private set; }
  64. internal int DisplayHeight { get; } = Console.WindowHeight - 13;
  65. public void Open(bool paddingLines = true)
  66. {
  67. Console.WriteLine();
  68. var frameOffset = (InitializedWidth - FrameWidth) / 2;
  69. Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth));
  70. Console.WriteLine();
  71. WriteCenteredLine(Header);
  72. if (paddingLines)
  73. {
  74. Console.WriteLine();
  75. Console.WriteLine();
  76. }
  77. OpenFrame = this;
  78. }
  79. public object Close(Prompt prompt = null, bool alignToBottom = false)
  80. {
  81. OpenFrame = null;
  82. if (alignToBottom)
  83. Console.SetCursorPosition(0, Console.WindowHeight - 7);
  84. Console.WriteLine();
  85. Console.WriteLine();
  86. var frameOffset = (InitializedWidth - FrameWidth) / 2;
  87. Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth));
  88. Console.WriteLine();
  89. if (prompt != null)
  90. {
  91. if (!prompt.MaxLength.HasValue)
  92. prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length;
  93. prompt.BindToOpenFrame = false;
  94. prompt.Text = new string(' ', frameOffset) + prompt.Text;
  95. try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {}
  96. try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {}
  97. }
  98. return null;
  99. }
  100. public object Close(string text, Prompt prompt = null, bool alignToBottom = false)
  101. {
  102. OpenFrame = null;
  103. if (alignToBottom)
  104. Console.SetCursorPosition(0, Console.WindowHeight - 7);
  105. Console.WriteLine();
  106. WriteCenteredLine(text, true);
  107. var frameOffset = (InitializedWidth - FrameWidth) / 2;
  108. Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth));
  109. Console.WriteLine();
  110. if (prompt != null)
  111. {
  112. if (!prompt.MaxLength.HasValue)
  113. prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length;
  114. prompt.BindToOpenFrame = false;
  115. prompt.Text = new string(' ', frameOffset) + prompt.Text;
  116. try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {}
  117. try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {}
  118. }
  119. return null;
  120. }
  121. public object Close(string text, ConsoleColor foreground, ConsoleColor background, Prompt prompt = null, bool alignToBottom = false)
  122. {
  123. OpenFrame = null;
  124. if (alignToBottom)
  125. Console.SetCursorPosition(0, Console.WindowHeight - 7);
  126. Console.WriteLine();
  127. WriteCenteredLine(text, foreground, background, true);
  128. var frameOffset = (InitializedWidth - FrameWidth) / 2;
  129. Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth));
  130. Console.WriteLine();
  131. if (prompt != null)
  132. {
  133. if (!prompt.MaxLength.HasValue)
  134. prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length;
  135. prompt.BindToOpenFrame = false;
  136. prompt.Text = new string(' ', frameOffset) + prompt.Text;
  137. try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {}
  138. try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {}
  139. }
  140. return null;
  141. }
  142. public void Clear(int bottomOffset = 2)
  143. {
  144. for (int i = 0; i < Console.WindowHeight - (6 + bottomOffset); i++)
  145. {
  146. Console.SetCursorPosition(DisplayOffset, i + 6);
  147. Console.Write(new string(' ', DisplayWidth));
  148. }
  149. Console.SetCursorPosition(0, 6);
  150. OpenFrame = this;
  151. }
  152. public int AvailableLines()
  153. {
  154. var totalLines = DisplayHeight - (Math.Max(Console.CursorTop - 6, 0));
  155. return totalLines;
  156. }
  157. public int AvailableChars()
  158. {
  159. var totalChars = Math.Max(Console.CursorLeft - DisplayOffset, 0) + (AvailableLines() * DisplayWidth);
  160. return totalChars;
  161. }
  162. }
  163. }
  164. }