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.
202 lines
6.3 KiB
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
|
|
}
|
|
}
|