diff --git a/.drone.yml b/.drone.yml
index f538cac..01a268d 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -100,7 +100,7 @@ steps:
dockerfile: MCTG/Dockerfile
context: MCTG/
registry: hub.codefirst.iut.uca.fr
- repo: hub.codefirst.iut.uca.fr/alexandre.agostinho/cli-mctg
+ repo: hub.codefirst.iut.uca.fr/alexandre.agostinho/console-mctg
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
@@ -111,7 +111,7 @@ steps:
# image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
# environment:
# IMAGENAME: hub.codefirst.iut.uca.fr/alexandre.agostinho/sae-2.01:latest
- # CONTAINERNAME: cli-mctg
+ # CONTAINERNAME: console-mctg
# COMMAND: create
# OVERWRITE: true
# depends_on: [ docker-build-and-push ]
diff --git a/MCTG/ConsoleApp/Menu/ConnectionMenu.cs b/MCTG/ConsoleApp/Menu/ConnectionMenu.cs
new file mode 100644
index 0000000..d4c9949
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/ConnectionMenu.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ internal class ConnectionMenu : Entry
+ {
+ public ConnectionMenu()
+ : base("Connection",
+ new Entry.EntryStep("Username: ", typeof(string)),
+ new Entry.EntryStep("Password: ", typeof(string)))
+ { }
+
+ public override IMenu? Return()
+ {
+ string username = _selectList[0].Item.Input;
+ string password = _selectList[1].Item.Input;
+ return new PlainText($"User: {username} connected with password: {password}");
+ }
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/Entry.EntryStep.cs b/MCTG/ConsoleApp/Menu/Entry.EntryStep.cs
new file mode 100644
index 0000000..b58a707
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/Entry.EntryStep.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ internal abstract partial class Entry
+ {
+ ///
+ /// Define a step of the Entry menu, or in other word, an entry itself.
+ ///
+ public class EntryStep
+ {
+ #region Attributes & Properties
+ private readonly Type _entryType;
+
+ ///
+ /// The entry description. This text is generally placed before the input field.
+ ///
+ public string Description { get; private set; }
+
+ ///
+ /// Contain the input gave by the menu.
+ ///
+ public string Input { get; internal set; }
+ #endregion
+
+ #region Constructors
+ ///
+ /// Constructor of the entry step.
+ ///
+ /// The text generally placed before the input in the menu.
+ /// The type of the returned input.
+ public EntryStep(string description, Type type)
+ {
+ Description = description;
+ Input = "";
+ _entryType = type;
+ }
+ #endregion
+
+ #region Methods
+ ///
+ /// Get the inputed string converted on this entry type.
+ ///
+ /// The converted string on the entry type.
+ /// Throw when the entry type converter does not exist here.
+ public object GetEntry()
+ {
+ try
+ {
+ if (_entryType == typeof(string))
+ return Input;
+ if (_entryType == typeof(int))
+ return Int32.Parse(Input);
+ if (_entryType == typeof(DateTime))
+ return DateTime.Parse(Input);
+ }
+ catch (FormatException fe)
+ {
+ Console.Error.WriteLine(fe);
+ }
+
+ throw new NotImplementedException("Error: parse of this type is not implemented.");
+ }
+ #endregion
+ }
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/Entry.cs b/MCTG/ConsoleApp/Menu/Entry.cs
new file mode 100644
index 0000000..3a84fff
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/Entry.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// Define an Entry menu.
+ ///
It allows you to navigate through the entries and completes them with a console input.
+ ///
+ internal abstract partial class Entry : Menu
+ {
+ #region Attributes & Properties
+ private List _steps;
+ #endregion
+
+ #region Constructors
+ ///
+ /// Constructor of the entry menu, based on the Menu constructor.
+ ///
+ /// The title of this menu.
+ /// All the entries of this menu.
+ protected Entry(string title, params EntryStep[] entrySteps) : base(title)
+ {
+ _steps = entrySteps.ToList();
+ _allSelectors = ConvertEntryStepsInSelector();
+ _selectList = _allSelectors;
+ }
+ #endregion
+
+ #region Methods
+ private List> ConvertEntryStepsInSelector()
+ {
+ List> newSelectors = new List>();
+ foreach (EntryStep step in _steps)
+ {
+ newSelectors.Add(new Selector(step, step.Description));
+ }
+ return newSelectors;
+ }
+ #endregion
+
+ #region IMenu implementation
+ public override void WriteMenuMode(ConsoleKeyInfo cki)
+ {
+ if (!WriteMode && cki.Key == ConsoleKey.R)
+ {
+ EnableWriteMode();
+ return;
+ }
+
+ if (WriteMode)
+ {
+ if (cki.Key == ConsoleKey.Escape)
+ {
+ if (CurrentSelected is null)
+ throw new ArgumentNullException("CurrentSelected");
+
+ CurrentSelected.Input = InputStr.ToString();
+ DisableWriteMode();
+ InputStr.Clear();
+ return;
+ }
+
+ if (cki.Key == ConsoleKey.Backspace && InputStr.Length > 0)
+ {
+ InputStr.Remove(InputStr.Length - 1, 1);
+ return;
+ }
+
+ InputStr.Append(cki.KeyChar);
+ }
+ }
+
+ public override void Update()
+ {
+ if (_selectList.Count == 0)
+ {
+ CurrentSelected = default;
+ return;
+ }
+ CurrentSelected = _selectList[CurrentLine].Item;
+ }
+
+ public override void Display()
+ {
+ _screenDisplay.Clear();
+ Console.Clear();
+
+ _screenDisplay.AppendLine($"[ {Title} ]");
+ _screenDisplay.AppendLine("-------------------------------------------");
+
+ for (int i = 0; i < _selectList.Count; i++)
+ {
+ if (CurrentLine == i)
+ _screenDisplay.Append($"> ");
+ else
+ _screenDisplay.Append($" ");
+
+ _screenDisplay.Append($"{_selectList[i].Line} {_selectList[i].Item.Input}");
+
+ if (CurrentLine == i && WriteMode)
+ _screenDisplay.Append(InputStr);
+
+ _screenDisplay.AppendLine();
+ }
+
+ if (_selectList.Count == 0)
+ _screenDisplay.AppendLine("Empty...");
+
+ _screenDisplay.AppendLine(
+ "\n\nHint:\n^:previous, v:next, <:ret, -enter-:return, r:write, -escape-:exit search mode");
+ Console.WriteLine(_screenDisplay);
+ }
+ #endregion
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/IMenu.cs b/MCTG/ConsoleApp/Menu/IMenu.cs
new file mode 100644
index 0000000..120a387
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/IMenu.cs
@@ -0,0 +1,72 @@
+using Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// Define a console menu with element selection.
+ ///
+ internal interface IMenu
+ {
+ ///
+ /// True when enable, False otherwise.
+ ///
+ bool WriteMode { get; set; }
+
+ ///
+ /// A string input. Used for search string or entry input.
+ ///
+ StringBuilder InputStr { get; set; }
+
+ ///
+ /// Refresh the console with the updated display. This function dose not call Update().
+ ///
+ void Display();
+
+ ///
+ /// Update the parameters of the menu. Generally called before Display() to refresh the informations.
+ ///
+ void Update();
+
+ ///
+ /// Select the next element in the selection list.
+ ///
+ void SelectNext();
+
+ ///
+ /// Select the previous element in the selection list.
+ ///
+ void SelectPrevious();
+
+ ///
+ /// Enable the write mode.
+ ///
+ void EnableWriteMode();
+
+ ///
+ /// Disable the write mode.
+ ///
+ void DisableWriteMode();
+
+ ///
+ /// Toogle the write mode.
+ ///
+ void ToggleWriteMode();
+
+ ///
+ /// Define the comportement of the write mode. For instence: in the standard menu, it is used for the research of a line.
+ ///
+ /// The key to deal with.
+ void WriteMenuMode(ConsoleKeyInfo cki);
+
+ ///
+ /// Execute some actions and then return.
+ ///
+ /// 'null' when there is no menu after this selection. Otherwise the next menu.
+ IMenu? Return();
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs
deleted file mode 100644
index 572082c..0000000
--- a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ConsoleApp.Menu
-{
- internal interface IMenuDisplay
- {
- ///
- /// Update the menu display in the Console.
- ///
- void UpdateDisplay();
-
- ///
- /// Select the next line in the menu
- ///
- /// The current number of the new selected line
- int SelectNextLine();
-
- ///
- /// Select the previous line in the menu
- ///
- /// The current number of the new selected line
- int SelectPrevioustLine();
- }
-}
diff --git a/MCTG/ConsoleApp/Menu/MainMenu.cs b/MCTG/ConsoleApp/Menu/MainMenu.cs
new file mode 100644
index 0000000..8dcbb8b
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/MainMenu.cs
@@ -0,0 +1,24 @@
+using Model;
+using DataPersistence;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// Main menu of the console. Contain the first interaction menus.
+ ///
+ internal class MainMenu : Menu
+ {
+ public MainMenu(DataManager dataMgr)
+ : base("Main menu",
+ new Selector(
+ new SearcherRecipe(new RecipeCollection("search", dataMgr.Data[nameof(Recipe)].Cast().ToArray())), "Recipe search"),
+ new Selector(
+ new ConnectionMenu(), "Connection"))
+ { }
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/Menu.cs b/MCTG/ConsoleApp/Menu/Menu.cs
new file mode 100644
index 0000000..68962db
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/Menu.cs
@@ -0,0 +1,201 @@
+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
+{
+ ///
+ /// Define a selection menu.
+ ///
It allows you to navigate through the selections and search with a console input.
+ ///
+ /// The type (or the implementation) of the selection.
+ internal abstract class Menu : IMenu
+ where T : notnull
+ {
+ #region Attributes & Properties
+ protected StringBuilder _screenDisplay;
+
+ protected List> _allSelectors = new List>();
+ protected List> _selectList = new List>();
+
+ private int _currentLine;
+
+ ///
+ /// Title of the menu.
+ ///
+ public string Title { get; private set; }
+
+ ///
+ /// The current line of the selection list.
+ ///
+ 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;
+ }
+ }
+
+ ///
+ /// The currently selected object.
+ ///
+ public T? CurrentSelected { get; protected set; }
+ #endregion
+
+ #region Constructors
+ ///
+ /// Base constructor of the Menu class.
+ ///
This one is incomplete and need to be completed in the inherited class constructors.
+ ///
Basically, the '_allSelection' and '_selectList' attribute initialization are missing.
+ ///
+ /// The title of the Menu.
+ protected Menu(string title)
+ {
+ Title = title;
+ CurrentLine = 0;
+ WriteMode = false;
+ _screenDisplay = new StringBuilder();
+ InputStr = new StringBuilder();
+ }
+
+ ///
+ /// Constructor of the Menu class. This constructor allows you to directly pass the selections.
+ ///
+ /// The title of the menu.
+ /// The selections of the menu.
+ protected Menu(string title, params Selector[] 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> 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
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/PlainText.cs b/MCTG/ConsoleApp/Menu/PlainText.cs
new file mode 100644
index 0000000..d5deee1
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/PlainText.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// Define a Plain text menu.
+ ///
This menu is a bit special. It display some text, and then, the only action that can be performed is the back return. Usefull for testing.
+ ///
+ internal class PlainText : IMenu
+ {
+ #region Constructors
+ ///
+ /// Constructor of the Plain text menu.
+ ///
+ /// The text buffer to display.
+ public PlainText(string text)
+ {
+ InputStr = new StringBuilder(text);
+ WriteMode = false;
+ }
+ #endregion
+
+ #region IMenu implementation
+ public IMenu? Return() { return null; }
+ public void Display()
+ {
+ Console.Clear();
+ Console.WriteLine(InputStr);
+ }
+
+ public bool WriteMode { get; set; }
+ public StringBuilder InputStr { get; set; }
+
+ public void DisableWriteMode()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void EnableWriteMode()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void SelectNext()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void SelectPrevious()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void ToggleWriteMode()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void Update()
+ {
+ // Plain text does not need to do anything for this.
+ }
+ public void WriteMenuMode(ConsoleKeyInfo cki)
+ {
+ // Plain text does not need to do anything for this.
+ }
+ #endregion
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/SearcherRecipe.cs b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs
index 4e17512..b7dea49 100644
--- a/MCTG/ConsoleApp/Menu/SearcherRecipe.cs
+++ b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs
@@ -1,125 +1,46 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Threading.Tasks;
-
-using Model;
-
-namespace ConsoleApp.Menu
-{
- ///
- /// An utility to find a recipe.
- ///
- public class SearcherRecipe : SelectMenu
- {
- #region Attribute
- private RecipeCollection _recipeOnSearch;
- #endregion
-
- #region Properties
- ///
- /// A collection of recipe where the title contain the search string
- ///
- public RecipeCollection SearchResult { get; private set; }
-
- ///
- /// The search string
- ///
- public string ResearchStr { get; set; }
- #endregion
-
- ///
- /// Constructor of the SearcherRecipe utility.
- ///
- /// The collection of recipe where to search
- public SearcherRecipe(RecipeCollection recipeOnSearch)
- {
- _recipeOnSearch = recipeOnSearch;
- SearchResult = _recipeOnSearch;
- ResearchStr = "";
- }
-
- #region Methodes
- ///
- /// Launch a search by name request in the collection of Recipe with with a string.
- ///
- /// The string for search
- /// True if the result of the search gave at least 1 element. False otherwise.
- public bool ComputeSearch(string researchStr = "")
- {
- ResearchStr = researchStr;
- SearchResult = _recipeOnSearch.ResearchByName(ResearchStr.ToLower());
- _maxLines = SearchResult.Count - 1;
-
- return SearchResult.Count > 0;
- }
-
- public override void UpdateDisplay()
- {
- StringBuilder sb = new StringBuilder();
- sb.AppendLine("---------------------------------------------------------");
- sb.AppendLine($" Research: {ResearchStr}");
- sb.AppendLine("---------------------------------------------------------");
- for (int i = 0; i < SearchResult.Count; i++)
- {
- if (i == CurrentLine)
- {
- CurrentSelected = SearchResult[i];
- sb.Append($">");
- }
- sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} ");
- }
- Console.Clear();
- Console.WriteLine(sb);
- }
-
- ///
- /// Launch and pilot the search menu.
- ///
- /// The collection of recipe where to search
- /// The recipe selected
- public static Recipe? ResearchOn(RecipeCollection recipeOnSearch)
- {
- SearcherRecipe sr = new SearcherRecipe(recipeOnSearch);
- StringBuilder sb = new StringBuilder();
- sr.ComputeSearch();
- sr.UpdateDisplay();
-
- ConsoleKeyInfo cki;
-
- do
- {
- cki = Console.ReadKey(true);
-
- switch (cki.Key)
- {
- case ConsoleKey.UpArrow:
- sr.SelectPrevioustLine();
- break;
- case ConsoleKey.DownArrow:
- sr.SelectNextLine();
- break;
- case ConsoleKey.Backspace:
- if (sb.Length > 0)
- {
- sb.Remove(sb.Length - 1, 1);
- sr.ComputeSearch(sb.ToString());
- }
- break;
- default:
- sb.Append(cki.KeyChar);
- sr.ComputeSearch(sb.ToString());
- break;
- }
-
- sr.UpdateDisplay();
-
- } while (cki.Key != ConsoleKey.Enter);
-
- return sr.CurrentSelected;
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// An utility to find a recipe.
+ ///
+ internal class SearcherRecipe : Menu
+ {
+ private readonly RecipeCollection _recipeCollectionOnSearch;
+
+ public SearcherRecipe(RecipeCollection recipeCollection) : base("Search recipe")
+ {
+ _recipeCollectionOnSearch = recipeCollection;
+ _allSelectors = ConvertRecipeCollectionInSelectors();
+ _selectList = _allSelectors;
+ }
+
+ #region Methods
+ private List> ConvertRecipeCollectionInSelectors()
+ {
+ List> newSelectors = new List>();
+ foreach (Recipe recipe in _recipeCollectionOnSearch)
+ {
+ newSelectors.Add(new Selector(recipe, $"[{recipe.Id}]: {recipe.Title}"));
+ }
+ return newSelectors;
+ }
+
+ public override IMenu? Return()
+ {
+ if (CurrentSelected == null)
+ throw new ArgumentNullException("CurrentSelected");
+
+ return new PlainText(CurrentSelected.ToString());
+ }
+ #endregion
+ }
+}
diff --git a/MCTG/ConsoleApp/Menu/SelectMenu.cs b/MCTG/ConsoleApp/Menu/SelectMenu.cs
deleted file mode 100644
index 0e331c6..0000000
--- a/MCTG/ConsoleApp/Menu/SelectMenu.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using ConsoleApp;
-using Model;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-
-namespace ConsoleApp.Menu
-{
- ///
- /// An abstract class that define the components of a selection-type menu.
- ///
- /// The return type of the currently selected item
- public abstract class SelectMenu : IMenuDisplay
- {
- protected int _currentLine = 0;
- protected int _maxLines = 0;
-
- ///
- /// The currently selected item.
- ///
- public T? CurrentSelected { get; protected set; }
-
- ///
- /// The current line selected in the menu.
- ///
- public int CurrentLine
- {
- get => _currentLine;
- protected set
- {
- _currentLine = value;
- if (_currentLine > _maxLines)
- {
- _currentLine = _maxLines;
- }
- if (_currentLine < 0)
- {
- _currentLine = 0;
- }
- return;
- }
- }
-
- public int SelectNextLine() { return ++CurrentLine; }
- public int SelectPrevioustLine() { return --CurrentLine; }
-
- public abstract void UpdateDisplay();
- }
-}
diff --git a/MCTG/ConsoleApp/Menu/Selector.cs b/MCTG/ConsoleApp/Menu/Selector.cs
new file mode 100644
index 0000000..f8f71e0
--- /dev/null
+++ b/MCTG/ConsoleApp/Menu/Selector.cs
@@ -0,0 +1,76 @@
+using Model;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Reflection.Emit;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp.Menu
+{
+ ///
+ /// The selector of a menu.
+ ///
+ /// The type of the selector.
+ internal class Selector : IEquatable>
+ where T : notnull
+ {
+ #region Attributes & Properties
+ private string _line = "";
+
+ ///
+ /// The string that are displayed on the menu.
+ ///
+ public string Line {
+ get => _line;
+ private set
+ {
+ if (string.IsNullOrEmpty(value))
+ _line = "no data";
+ else
+ _line = value;
+ }
+ }
+
+ ///
+ /// The item contained in the selector.
+ ///
+ public T Item { get; private set; }
+ #endregion
+
+ #region Constructors
+ ///
+ /// The constructor of the selector.
+ ///
+ /// The item to place inside.
+ /// The string to display in the menu.
+ public Selector(T item, string line = "")
+ {
+ Line = line;
+ Item = item;
+ }
+ #endregion
+
+ #region IEquatable implementation
+ public virtual bool Equals(Selector? other)
+ {
+ if (other == null) return false;
+ if (other == this) return true;
+ return other.Line.Equals(this.Line);
+ }
+
+ public override bool Equals(object? obj)
+ {
+ var item = obj as Selector;
+ if (item == null) return false;
+ return Equals(obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return Line.GetHashCode();
+ }
+ #endregion
+ }
+}
diff --git a/MCTG/ConsoleApp/MenuManager.cs b/MCTG/ConsoleApp/MenuManager.cs
new file mode 100644
index 0000000..20cf567
--- /dev/null
+++ b/MCTG/ConsoleApp/MenuManager.cs
@@ -0,0 +1,90 @@
+using ConsoleApp.Menu;
+using Model;
+using DataPersistence;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp
+{
+ ///
+ /// Manage the menus of the console application.
+ ///
+ internal class MenuManager
+ {
+ #region Attributes & Properties
+ ///
+ /// The manager that contains usefull data taken from the model.
+ ///
+ public DataManager DataManager { get; private set; }
+
+ ///
+ /// Each menu called are push in this stack. Then, to return back, we pop this stack to retrive the previous menu.
+ ///
+ public Stack MenuCallStack { get; set; }
+ #endregion
+
+ #region Constructors
+ ///
+ /// Constructor of the MenuManager class. This constructor allows you to give the first menu of the call stack, wich is usefull for testing.
+ ///
+ /// The data manager needed by the menus inside.
+ /// The starting menu, the first that will be push on the call stack.
+ public MenuManager(DataManager dataManager, Menu.IMenu firstMenu)
+ {
+ DataManager = dataManager;
+
+ MenuCallStack = new Stack();
+ MenuCallStack.Push(firstMenu);
+ }
+
+ ///
+ /// Constructor of the MenuManager class.
+ ///
+ /// The data manager needed by the menus inside.
+ public MenuManager(DataManager dataManager) : this(dataManager, new MainMenu(dataManager))
+ { }
+ #endregion
+
+ #region Methods
+ ///
+ /// Main loop. Loop while the menu call stack is not empty.
+ ///
+ public void Loop()
+ {
+ ConsoleKeyInfo cki;
+ Menu.IMenu menuOnHead;
+ do
+ {
+ menuOnHead = MenuCallStack.Peek();
+ menuOnHead.Update();
+ menuOnHead.Display();
+
+ cki = Console.ReadKey(true);
+ switch (cki.Key)
+ {
+ case ConsoleKey.DownArrow:
+ menuOnHead.SelectNext();
+ break;
+ case ConsoleKey.UpArrow:
+ menuOnHead.SelectPrevious();
+ break;
+ case ConsoleKey.Enter:
+ Menu.IMenu? retMenu = menuOnHead.Return();
+ if (retMenu is null) MenuCallStack.Pop();
+ else MenuCallStack.Push(retMenu);
+ break;
+ case ConsoleKey.LeftArrow:
+ MenuCallStack.Pop();
+ break;
+ default:
+ menuOnHead.WriteMenuMode(cki);
+ break;
+ }
+ } while (MenuCallStack.Count > 0);
+ }
+ #endregion
+ }
+}
diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs
index 554006c..65c6564 100644
--- a/MCTG/ConsoleApp/Program.cs
+++ b/MCTG/ConsoleApp/Program.cs
@@ -11,12 +11,12 @@ Console.WriteLine("Hello, World!\n\n");
// TESTS:
-//DataManager dataMgr = new DataManager(new Stubs());
+DataManager dataMgr = new DataManager(new Stubs());
//DataManager dataMgr = new DataManager(new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data"));
-DataManager dataMgr = new DataManager(new DataContractJSON(jsonFolderPath: "../../../../DataPersistence/data"));
+//DataManager dataMgr = new DataManager(new DataContractJSON());
//dataMgr.Serializer = new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data");
-//dataMgr.Serializer = new DataContractJSON(jsonFolderPath: "../../../../DataPersistence/data");
+dataMgr.Serializer = new DataContractJSON();
// /!\ here is an absolute path I put for testing purpose. It will only work on my computer so don't forget to change it whene you test.
@@ -25,10 +25,11 @@ DataManager dataMgr = new DataManager(new DataContractJSON(jsonFolderPath: "../.
RecipeCollection rc = new RecipeCollection("All recipes", dataMgr.Data[nameof(Recipe)].Cast().ToArray());
-Recipe? ret = SearcherRecipe.ResearchOn(rc);
-Console.WriteLine(ret);
-
dataMgr.Save();
+MenuManager menuMgr = new MenuManager(dataMgr);
+
+menuMgr.Loop();
+
// press any key to quit
-Console.ReadKey();
+//Console.ReadKey();
diff --git a/MCTG/Model/Manager/Manager.cs b/MCTG/Model/Manager/Manager.cs
deleted file mode 100644
index 5c4a6a7..0000000
--- a/MCTG/Model/Manager/Manager.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Model
-{
- ///
- /// Manager of the model. Here is stoked all the recipes, the users, etc...
- ///
- public class Manager
- {
- ///
- /// A collection of all the recipe loaded in the app.
- ///
- public RecipeCollection AllRecipes { get; protected set; }
-
- ///
- /// The constructor of the manager.
- ///
- public Manager()
- {
- AllRecipes = new RecipeCollection(description: "All Recipes");
- }
-
- ///
- /// The constructor of the manager.
- ///
- /// A list of loaded recipes
- public Manager(RecipeCollection allRecipes)
- {
- AllRecipes = new RecipeCollection(
- description: "All Recipes",
- recipes: allRecipes.ToArray());
- }
- }
-}
diff --git a/MCTG/Model/Recipes/RecipeCollection.cs b/MCTG/Model/Recipes/RecipeCollection.cs
index d439c76..a1d8393 100644
--- a/MCTG/Model/Recipes/RecipeCollection.cs
+++ b/MCTG/Model/Recipes/RecipeCollection.cs
@@ -10,10 +10,9 @@ namespace Model
/// Define a collection of .
///
This class implement and .
///
- public class RecipeCollection : IList, IEquatable
+ public class RecipeCollection : List, IEquatable
{
#region Attributes
- private readonly List _recipes;
private string _description = "";
#endregion
@@ -33,12 +32,6 @@ namespace Model
_description = value;
}
}
-
- #region IList Prperties
- public int Count => _recipes.Count;
- public bool IsReadOnly => false;
- public Recipe this[int index] { get => _recipes[index]; set => _recipes[index] = value; }
- #endregion
#endregion
#region Constructors
@@ -48,8 +41,8 @@ namespace Model
/// A short description of what this list will contain
/// Recipes to add in this new collection
public RecipeCollection(string description, params Recipe[] recipes)
+ : base(recipes)
{
- _recipes = new List(recipes);
Description = description;
}
#endregion
@@ -63,7 +56,7 @@ namespace Model
///
public Recipe? GetRecipeById(int id)
{
- Recipe? recipe = _recipes.Find(r => r.Id == id);
+ Recipe? recipe = this.Find(r => r.Id == id);
if (recipe == null) throw new ArgumentException("No _recipes match the given id.");
return recipe;
}
@@ -77,66 +70,14 @@ namespace Model
{
return new RecipeCollection(
description: $"Results of the research: {str}",
- recipes: _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray());
- }
-
- #region IList Methods
- public int IndexOf(Recipe item)
- {
- return _recipes.IndexOf(item);
- }
-
- public void Insert(int index, Recipe item)
- {
- _recipes.Insert(index, item);
- }
-
- public void RemoveAt(int index)
- {
- _recipes.RemoveAt(index);
- }
-
- public void Add(Recipe item)
- {
- _recipes.Add(item);
- }
-
- public void Clear()
- {
- _recipes.Clear();
+ recipes: this.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray());
}
- public bool Contains(Recipe item)
- {
- return _recipes.Contains(item);
- }
-
- public void CopyTo(Recipe[] array, int arrayIndex)
- {
- _recipes.CopyTo(array, arrayIndex);
- }
-
- public bool Remove(Recipe item)
- {
- return _recipes.Remove(item);
- }
-
- public IEnumerator GetEnumerator()
- {
- return _recipes.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return _recipes.GetEnumerator();
- }
- #endregion
-
public virtual bool Equals(RecipeCollection? other)
{
if (other == null) return false;
if (other == this) return true;
- return _description.Equals(other.Description) && _recipes.Equals(other._recipes);
+ return this.Description.Equals(other.Description);
}
public override bool Equals(object? obj)
@@ -148,13 +89,13 @@ namespace Model
public override int GetHashCode()
{
- return _recipes.GetHashCode();
+ return Description.GetHashCode();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder($"[RecipeCollection] - {Description}:\n");
- foreach (Recipe r in _recipes)
+ foreach (Recipe r in this)
{
sb.AppendFormat("\t - {0}\n", r.ToString());
}
diff --git a/MCTG/Tests/Model_UnitTests/Model_UnitTests.csproj b/MCTG/Tests/Model_UnitTests/Model_UnitTests.csproj
index 318f712..2a658d9 100644
--- a/MCTG/Tests/Model_UnitTests/Model_UnitTests.csproj
+++ b/MCTG/Tests/Model_UnitTests/Model_UnitTests.csproj
@@ -21,5 +21,6 @@
+
\ No newline at end of file
diff --git a/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs
index 36008b1..3f09b70 100644
--- a/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs
+++ b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs
@@ -22,7 +22,10 @@ namespace Model_UnitTests
new Recipe(title: "Gateau aux cerises", id: 3)
});
- Assert.Equal(2, recipes.ResearchByName("chocolat").FirstOrDefault().Id);
+ Recipe? recipe = recipes.ResearchByName("chocolat").FirstOrDefault();
+
+ Assert.NotNull(recipe);
+ Assert.Equal(2, recipe.Id);
}
}
}
diff --git a/MCTG/Tests/Model_UnitTests/test_unit_user.cs b/MCTG/Tests/Model_UnitTests/test_unit_user.cs
index 943afa0..1756e20 100644
--- a/MCTG/Tests/Model_UnitTests/test_unit_user.cs
+++ b/MCTG/Tests/Model_UnitTests/test_unit_user.cs
@@ -12,8 +12,8 @@ namespace Model_UnitTests
[Fact]
public void TestConstructUser()
{
- User user = new User("Bob","Dylan", "bd@gmail.com");
- //Assert.
+ User? user = new User("Bob","Dylan", "bd@gmail.com");
+ Assert.NotNull(user);
}
}
}