Skip to content

Instantly share code, notes, and snippets.

@JerryNixon
Created February 9, 2023 17:31
Show Gist options
  • Save JerryNixon/6bf47679b77c5815268e6b1f0538bdba to your computer and use it in GitHub Desktop.
Save JerryNixon/6bf47679b77c5815268e6b1f0538bdba to your computer and use it in GitHub Desktop.
Week 04 Coding in Class Snapshot
public static class Menu
{
/// <summary>
/// Displays a menu of options on the console and waits for the user to make a selection.
/// </summary>
/// <param name="x">The x-coordinate of the top-left corner of the menu box.</param>
/// <param name="y">The y-coordinate of the top-left corner of the menu box.</param>
/// <param name="items">The options to display in the menu.</param>
/// <returns>The selected option as a string.</returns>
public static void Draw(int x, int y, string current, string[] items)
{
foreach (var item in items)
{
if (item == current)
{
Screen.WriteAt(item, x, y++, ConsoleColor.Black, ConsoleColor.White);
}
else
{
Screen.WriteAt(item, x, y++, ConsoleColor.White, ConsoleColor.Black);
}
}
}
}
using System;
internal class Program
{
private static async Task Main(string[] args)
{
Setup();
var items = new[] { "Clear the directory", "Create files", "Arrange files" };
var current = items[0];
while (true)
{
Menu.Draw(0, 0, current, items);
var key = Console.ReadKey(true).Key;
if (key == ConsoleKey.UpArrow)
{
if (current != items.First())
{
var index = Array.IndexOf(items, current);
current = items[index - 1];
}
}
else if (key == ConsoleKey.DownArrow)
{
if (current != items.Last())
{
var index = Array.IndexOf(items, current);
current = items[index + 1];
}
}
else if (key == ConsoleKey.Enter)
{
var l = items.Max(x => x.Length);
var s = new string(' ', l);
Screen.WriteAt(s, 0, items.Length, ConsoleColor.White, ConsoleColor.Black);
Screen.WriteAt(current, 0, items.Length, ConsoleColor.Yellow, ConsoleColor.Blue);
}
else
{
HandleInvalidKey();
}
}
void HandleInvalidKey()
{
var l = items.Max(x => x.Length);
var s = new string(' ', l);
Screen.WriteAt(s, 0, items.Length, ConsoleColor.White, ConsoleColor.Black);
Screen.WriteAt("Invalid selection", 0, items.Length, ConsoleColor.Yellow, ConsoleColor.Blue);
}
static void Setup()
{
Console.Clear();
Console.CursorVisible = false;
}
}
}
public static class Screen
{
/// <summary>
/// Writes the text to the console at the specified (x, y) position, with optional foreground and background colors.
/// </summary>
/// <param name="text">The text to write to the console.</param>
/// <param name="x">The x-coordinate of the position to write the text.</param>
/// <param name="y">The y-coordinate of the position to write the text.</param>
/// <param name="foreground">The foreground color to use for the text. If not specified, the current foreground color will be used.</param>
/// <param name="background">The background color to use for the text. If not specified, the current background color will be used.</param>
public static void WriteAt(this string text, int x, int y, ConsoleColor? foreground = null, ConsoleColor? background = null)
{
if (foreground is null)
{
foreground = ConsoleColor.White;
}
Console.ForegroundColor = foreground.Value;
Console.BackgroundColor = background ?? ConsoleColor.Black;
Console.SetCursorPosition(left: x, top: y);
Console.WriteLine(text);
Console.ResetColor();
}
/// <summary>
/// Listens for a keystroke from the user and returns the first allowed key that is pressed.
/// </summary>
/// <param name="allowed">An array of allowed keys to listen for.</param>
/// <param name="key">The first allowed key that was pressed by the user.</param>
public static void Listen(this ConsoleKey[] allowed, out ConsoleKey key)
{
throw new NotImplementedException();
}
}
@JerryNixon
Copy link
Author

JerryNixon commented Feb 10, 2023

What would that if-then statement look like as a case statement?

    switch (key)
    {
        case ConsoleKey.UpArrow when current != items.First():
            {
                var index = Array.IndexOf(items, current);
                current = items[index - 1];
                break;
            }
        case ConsoleKey.DownArrow when current != items.Last():
            {
                var index = Array.IndexOf(items, current);
                current = items[index + 1];
                break;
            }
        case ConsoleKey.Enter:
            {
                var l = items.Max(x => x.Length);
                var s = new string(' ', l);

                Screen.WriteAt(s, 0, items.Length, ConsoleColor.White, ConsoleColor.Black);
                Screen.WriteAt(current, 0, items.Length, ConsoleColor.Yellow, ConsoleColor.Blue);
                     
                break;
            }
        default:
            HandleInvalidKey();
            break;
    }

@JerryNixon
Copy link
Author

Here's another interesting approach that accomplishes the same thing using switch expressions.

    current = key switch
    {
        ConsoleKey.UpArrow when current != items.First() => items[Array.IndexOf(items, current) - 1],
        ConsoleKey.DownArrow when current != items.Last() => items[Array.IndexOf(items, current) + 1],
        _ => current,
    };

    if (key == ConsoleKey.Enter)
    {
        var l = items.Max(x => x.Length);
        var s = new string(' ', l);

        Screen.WriteAt(s, 0, items.Length, ConsoleColor.White, ConsoleColor.Black);
        Screen.WriteAt(current, 0, items.Length, ConsoleColor.Yellow, ConsoleColor.Blue);
    }

@JerryNixon
Copy link
Author

To help you out, here's a first draft at Box.Draw().

    public static void Draw(this Rectangle rect, char fill = ' ')
    {
        // Character reference: ┌ ─ ┐ │ └ ─ ┘

        var top = $"{new string('─', rect.Width)}";
        Screen.WriteAt(top, rect.Left, rect.Top);

        // TODO: middle

        var bottom = $"{new string('─', rect.Width)}";
        Screen.WriteAt(top, rect.Left, rect.Top + rect.Height);
    }

@JerryNixon
Copy link
Author

If you want to rewrite the signature to not use Rectangle, you can do that.

    public static void Draw(int x, int y, int height, int width, char fill = ' ')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment