class Program { static async Task Main() { Console.WriteLine(DateTime.Now.ToString()); await TypeText("Hello"); Console.WriteLine(); string[] options = new string[] { "Play", "Load Save", "Settings", "Exit" }; int selectedOption = await PromptChoice(options, highlightColor: ConsoleColor.Blue, useHorizontal: true); switch (selectedOption) { case 1: Console.Write($"{options[0]} was selected."); break; case 2: Console.Write($"{options[1]} was selected."); break; case 3: Console.Write($"{options[2]} was selected."); break; case 4: Console.Write($"{options[3]} was selected."); break; } } static async Task TypeText(string text, int delay = 100) { foreach (char character in text) { Console.Write(character); await Task.Delay(delay); } } static async Task PromptChoice(string[] options = null, ConsoleColor highlightColor = ConsoleColor.White, bool useDynamicPadding = true, bool useHorizontal = false) { bool oldCursorState = Console.CursorVisible; int startingRow = Console.CursorTop; int startingColumn = Console.CursorLeft; int optionCount = options?.Length ?? 4; int selectedOption = 1; if (options == null) { options = new string[] { "Option 1", "Option 2", "Option 3", "Exit" }; } int maxOptionLength = options.Max(option => option.Length); if (startingRow != 0 || startingColumn != 0) { Console.WriteLine(new string('—', 30)); } await TypeText("Select an option:"); while (true) { Console.CursorVisible = (oldCursorState != false) ? false : Console.CursorVisible; for (int i = 0; i < optionCount; i++) { string optionText = options[i]; int lastOptionLength = i == 0 ? 1 : options[i - 1].Length; bool isSelected = selectedOption == (i + 1); string padding = isSelected ? "> " : " "; if (useHorizontal) Console.SetCursorPosition(startingColumn + (lastOptionLength + 2), startingRow + ((startingRow != 0) ? 3 : 2)) ; else Console.SetCursorPosition(startingColumn, startingRow + i + ((startingRow != 0) ? 3 : 2)); Console.ForegroundColor = isSelected ? highlightColor : Console.ForegroundColor; if (useHorizontal) Console.Write(isSelected ? $" \x1B[4m{optionText}\x1B[0m" : $" {optionText}"); else Console.Write(padding + (useDynamicPadding ? optionText.PadRight(maxOptionLength) + " " : optionText)); Console.ResetColor(); } ConsoleKey userInput = Console.ReadKey(true).Key; switch (userInput) { case ConsoleKey.UpArrow: selectedOption = Math.Max(1, selectedOption - 1); break; case ConsoleKey.DownArrow: selectedOption = Math.Min(optionCount, selectedOption + 1); break; case ConsoleKey.LeftArrow: if (useHorizontal) selectedOption = Math.Max(1, selectedOption - 1); break; case ConsoleKey.RightArrow: if (useHorizontal) selectedOption = Math.Min(optionCount, selectedOption + 1); break; case ConsoleKey.Enter: Console.WriteLine(); Console.CursorVisible = oldCursorState; return selectedOption; } } } }