From d05f215a622572a65d1171d322d44ac23695722f Mon Sep 17 00:00:00 2001
From: JFronny <33260128+JFronny@users.noreply.github.com>
Date: Sat, 23 May 2020 15:32:24 +0200
Subject: [PATCH] Document all non-mathematical functions
---
Commandline/TUI/Button.cs | 21 ++--
Commandline/TUI/CheckBox.cs | 33 +++--
Commandline/TUI/Control.cs | 49 ++++++--
Commandline/TUI/DiffDraw.cs | 78 ++++++++++--
Commandline/TUI/InputEventArgs.cs | 11 +-
Commandline/TUI/Label.cs | 21 ++--
Commandline/TUI/Panel.cs | 25 ++--
Commandline/TUI/Pixel.cs | 67 ++++++++--
Commandline/TUI/Screen.cs | 72 +++++++++--
Commandline/TUI/Slider.cs | 36 ++++--
Commandline/TUI/TextBox.cs | 51 +++++---
Commandline/TableParser.cs | 31 ++++-
Misc/ArrayFormatter.cs | 71 +++++++++--
Misc/Crypto.cs | 18 ++-
Misc/GenericExtensions.cs | 203 +++++++++++++++++++++++-------
Misc/HID.cs | 28 ++++-
Misc/IO.cs | 18 ++-
Misc/SpecialChars.cs | 8 +-
18 files changed, 681 insertions(+), 160 deletions(-)
diff --git a/Commandline/TUI/Button.cs b/Commandline/TUI/Button.cs
index d943b14..6285536 100644
--- a/Commandline/TUI/Button.cs
+++ b/Commandline/TUI/Button.cs
@@ -3,19 +3,30 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// A basic button type
+ ///
public class Button : Control
{
+ ///
+ /// The text inside this button
+ ///
public string Content;
+ ///
+ /// Creates a new button
+ ///
+ /// The text inside this button
public Button(string content)
{
Content = content;
- char[,] tmp = Content.ToNDArray2D();
+ char[,] tmp = Content.ToNdArray2D();
Size = new Size(tmp.GetLength(0), tmp.GetLength(1));
}
+ ///
public override Pixel[,] Render()
{
- char[,] inp = Content.ToNDArray2D();
+ char[,] inp = Content.ToNdArray2D();
inp = inp.Resize(Size.Width, Size.Height);
Pixel[,] output = new Pixel[Size.Width, Size.Height];
for (int x = 0; x < Size.Width; x++)
@@ -24,11 +35,7 @@ namespace CC_Functions.Commandline.TUI
return output;
}
- protected override void Resize(int width, int height)
- {
- //ignored for [Render]s sake, do not use
- }
-
+ ///
public override bool Selectable { get; } = true;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/CheckBox.cs b/Commandline/TUI/CheckBox.cs
index 3472213..cddda3a 100644
--- a/Commandline/TUI/CheckBox.cs
+++ b/Commandline/TUI/CheckBox.cs
@@ -4,10 +4,23 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Provides a control for users to select a boolean
+ ///
public class CheckBox : Control
{
+ ///
+ /// The text inside this checkbox
+ ///
public string Content;
+ ///
+ /// Whether the box is checked
+ ///
public bool Checked = false;
+ ///
+ /// Creates a new checkbox
+ ///
+ /// The text inside this CheckBox
public CheckBox(string content)
{
Content = content;
@@ -30,14 +43,15 @@ namespace CC_Functions.Commandline.TUI
};
}
+ ///
public override Pixel[,] Render()
{
- char[,] inp1 = Content.ToNDArray2D();
+ char[,] inp1 = Content.ToNdArray2D();
char[,] inp = new char[inp1.GetLength(0), inp1.GetLength(1) + 4];
inp.Populate(' ');
inp1.CopyTo(inp, new Point(4, 0));
inp[0, 0] = '[';
- inp[0, 1] = Checked ? 'X' : SpecialChars.empty;
+ inp[0, 1] = Checked ? 'X' : SpecialChars.Empty;
inp[0, 2] = ']';
int w = inp.GetLength(0);
int h = inp.GetLength(1);
@@ -49,13 +63,18 @@ namespace CC_Functions.Commandline.TUI
return output;
}
- protected override void Resize(int width, int height)
- {
- //ignored for [Render]s sake, do not use
- }
-
+ ///
public override bool Selectable { get; } = true;
+
+ ///
+ /// Called when the state of this checkbox is changed
+ ///
+ /// The current screen instance
+ /// Args
public delegate void OnCheckedChanged(Screen screen, EventArgs e);
+ ///
+ /// Called when the state of this checkbox is changed
+ ///
public event OnClick CheckedChanged;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/Control.cs b/Commandline/TUI/Control.cs
index 7ff955c..88c7939 100644
--- a/Commandline/TUI/Control.cs
+++ b/Commandline/TUI/Control.cs
@@ -3,32 +3,62 @@ using System.Drawing;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Abstract class inherited by all controls
+ ///
public abstract class Control
{
+ ///
+ /// Called when the controls Size property is changed
+ ///
+ /// The calling control
+ /// Args
+ public delegate void OnResize(Control caller, EventArgs e);
+ ///
+ /// Called when the controls Size property is changed
+ ///
+ public event OnResize Resize;
private Point _point;
private Size _size;
+ ///
+ /// Renders the control
+ ///
+ /// The rendered pixels
public abstract Pixel[,] Render();
- protected abstract void Resize(int width, int height);
- private void Resize(Size size) => Resize(size.Width, size.Height);
-
+ ///
+ /// The size of the control
+ ///
public Size Size
{
set
{
- _size = value;
- Resize(value);
+ if (_size != value)
+ {
+ _size = value;
+ Resize?.Invoke(this, new EventArgs());
+ }
}
get => _size;
}
-
+ ///
+ /// The position of this control
+ ///
public Point Point
{
get => _point;
set => _point = value;
}
-
+ ///
+ /// The foreground color for this control
+ ///
public ConsoleColor ForeColor { get; set; } = Console.ForegroundColor;
+ ///
+ /// The background color for this control
+ ///
public ConsoleColor BackColor { get; set; } = Console.BackgroundColor;
+ ///
+ /// Whether the control can be selected
+ ///
public abstract bool Selectable { get; }
///
@@ -72,10 +102,13 @@ namespace CC_Functions.Commandline.TUI
{
Input?.Invoke(screen, new InputEventArgs(info));
}
-
///
/// Whether the control should be rendered
///
public bool Visible = true;
+ ///
+ /// Whether the control can be interacted with
+ ///
+ public bool Enabled = true;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/DiffDraw.cs b/Commandline/TUI/DiffDraw.cs
index 65033f8..a500de3 100644
--- a/Commandline/TUI/DiffDraw.cs
+++ b/Commandline/TUI/DiffDraw.cs
@@ -11,9 +11,18 @@ namespace CC_Functions.Commandline.TUI
{
private static Pixel[,] Screen { get; set; } = new Pixel[0, 0];
private static Pixel[,] _last = new Pixel[0,0];
+ ///
+ /// The regions width
+ ///
public static int Width => Screen.GetLength(1);
+ ///
+ /// The regions height
+ ///
public static int Height => Screen.GetLength(0);
-
+ ///
+ /// Draws to the console
+ ///
+ /// Whether to use color
public static void Draw(bool color)
{
Console.CursorTop = 0;
@@ -43,7 +52,10 @@ namespace CC_Functions.Commandline.TUI
Console.BackgroundColor = bcol;
_last = Screen;
}
-
+ ///
+ /// Redraws the entire screen (should be done from time to time to prevent corruption)
+ ///
+ /// Whether to use color
public static void FullDraw(bool color)
{
Console.CursorTop = 0;
@@ -73,26 +85,76 @@ namespace CC_Functions.Commandline.TUI
Console.BackgroundColor = bcol;
_last = Screen;
}
-
+ ///
+ /// Gets the char at a location
+ ///
+ /// The location
+ /// The char
public static char Get(Point p) => Get(p.X, p.Y);
+ ///
+ /// Gets the char at a location
+ ///
+ /// The locations X coordinate
+ /// The locations Y coordinate
+ /// The char
public static char Get(int x, int y) => Screen[y, x].Content;
+ ///
+ /// Gets the foreground color at a location
+ ///
+ /// The location
+ /// The color
public static ConsoleColor GetForeColor(Point p) => GetForeColor(p.X, p.Y);
+ ///
+ /// Gets the foreground color at a location
+ ///
+ /// The locations X coordinate
+ /// The locations Y coordinate
+ /// The color
public static ConsoleColor GetForeColor(int x, int y) => Screen[y, x].ForeColor;
+ ///
+ /// Gets the background color at a location
+ ///
+ /// The location
+ /// The color
public static ConsoleColor GetBackColor(Point p) => GetBackColor(p.X, p.Y);
+ ///
+ /// Gets the background color at a location
+ ///
+ /// The locations X coordinate
+ /// The locations Y coordinate
+ /// The color
public static ConsoleColor GetBackColor(int x, int y) => Screen[y, x].BackColor;
-
+ ///
+ /// Sets a pixel at a point
+ ///
+ /// The point to place at
+ /// The pixel to place
public static void Set(Point p, Pixel c) => Set(p.X, p.Y, c);
-
+ ///
+ /// Sets a pixel at a location
+ ///
+ /// The locations X coordinate
+ /// The locations Y coordinate
+ /// The pixel to place
public static void Set(int x, int y, Pixel c) => Screen[y, x] = c;
-
+ ///
+ /// Clears the screen
+ ///
public static void Clear() => Clear(Width, Height);
-
+ ///
+ /// Resizes and clears the screen
+ ///
+ /// The new width
+ /// The new height
public static void Clear(int width, int height)
{
Screen = new Pixel[height, width];
_last = _last.Resize(height, width);
}
-
+ ///
+ /// Replaces the screen state
+ ///
+ /// The new state
public static void Clear(Pixel[,] content)
{
Screen = content;
diff --git a/Commandline/TUI/InputEventArgs.cs b/Commandline/TUI/InputEventArgs.cs
index f528784..431d31f 100644
--- a/Commandline/TUI/InputEventArgs.cs
+++ b/Commandline/TUI/InputEventArgs.cs
@@ -2,11 +2,20 @@ using System;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Arguments containing input data
+ ///
public class InputEventArgs : EventArgs
{
private readonly ConsoleKeyInfo _info;
+ ///
+ /// The inputs data
+ ///
public ConsoleKeyInfo Info => _info;
-
+ ///
+ /// Generates new arguments
+ ///
+ /// The input data
public InputEventArgs(ConsoleKeyInfo info) => _info = info;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/Label.cs b/Commandline/TUI/Label.cs
index 27f3a67..c0e1069 100644
--- a/Commandline/TUI/Label.cs
+++ b/Commandline/TUI/Label.cs
@@ -3,14 +3,24 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// A basic text control
+ ///
public class Label : Control
{
+ ///
+ /// The text inside this label
+ ///
public string Content;
+ ///
+ /// Creates a new label
+ ///
+ /// The text inside this label
public Label(string content) => Content = content;
-
+ ///
public override Pixel[,] Render()
{
- char[,] inp = Content.ToNDArray2D();
+ char[,] inp = Content.ToNdArray2D();
int w = inp.GetLength(0);
int h = inp.GetLength(1);
Pixel[,] output = new Pixel[w, h];
@@ -20,12 +30,7 @@ namespace CC_Functions.Commandline.TUI
Size = new Size(w, h);
return output;
}
-
- protected override void Resize(int width, int height)
- {
- //ignored for [Render]s sake, do not use
- }
-
+ ///
public override bool Selectable { get; } = false;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/Panel.cs b/Commandline/TUI/Panel.cs
index a47f244..6ed8218 100644
--- a/Commandline/TUI/Panel.cs
+++ b/Commandline/TUI/Panel.cs
@@ -4,14 +4,24 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// A panel containing other components. MUST be inherited for all other controls that contain others
+ ///
public class Panel : Control
{
+ ///
+ /// The controls inside this panel
+ ///
public List Controls = new List();
-
+
+ ///
+ /// Renders the control and all contained controls
+ ///
+ /// The rendered pixels
public override Pixel[,] Render()
{
Pixel[,] tmp = new Pixel[Size.Height, Size.Width];
- tmp.Populate(new Pixel(BackColor, ForeColor, SpecialChars.empty));
+ tmp.Populate(new Pixel(BackColor, ForeColor, SpecialChars.Empty));
foreach (Control control in Controls)
{
if (control.Visible)
@@ -22,13 +32,12 @@ namespace CC_Functions.Commandline.TUI
}
return tmp;
}
-
- protected override void Resize(int width, int height)
- {
- }
-
+ ///
public override bool Selectable { get; } = false;
-
+ ///
+ /// Recursively enumerates all controls
+ ///
+ /// A list of all controls
public Control[] EnumerateRecursive()
{
List output = Controls.ToList();
diff --git a/Commandline/TUI/Pixel.cs b/Commandline/TUI/Pixel.cs
index c76a9ba..2ebaedf 100644
--- a/Commandline/TUI/Pixel.cs
+++ b/Commandline/TUI/Pixel.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Represents a pixel
+ ///
public class Pixel
{
private sealed class ColorContentEqualityComparer : IEqualityComparer
@@ -18,11 +21,21 @@ namespace CC_Functions.Commandline.TUI
public int GetHashCode(Pixel obj) => obj.GetHashCode();
}
-
+ ///
+ /// Use this in functions that require equality comparers
+ ///
public static IEqualityComparer ColorContentComparer { get; } = new ColorContentEqualityComparer();
-
+ ///
+ /// Whether this is equal to another pixel
+ ///
+ /// The other pixel to compare
+ /// Whether they are equal
protected bool Equals(Pixel other) => ColorContentComparer.Equals(this, other);
-
+ ///
+ /// Whether this is equal to another object
+ ///
+ /// The other object to compare
+ ///
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
@@ -31,30 +44,66 @@ namespace CC_Functions.Commandline.TUI
return Equals((Pixel) obj);
}
+ ///
+ /// Generates an integer for comparing this object
+ ///
+ /// The generated hash
public override int GetHashCode() => HashCode.Combine((int) BackColor, (int) ForeColor, Content);
-
+ ///
+ /// This pixels background color
+ ///
public ConsoleColor BackColor;
+ ///
+ /// This pixels foregound color
+ ///
public ConsoleColor ForeColor;
+ ///
+ /// This pixels content character
+ ///
public char Content;
-
+ ///
+ /// Generates a new pixel
+ ///
+ /// The background color
+ /// The foreground color
+ /// The new content
public Pixel(ConsoleColor backColor, ConsoleColor foreColor, char content)
{
BackColor = backColor;
ForeColor = foreColor;
Content = content;
}
-
+ ///
+ /// Generates a new pixel
+ ///
+ /// The content for this pixel
public Pixel(char content) : this(Console.BackgroundColor, Console.ForegroundColor, content)
{
}
-
+ ///
+ /// Generates a new pixel
+ ///
public Pixel() : this(' ')
{
}
-
+ ///
+ /// Whether two pixels are equal
+ ///
+ /// First pixel to compare
+ /// Second pixel to compare
+ /// Whether they are equal
public static bool operator ==(Pixel a, Pixel b) => a.Equals(b);
+ ///
+ /// Whether to pixels are not equal
+ ///
+ /// First pixel to compare
+ /// Second pixel to compare
+ /// Whether they are not equal
public static bool operator !=(Pixel a, Pixel b) => !a.Equals(b);
-
+ ///
+ /// Returns the content of this pixel
+ ///
+ /// The content of this pixel
public override string ToString() => Content.ToString();
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/Screen.cs b/Commandline/TUI/Screen.cs
index ea65a3c..642cae0 100644
--- a/Commandline/TUI/Screen.cs
+++ b/Commandline/TUI/Screen.cs
@@ -4,10 +4,21 @@ using System.Linq;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Provides a front-end renderer for panels, draws using DiffDraw
+ ///
public class Screen : Panel
{
+ ///
+ /// Whether to output in color. Recommended for most terminals, might cause slowdowns in others
+ ///
public readonly bool Color;
+ ///
+ /// The current index of the tab-selected control in an array of selectable controls
+ ///
public int TabPoint = 0;
+ private int _wndWidth = Console.WindowWidth;
+ private int _wndHeight = Console.WindowHeight;
///
/// Creates a screen object. Multiple can be instantiated but drawing one overrides others. Use panels for that
///
@@ -26,7 +37,7 @@ namespace CC_Functions.Commandline.TUI
///
///
///
- public void Resize(int width, int height)
+ public new void Resize(int width, int height)
{
Size = new Size(width, height);
DiffDraw.Clear(width, height);
@@ -36,7 +47,7 @@ namespace CC_Functions.Commandline.TUI
/// Renders the screen, draws it to the console and outputs the new state
///
/// The new state of the screen
- public Pixel[,] Render()
+ public new Pixel[,] Render()
{
Pixel[,] tmp = base.Render();
DiffDraw.Clear(tmp);
@@ -44,8 +55,13 @@ namespace CC_Functions.Commandline.TUI
return tmp;
}
- public void ReadInput()
+ ///
+ /// Reads input from Console and calls according functions
+ ///
+ /// Set to false to prevent redrawing if the screen should be updated. You can Render manually in that case
+ public void ReadInput(bool canRedraw = true)
{
+ bool render = false;
while (Console.KeyAvailable)
{
Control[] controls = EnumerateRecursive();
@@ -57,33 +73,49 @@ namespace CC_Functions.Commandline.TUI
Tab(selectable, (input.Modifiers & ConsoleModifiers.Shift) != 0);
break;
case ConsoleKey.Enter:
- if (selectable.Any() && selectable.Length >= TabPoint)
+ if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
{
selectable[TabPoint].InvokeClick(this);
- Render();
+ render = true;
}
break;
case ConsoleKey.Escape:
Close?.Invoke(this, new EventArgs());
break;
default:
- if (selectable.Any() && selectable.Length >= TabPoint)
+ if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
{
selectable[TabPoint].InvokeInput(this, input);
- Render();
+ render = true;
}
break;
}
}
+ if (_wndWidth != Console.WindowWidth || _wndHeight != Console.WindowHeight)
+ {
+ render = true;
+ _wndWidth = Console.WindowWidth;
+ _wndHeight = Console.WindowHeight;
+ WindowResize?.Invoke(this, new EventArgs());
+ }
+ if (canRedraw && render)
+ Render();
}
-
+ ///
+ /// Increases the TabPoint or reverts back to 0 if at the end of selectables
+ ///
+ /// Set to false to decrease instead
public void Tab(bool positive = true)
{
Control[] controls = EnumerateRecursive();
Control[] selectable = controls.Where(s => s.Selectable).ToArray();
Tab(selectable, positive);
}
-
+ ///
+ /// Increases the TabPoint or reverts back to 0 if at the end of selectables
+ ///
+ /// The array of selectable controls to select from. You should most likely not use this
+ /// Set to false to decrease instead
public void Tab(Control[] selectable, bool positive)
{
if (selectable.Any())
@@ -103,9 +135,25 @@ namespace CC_Functions.Commandline.TUI
Render();
}
}
-
+ ///
+ /// Called if Escape is pressed, use this for flow control
+ ///
+ /// This instance of the screen class
+ /// Args
public delegate void OnClose(Screen screen, EventArgs e);
-
- public event OnClick Close;
+ ///
+ /// Called if Escape is pressed, use this for flow control
+ ///
+ public event OnClose Close;
+ ///
+ /// Called by ReadInput if a change in the window size is detected. Use this for positioning
+ ///
+ /// This instance of the screen class
+ /// Args
+ public delegate void OnWindowResize(Screen screen, EventArgs e);
+ ///
+ /// Called by ReadInput if a change in the window size is detected. Use this for positioning
+ ///
+ public event OnWindowResize WindowResize;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/Slider.cs b/Commandline/TUI/Slider.cs
index f324246..fbdabfe 100644
--- a/Commandline/TUI/Slider.cs
+++ b/Commandline/TUI/Slider.cs
@@ -3,8 +3,14 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// Provides a control to select a number from a range of numbers
+ ///
public class Slider : Control
{
+ ///
+ /// Generates a new slider
+ ///
public Slider()
{
Input += (screen, args) =>
@@ -26,7 +32,10 @@ namespace CC_Functions.Commandline.TUI
}
};
}
-
+ ///
+ /// The maximum value for this slider
+ ///
+ /// Thrown if too low/high
public int MaxValue
{
get => _maxValue;
@@ -38,7 +47,10 @@ namespace CC_Functions.Commandline.TUI
throw new ArgumentOutOfRangeException("MaxValue must be larger than MinValue and equal to or larger than Value");
}
}
-
+ ///
+ /// The minimal value for this slider
+ ///
+ /// Thrown if too low/high
public int MinValue
{
get => _minValue;
@@ -50,7 +62,10 @@ namespace CC_Functions.Commandline.TUI
throw new ArgumentOutOfRangeException("MaxValue must be larger than MinValue and equal to or smaller than Value");
}
}
-
+ ///
+ /// The current value of this slider
+ ///
+ /// Thrown if too low/high
public int Value
{
get => _value;
@@ -62,19 +77,21 @@ namespace CC_Functions.Commandline.TUI
throw new ArgumentOutOfRangeException("Value must be between MinValue and MaxValue");
}
}
-
+ ///
+ /// The size of steps in this slider
+ ///
public int StepSize = 1;
private int _value = 5;
private int _maxValue = 10;
private int _minValue = 0;
-
+ ///
public override Pixel[,] Render()
{
int delta = MaxValue - MinValue;
int litValLen = Math.Max(MaxValue.ToString().Length, MinValue.ToString().Length);
int prevpts = Math.Max((Value - MinValue) * Size.Width / delta - litValLen - 2, 0);
int postpts = Math.Max(Size.Width - prevpts - litValLen - 2, 0);
- char[,] rend = $"{new string('=', prevpts)}[{Value.ToString($"D{litValLen}")}]{new string('=', postpts)}".ToNDArray2D();
+ char[,] rend = $"{new string('=', prevpts)}[{Value.ToString($"D{litValLen}")}]{new string('=', postpts)}".ToNdArray2D();
int f1 = rend.GetLength(0);
int f2 = rend.GetLength(1);
Pixel[,] output = new Pixel[f1, f2];
@@ -83,12 +100,7 @@ namespace CC_Functions.Commandline.TUI
for (int j = 0; j < f2; j++) output[i, j] = new Pixel(Selected ? ForeColor : BackColor, Selected ? BackColor : ForeColor, rend[i, j]);
return output;
}
-
- protected override void Resize(int width, int height)
- {
-
- }
-
+ ///
public override bool Selectable { get; } = true;
}
}
\ No newline at end of file
diff --git a/Commandline/TUI/TextBox.cs b/Commandline/TUI/TextBox.cs
index dc2b77c..0f62bc3 100644
--- a/Commandline/TUI/TextBox.cs
+++ b/Commandline/TUI/TextBox.cs
@@ -6,16 +6,28 @@ using CC_Functions.Misc;
namespace CC_Functions.Commandline.TUI
{
+ ///
+ /// A basic non-scrolling text-editor control
+ ///
public class TextBox : Control
{
+ ///
+ /// The text inside this textbox
+ ///
public string Content;
private string[] Lines
{
get => Content.Split('\n');
set => Content = string.Join('\n', value);
}
-
+ ///
+ /// The "Cursors" position in this text box
+ ///
public Point Cursor = new Point(0, 0);
+ ///
+ /// Creates a new text box
+ ///
+ /// The text inside this text box
public TextBox(string content)
{
Content = content;
@@ -25,7 +37,11 @@ namespace CC_Functions.Commandline.TUI
};
Click += (screen, args) => ProcessInput(ConsoleKey.Enter, new ConsoleKeyInfo());
}
-
+ ///
+ /// Function to process input
+ ///
+ /// The pressed key
+ /// Input metadata
private void ProcessInput(ConsoleKey key, ConsoleKeyInfo info)
{
string[] lines = Lines;
@@ -113,25 +129,32 @@ namespace CC_Functions.Commandline.TUI
Lines = lines;
break;
case ConsoleKey.Enter:
- tmp = lines.ToList();
- lines[Cursor.Y] = lines[Cursor.Y].Insert(Cursor.X, "\n");
- Cursor.Y++;
- Cursor.X = 0;
- Lines = lines;
+ if (lines.Length < Size.Height)
+ {
+ tmp = lines.ToList();
+ lines[Cursor.Y] = lines[Cursor.Y].Insert(Cursor.X, "\n");
+ Cursor.Y++;
+ Cursor.X = 0;
+ Lines = lines;
+ }
break;
default:
- lines[Cursor.Y] = lines[Cursor.Y].Insert(Cursor.X, info.KeyChar.ToString());
- Lines = lines;
+ if (lines[Cursor.Y].Length < Size.Width)
+ {
+ lines[Cursor.Y] = lines[Cursor.Y].Insert(Cursor.X, info.KeyChar.ToString());
+ Lines = lines;
+ }
break;
}
}
+ ///
public override Pixel[,] Render()
{
- char[,] inp1 = Content.ToNDArray2D();
+ char[,] inp1 = Content.ToNdArray2D();
inp1 = inp1.Resize(Size.Height, Size.Width - 2);
char[,] inp = new char[Size.Width, Size.Height];
- inp.Populate(SpecialChars.empty);
+ inp.Populate(SpecialChars.Empty);
for (int i = 0; i < Size.Height; i++)
{
inp[0, i] = '[';
@@ -148,11 +171,7 @@ namespace CC_Functions.Commandline.TUI
return output;
}
- protected override void Resize(int width, int height)
- {
- //ignored for [Render]s sake, do not use
- }
-
+ ///
public override bool Selectable { get; } = true;
}
}
\ No newline at end of file
diff --git a/Commandline/TableParser.cs b/Commandline/TableParser.cs
index 7fd2e93..09359c2 100644
--- a/Commandline/TableParser.cs
+++ b/Commandline/TableParser.cs
@@ -13,9 +13,24 @@ namespace CC_Functions.Commandline
///
public static class TableParser
{
+ ///
+ /// Parses the enumerable to a table using with the specified headers and transformed to strings with the specified selector
+ ///
+ /// The values to display
+ /// The headers for columns
+ /// Functions to get data for the cells
+ /// The type of the elements in the enumerable
+ /// The generated table
public static string ToStringTable(this IEnumerable values, string[] columnHeaders,
params Func[] valueSelectors) => ToStringTable(values.ToArray(), columnHeaders, valueSelectors);
-
+ ///
+ /// Parses the array to a table using with the specified headers and transformed to strings with the specified selector
+ ///
+ /// The values to display
+ /// The headers for columns
+ /// Functions to get data for the cells
+ /// The type of the elements in the array
+ /// The generated table
public static string ToStringTable(this T[] values, string[] columnHeaders,
params Func[] valueSelectors)
{
@@ -38,7 +53,11 @@ namespace CC_Functions.Commandline
return ToStringTable(arrValues);
}
-
+ ///
+ /// Parses the array to a table
+ ///
+ /// The cells of the table
+ /// The generated table
public static string ToStringTable(this string[,] arrValues)
{
int[] maxColumnsWidth = GetMaxColumnsWidth(arrValues);
@@ -85,7 +104,13 @@ namespace CC_Functions.Commandline
return maxColumnsWidth;
}
-
+ ///
+ /// Parses the enumerable to a table, transformed to strings with the specified selector
+ ///
+ /// The values to display
+ /// Functions to get data for the cells
+ /// The type of the elements in the enumerable
+ /// The generated table
public static string ToStringTable(this IEnumerable values,
params Expression>[] valueSelectors)
{
diff --git a/Misc/ArrayFormatter.cs b/Misc/ArrayFormatter.cs
index 28c3aef..b8127cb 100644
--- a/Misc/ArrayFormatter.cs
+++ b/Misc/ArrayFormatter.cs
@@ -4,11 +4,38 @@ using System.Linq;
namespace CC_Functions.Misc
{
+ ///
+ /// Contains extension functions to work with 1D and 2D arrays
+ ///
public static class ArrayFormatter
{
- public static T[,] Resize(this T[,] original, int rows, int cols)
+ ///
+ /// Copies and resizes the array
+ ///
+ /// The original array. This is not modified
+ /// The new amount of elements
+ /// The type of elements in the array
+ /// The new, resized array
+ public static T[] Resize(this T[] original, int elements)
+ {
+ T[] output = new T[original.Length];
+ original.CopyTo(output, 0);
+ Array.Resize(ref output, elements);
+ return output;
+ }
+ ///
+ /// Copies and resizes the array
+ ///
+ /// The original array. This is not modified
+ /// The new amount of elements in dimension 0
+ /// The new amount of elements in dimension 1
+ /// The element to place in empty fields of the new array
+ /// The type of elements in the array
+ /// The new, resized array
+ public static T[,] Resize(this T[,] original, int rows, int cols, T defaultEl = default)
{
T[,] newArray = new T[rows, cols];
+ newArray.Populate(defaultEl);
int minRows = Math.Min(rows, original.GetLength(0));
int minCols = Math.Min(cols, original.GetLength(1));
for (int i = 0; i < minRows; i++)
@@ -16,8 +43,13 @@ namespace CC_Functions.Misc
newArray[i, j] = original[i, j];
return newArray;
}
-
- public static char[,] ToNDArray2D(this string source, char defaultEl = SpecialChars.empty)
+ ///
+ /// Converts a string to a 2d char array using newlines
+ ///
+ /// The source string
+ /// The element to place in empty fields of the new array
+ /// The generated array
+ public static char[,] ToNdArray2D(this string source, char defaultEl = SpecialChars.Empty)
{
string[] sourceArr = source.Split('\n');
int width = sourceArr.Select(s => s.Length).OrderBy(s => s).Last();
@@ -32,11 +64,21 @@ namespace CC_Functions.Misc
}
return output;
}
-
- public static void Populate(this T[] arr, T value) {
- for ( int i = 0; i < arr.Length;i++ ) arr[i] = value;
+ ///
+ /// Clears and fills the array with the specified value
+ ///
+ /// The array to populate
+ /// The value to copy to the array, defaults to the default value (usually null)
+ /// The type of elements in the array
+ public static void Populate(this T[] arr, T value = default) {
+ for (int i = 0; i < arr.Length; i++) arr[i] = value;
}
-
+ ///
+ /// Clears and fills the array with the specified value
+ ///
+ /// The array to populate
+ /// The value to copy to the array, defaults to the default value (usually null)
+ /// The type of elements in the array
public static void Populate(this T[,] arr, T value)
{
int w = arr.GetLength(0);
@@ -44,7 +86,13 @@ namespace CC_Functions.Misc
for (int i = 0; i < w; i++)
for (int j = 0; j < h; j++) arr[i, j] = value;
}
-
+ ///
+ /// Copies the content of a 2D array to another with offset
+ ///
+ /// The array to copy from
+ /// The array to copy to
+ /// The copy offset
+ /// The type of elements in the array
public static void CopyTo(this T[,] arr, T[,] target, Point offset)
{
int w = arr.GetLength(1);
@@ -57,7 +105,12 @@ namespace CC_Functions.Misc
for (int y = oh; y < Math.Min(mh, h + oh); y++)
target[y, x] = arr[y - oh, x - ow];
}
-
+ ///
+ /// Copies and rotates the 2d array (row->column, column->row)
+ ///
+ /// The array to copy from
+ /// The type of elements in the array
+ /// The new, rotated array
public static T[,] Rotate(this T[,] arr)
{
int w = arr.GetLength(0);
diff --git a/Misc/Crypto.cs b/Misc/Crypto.cs
index 95c3395..937aa44 100644
--- a/Misc/Crypto.cs
+++ b/Misc/Crypto.cs
@@ -4,8 +4,18 @@ using System.Security.Cryptography;
namespace CC_Functions.Misc
{
+ ///
+ /// Contains cryptographic functions
+ ///
public static class Crypto
{
+ ///
+ /// Encrypts an array of bytes using SHA512. Use with Decrypt
+ ///
+ /// The array of bytes to encrypt
+ /// The key for encryption, later required to decrypt
+ /// The encrypted data
+ /// Thrown if provided data is invalid
public static byte[] Encrypt(byte[] data, byte[] key)
{
if (key is null)
@@ -39,7 +49,13 @@ namespace CC_Functions.Misc
return combined;
}
-
+ ///
+ /// Decrypts an SHA512-encrypted byte array. Use with Encrypt
+ ///
+ /// The array of bytes to decrypt
+ /// The key the data was encrypted with
+ /// The decrypted data
+ /// Thrown if provided data is invalid
public static byte[] Decrypt(byte[] encrypted, byte[] key)
{
if (key is null)
diff --git a/Misc/GenericExtensions.cs b/Misc/GenericExtensions.cs
index ebb226f..45a2106 100644
--- a/Misc/GenericExtensions.cs
+++ b/Misc/GenericExtensions.cs
@@ -8,22 +8,48 @@ using System.Net;
namespace CC_Functions.Misc
{
+ ///
+ /// Extension methods for various types
+ ///
public static class GenericExtensions
{
- public static T get(this Dictionary dict, G key, T def)
+ ///
+ /// Gets an element from the dictionary or adds the default
+ ///
+ /// The dictionary to get from
+ /// The key to check
+ /// The default value to place
+ /// The key type
+ /// The value type
+ /// The element at the key
+ public static TValue Get(this IDictionary dict, TKey key, TValue def = default)
{
if (!dict.ContainsKey(key))
dict[key] = def;
return dict[key];
}
-
- public static T set(this Dictionary dict, G key, T val)
+ ///
+ /// Sets an element and returns it
+ ///
+ /// The dictionary to set in
+ /// The key to set at
+ /// The value to place
+ /// The key type
+ /// The value type
+ /// The value that was placed
+ public static TValue Set(this IDictionary dict, TKey key, TValue val = default)
{
dict[key] = val;
return dict[key];
}
-
- public static bool tryCast(this object o, out T parsed)
+ ///
+ /// Tries to cast an object
+ ///
+ /// The object to try to parse
+ /// The parsed object (if successful) or the default (usually null)
+ /// The type to cast to
+ /// Whether the cast was successful
+ public static bool TryCast(this object o, out T parsed)
{
try
{
@@ -36,58 +62,126 @@ namespace CC_Functions.Misc
return false;
}
}
-
- public static G selectO(this T self, Func func) => func.Invoke(self);
-
- public static void runIf(bool condition, Action func)
+ ///
+ /// Runs a function that transforms an object in-line
+ ///
+ /// The object to run on
+ /// The function to run
+ /// The input type
+ /// The output type
+ ///
+ public static TOut SelectO(this TIn self, Func func) => func.Invoke(self);
+ ///
+ /// Runs a function under a condition in-line (equal to if)
+ ///
+ /// The condition to check
+ /// The function to run
+ public static void RunIf(bool condition, Action func)
{
if (condition)
func();
}
+ ///
+ /// Parses a string to a value of an enum
+ ///
+ /// The string to parse
+ /// The enum type (MUST be an enum)
+ /// The element
+ public static TEnum ParseToEnum(string value) => (TEnum) Enum.Parse(typeof(TEnum),
+ Enum.GetNames(typeof(TEnum)).First(s => s.ToLower() == value.ToLower()));
- public static T ParseToEnum(string value) => (T) Enum.Parse(typeof(T),
- Enum.GetNames(typeof(T)).First(s => s.ToLower() == value.ToLower()));
-
+ ///
+ /// Parses a string to a nullable bool (defaults to null if parse fails)
+ ///
+ /// The st string to parse
+ /// The output nullable bool
public static bool? ParseBool(string value) =>
- string.IsNullOrWhiteSpace(value) || value.ToLower() == "Indeterminate"
- ? (bool?) null
- : bool.Parse(value);
-
- public static bool AND(this bool? left, bool? right) => left.TRUE() && right.TRUE();
-
- public static bool OR(this bool? left, bool? right) => left.TRUE() || right.TRUE();
-
- public static bool XOR(this bool? left, bool? right) => left.OR(right) && !left.AND(right);
-
- public static bool TRUE(this bool? self) => self == true;
-
- public static bool FALSE(this bool? self) => self == false;
-
- public static bool NULL(this bool? self) => self == null;
-
- public static void RemoveAt(this Dictionary dict, int index) =>
- dict.Remove(dict.Keys.OfType().ToArray()[index]);
-
+ bool.TryParse(value, out bool tmp) ? (bool?)tmp : null;
+ ///
+ /// AND operation for nullable bools (uses True)
+ ///
+ /// First bool to check
+ /// Second bool to check
+ /// The operation result
+ public static bool And(this bool? left, bool? right) => left.True() && right.True();
+ ///
+ /// OR operation for nullable bools (uses True)
+ ///
+ /// First bool to check
+ /// Second bool to check
+ /// The operation result
+ public static bool Or(this bool? left, bool? right) => left.True() || right.True();
+ ///
+ /// XOR operation for nullable bools (uses True)
+ ///
+ /// First bool to check
+ /// Second bool to check
+ /// The operation result
+ public static bool Xor(this bool? left, bool? right) => left.Or(right) && !left.And(right);
+ ///
+ /// Whether the nullable bool is true (null->false)
+ ///
+ /// Value to check
+ /// Whether it is true
+ public static bool True(this bool? self) => self == true;
+ ///
+ /// Whether the nullable bool is false (null->false)
+ ///
+ /// Value to check
+ /// Whether it is false
+ public static bool False(this bool? self) => self == false;
+ ///
+ /// Whether the nullable bool is null
+ ///
+ /// Value to check
+ /// Whether it is null
+ public static bool Null(this bool? self) => self == null;
+ ///
+ /// Removes an element from a dictionary by its index (not key)
+ ///
+ /// The dictionary to remove from
+ /// The index of the value
+ /// The key type
+ /// The value type
+ public static void RemoveAt(this Dictionary dict, int index) =>
+ dict.Remove(dict.Keys.ToArray()[index]);
+ ///
+ /// Gets the size of a dictionary
+ ///
+ /// The dictionary to check
+ /// The size of the dictionary
public static long GetSize(this DirectoryInfo directory) => IO.GetDirectorySize(directory.FullName);
-
+ ///
+ /// Adds a directory to an archive recursively
+ ///
+ /// The archive to add to
+ /// The directory to add
+ /// The name of the directory in-archive
+ /// Extensions for files to ignore
+ /// Paths to exclude from adding
+ /// The new entry
public static ZipArchiveEntry AddDirectory(this ZipArchive archive, string folderPath, string entryName,
string[] ignoredExtensions, string[] ignoredPaths)
{
entryName = entryName.TrimEnd('/');
ZipArchiveEntry result = archive.CreateEntry($"{entryName}/");
string[] files = Directory.GetFiles(folderPath);
- for (int i = 0; i < files.Length; i++)
- if (!ignoredExtensions.Contains(Path.GetExtension(files[i])) &&
- !ignoredPaths.Any(s => IO.CheckPathEqual(s, files[i])))
- archive.CreateEntryFromFile(files[i], $"{entryName}/{Path.GetFileName(files[i])}");
+ foreach (string t in files)
+ if (!ignoredExtensions.Contains(Path.GetExtension(t)) &&
+ !ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
+ archive.CreateEntryFromFile(t, $"{entryName}/{Path.GetFileName(t)}");
string[] dirs = Directory.GetDirectories(folderPath);
- for (int i = 0; i < dirs.Length; i++)
- if (!ignoredPaths.Any(s => IO.CheckPathEqual(s, dirs[i])))
- archive.AddDirectory(dirs[i], $"{entryName}/{Path.GetFileName(dirs[i])}", ignoredExtensions,
+ foreach (string t in dirs)
+ if (!ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
+ archive.AddDirectory(t, $"{entryName}/{Path.GetFileName(t)}", ignoredExtensions,
ignoredPaths);
return result;
}
-
+ ///
+ /// "Unshorten" (follow) an URL
+ ///
+ /// The URL to unshorten
+ /// The unshortened URL
public static Uri Unshorten(this Uri self)
{
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(self);
@@ -96,7 +190,11 @@ namespace CC_Functions.Misc
WebResponse resp = req.GetResponse();
return resp.ResponseUri;
}
-
+ ///
+ /// Pings an URL to check for availability
+ ///
+ /// The URL to check
+ /// Whether the service is online
public static bool Ping(this Uri self)
{
try
@@ -112,10 +210,31 @@ namespace CC_Functions.Misc
return false;
}
}
-
+ ///
+ /// Rounds a RectangleF to a Rectangle instead of flooring
+ ///
+ /// The RectangleF to round
+ /// The rounded Rectangle
public static Rectangle Round(this RectangleF self) => Rectangle.Round(self);
+ ///
+ /// Ceilings a RectangleF to a Rectangle instead of flooring
+ ///
+ /// The RectangleF to ceil (?)
+ /// The ceiled (?) Rectangle
public static Rectangle Ceiling(this RectangleF self) => Rectangle.Ceiling(self);
+ ///
+ /// Extension method for Crypto's Encrypt
+ ///
+ /// The data to encrypt
+ /// The key to encrypt with
+ /// The encrypted data
public static byte[] Encrypt(this byte[] self, byte[] key) => Crypto.Encrypt(self, key);
+ ///
+ /// Extension method for Crypto's Decrypt
+ ///
+ /// The data to decrypt
+ /// The key to decrypt with
+ /// The decrypted data
public static byte[] Decrypt(this byte[] self, byte[] key) => Crypto.Decrypt(self, key);
}
}
\ No newline at end of file
diff --git a/Misc/HID.cs b/Misc/HID.cs
index 34cb9fe..85e04ae 100644
--- a/Misc/HID.cs
+++ b/Misc/HID.cs
@@ -7,9 +7,15 @@ using System.Text;
namespace CC_Functions.Misc
{
- public static class HID
+ ///
+ /// Functions for hardware identidiers
+ ///
+ public static class Hid
{
- public static bool forceWindows = false;
+ ///
+ /// Whether to force Win32-based operation
+ ///
+ public static bool ForceWindows = false;
private static byte[] _fingerPrint;
private static readonly string HIDClasses = @"Win32_Processor:UniqueId
@@ -27,14 +33,16 @@ Win32_BaseBoard:Manufacturer
Win32_BaseBoard:Name
Win32_BaseBoard:SerialNumber
Win32_NetworkAdapterConfiguration:MACAddress";
-
+ ///
+ /// The HID for this machine
+ ///
public static byte[] Value
{
get
{
if (_fingerPrint != null) return _fingerPrint;
string fingerprintTmp = "";
- if (forceWindows || new [] {PlatformID.Xbox, PlatformID.Win32S, PlatformID.Win32Windows, PlatformID.Win32NT, PlatformID.WinCE}.Contains(Environment.OSVersion.Platform))
+ if (ForceWindows || new [] {PlatformID.Xbox, PlatformID.Win32S, PlatformID.Win32Windows, PlatformID.Win32NT, PlatformID.WinCE}.Contains(Environment.OSVersion.Platform))
{
HIDClasses.Split(new[] {"\r\n"}, StringSplitOptions.None).Select(s =>
{
@@ -91,10 +99,18 @@ Win32_NetworkAdapterConfiguration:MACAddress";
return _fingerPrint;
}
}
-
+ ///
+ /// Encrypts data using Crypto's Encrypt and the HID
+ ///
+ /// The data to encrypt
+ /// The encrypted data
public static byte[] EncryptLocal(byte[] unencrypted) =>
Crypto.Encrypt(unencrypted, Value);
-
+ ///
+ /// Decrypts data using Crypto's Decrypt and the HID
+ ///
+ /// The data to decrypt
+ /// The decrypted data
public static byte[] DecryptLocal(byte[] encrypted) =>
Crypto.Decrypt(encrypted, Value);
}
diff --git a/Misc/IO.cs b/Misc/IO.cs
index 11407d3..3f40a02 100644
--- a/Misc/IO.cs
+++ b/Misc/IO.cs
@@ -3,16 +3,30 @@ using System.IO;
namespace CC_Functions.Misc
{
+ ///
+ /// IO functions
+ ///
public static class IO
{
+ ///
+ /// Recursively gets the size of an directory
+ ///
+ /// The path of the directory
+ /// The size of the directory
public static long GetDirectorySize(string path)
{
string[] a = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
long size = 0;
- for (int i = 0; i < a.Length; i++) size += new FileInfo(a[i]).Length;
+ foreach (string t in a)
+ size += new FileInfo(t).Length;
return size;
}
-
+ ///
+ /// Check whether the paths are equivalent (ignores case)
+ ///
+ /// The first path to check
+ /// The second path to check
+ /// Whether the paths are equal
public static bool CheckPathEqual(string path1, string path2) =>
Path.GetFullPath(path1)
.Equals(Path.GetFullPath(path2), StringComparison.InvariantCultureIgnoreCase);
diff --git a/Misc/SpecialChars.cs b/Misc/SpecialChars.cs
index 03e7372..4483dc1 100644
--- a/Misc/SpecialChars.cs
+++ b/Misc/SpecialChars.cs
@@ -1,7 +1,13 @@
namespace CC_Functions.Misc
{
+ ///
+ /// Characters for use in CC-Functions.CommandLine
+ ///
public static class SpecialChars
{
- public const char empty = ' ';
+ ///
+ /// The space character
+ ///
+ public const char Empty = ' ';
}
}
\ No newline at end of file