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.
SAE-2.01/MCTG/ConsoleApp/Menu/Core/Menu.cs

202 lines
6.3 KiB

using System.Data;
using Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp.Menu.Core
{
/// <summary>
/// Define a selection menu.
/// <br/>It allows you to navigate through the selections and search with a console input.
/// </summary>
/// <typeparam name="T">The type (or the implementation) of the selection.</typeparam>
internal abstract class Menu<T> : IMenu
where T : notnull
{
#region Attributes & Properties
protected StringBuilder _screenDisplay;
protected List<Selector<T>> _allSelectors = new List<Selector<T>>();
protected List<Selector<T>> _selectList = new List<Selector<T>>();
private int _currentLine;
/// <summary>
/// Title of the menu.
/// </summary>
public string Title { get; private set; }
/// <summary>
/// The current line of the selection list.
/// </summary>
public int CurrentLine
{
get
{
if (_currentLine >= _selectList.Count) _currentLine = _selectList.Count - 1;
return _currentLine;
}
protected set
{
_currentLine = value;
if (_currentLine <= 0) _currentLine = 0;
else if (_currentLine >= _selectList.Count) _currentLine = _selectList.Count - 1;
}
}
/// <summary>
/// The currently selected object.
/// </summary>
public T? CurrentSelected { get; protected set; }
#endregion
#region Constructors
/// <summary>
/// Base constructor of the Menu class.
/// <br/>This one is incomplete and need to be completed in the inherited class constructors.
/// <br/>Basically, the '_allSelection' and '_selectList' attribute initialization are missing.
/// </summary>
/// <param name="title">The title of the Menu.</param>
protected Menu(string title)
{
Title = title;
CurrentLine = 0;
WriteMode = false;
_screenDisplay = new StringBuilder();
InputStr = new StringBuilder();
}
/// <summary>
/// Constructor of the Menu class. This constructor allows you to directly pass the selections.
/// </summary>
/// <param name="title">The title of the menu.</param>
/// <param name="selections">The selections of the menu.</param>
protected Menu(string title, params Selector<T>[] selections) : this(title)
{
if (selections == null || selections.Length == 0)
{
Console.WriteLine("Empty menu...");
return;
}
_allSelectors = selections.ToList();
_selectList = _allSelectors;
CurrentSelected = _allSelectors[0].Item;
}
#endregion
#region IMenu implementation
public StringBuilder InputStr { get; set; }
public bool WriteMode { get; set; }
public virtual IMenu? Return()
{
if (CurrentSelected is null)
throw new ArgumentNullException("CurrentSelected");
return (IMenu)CurrentSelected;
}
protected virtual List<Selector<T>> SearchInSelection()
{
if (_allSelectors is null)
throw new ArgumentNullException("_allSelectors");
return _allSelectors.FindAll(x =>
x.Line.ToLower().Contains(InputStr.ToString().ToLower()));
}
public virtual void WriteMenuMode(ConsoleKeyInfo cki)
{
if (!WriteMode && cki.Key == ConsoleKey.R)
{
EnableWriteMode();
return;
}
if (WriteMode)
{
if (cki.Key == ConsoleKey.Escape)
{
DisableWriteMode();
InputStr.Clear();
return;
}
if (cki.Key == ConsoleKey.Backspace && InputStr.Length > 0)
{
InputStr.Remove(InputStr.Length - 1, 1);
return;
}
InputStr.Append(cki.KeyChar);
}
}
public virtual void Update()
{
_selectList = SearchInSelection();
if (_selectList.Count == 0)
{
CurrentSelected = default;
return;
}
CurrentSelected = _selectList[CurrentLine].Item;
}
public virtual void Display()
{
_screenDisplay.Clear();
Console.Clear();
_screenDisplay.AppendLine($"[ {Title} ]");
_screenDisplay.AppendLine("-------------------------------------------");
if (WriteMode)
{
_screenDisplay.Append("Search: ");
_screenDisplay.AppendLine(InputStr.ToString());
}
for (int i = 0; i < _selectList.Count; i++)
{
if (CurrentLine == i)
_screenDisplay.Append($"> ");
else
_screenDisplay.Append($" ");
_screenDisplay.AppendLine($"{_selectList[i].Line}");
}
if (_selectList.Count == 0)
_screenDisplay.AppendLine("Empty...");
_screenDisplay.AppendLine(
"\n\nHint:\n^:previous, v:next, <:ret, -enter-:select, r:search, -escape-:exit search mode");
Console.WriteLine(_screenDisplay);
}
public void SelectNext() => ++CurrentLine;
public void SelectPrevious() => --CurrentLine;
public void EnableWriteMode() => WriteMode = true;
public void DisableWriteMode() => WriteMode = false;
public void ToggleWriteMode()
{
if (WriteMode)
DisableWriteMode();
else
EnableWriteMode();
}
#endregion
}
}