Base features
This commit is contained in:
254
src/FileTime.ConsoleUI.App/Application.CommandHandlers.cs
Normal file
254
src/FileTime.ConsoleUI.App/Application.CommandHandlers.cs
Normal file
@@ -0,0 +1,254 @@
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
using FileTime.Core.Command;
|
||||
using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.ConsoleUI.App
|
||||
{
|
||||
public partial class Application
|
||||
{
|
||||
private void ClosePane()
|
||||
{
|
||||
var currentPaneIndex = _panes.IndexOf(_selectedPane!);
|
||||
RemovePane(_selectedPane!);
|
||||
|
||||
if (_panes.Count > 0)
|
||||
{
|
||||
_selectedPane = _panes[currentPaneIndex == 0 ? 0 : currentPaneIndex - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedPane = null;
|
||||
IsRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveCursorUp() => _selectedPane!.SelectPreviousItem();
|
||||
private void MoveCursorDown() => _selectedPane!.SelectNextItem();
|
||||
private void GoUp() => _selectedPane!.GoUp();
|
||||
private void Open() => _selectedPane!.Open();
|
||||
|
||||
private void MoveCursorUpPage() => _selectedPane!.SelectPreviousItem(_renderers[_selectedPane].PageSize);
|
||||
private void MoveCursorDownPage() => _selectedPane!.SelectNextItem(_renderers[_selectedPane].PageSize);
|
||||
private void MoveCursorToTop() => _selectedPane!.SelectFirstItem();
|
||||
private void MoveCursorToBottom() => _selectedPane!.SelectLastItem();
|
||||
|
||||
private void ToggleHidden()
|
||||
{
|
||||
const string hiddenFilterName = "filter_showhiddenelements";
|
||||
|
||||
IContainer containerToOpen = _selectedPane!.CurrentLocation;
|
||||
|
||||
if (_selectedPane.CurrentLocation is VirtualContainer oldVirtualContainer)
|
||||
{
|
||||
containerToOpen = oldVirtualContainer.HasWithName(hiddenFilterName)
|
||||
? oldVirtualContainer.ExceptWithName(hiddenFilterName)
|
||||
: GenerateHiddenFilterVirtualContainer(_selectedPane.CurrentLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
containerToOpen = GenerateHiddenFilterVirtualContainer(_selectedPane.CurrentLocation);
|
||||
}
|
||||
|
||||
_selectedPane.OpenContainer(containerToOpen);
|
||||
|
||||
static VirtualContainer GenerateHiddenFilterVirtualContainer(IContainer container)
|
||||
{
|
||||
return new VirtualContainer(
|
||||
container,
|
||||
new List<Func<IEnumerable<IContainer>, IEnumerable<IContainer>>>()
|
||||
{
|
||||
container => container.Where(c => !c.IsHidden)
|
||||
},
|
||||
new List<Func<IEnumerable<IElement>, IEnumerable<IElement>>>()
|
||||
{
|
||||
element => element.Where(e => !e.IsHidden)
|
||||
},
|
||||
true,
|
||||
true,
|
||||
hiddenFilterName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
if (_selectedPane!.CurrentSelectedItem != null)
|
||||
{
|
||||
var currentSelectedItem = _selectedPane.CurrentSelectedItem;
|
||||
if (_paneStates[_selectedPane].ContainsSelectedItem(currentSelectedItem.Provider, _selectedPane.CurrentLocation, currentSelectedItem.FullName!))
|
||||
{
|
||||
_paneStates[_selectedPane].RemoveSelectedItem(currentSelectedItem.Provider, _selectedPane.CurrentLocation, currentSelectedItem.FullName!);
|
||||
}
|
||||
else
|
||||
{
|
||||
_paneStates[_selectedPane].AddSelectedItem(currentSelectedItem.Provider, _selectedPane.CurrentLocation, currentSelectedItem.FullName!);
|
||||
}
|
||||
|
||||
_selectedPane.SelectNextItem();
|
||||
}
|
||||
}
|
||||
|
||||
public void Copy()
|
||||
{
|
||||
_clipboard.Clear();
|
||||
_clipboard.SetCommand<CopyCommand>();
|
||||
|
||||
if (_paneStates[_selectedPane!].GetCurrentSelectedItems().Count > 0)
|
||||
{
|
||||
foreach (var selectedItem in _paneStates[_selectedPane!].GetCurrentSelectedItems())
|
||||
{
|
||||
_clipboard.AddContent(selectedItem.ContentProvider, selectedItem.Path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_clipboard.AddContent(_selectedPane!.CurrentSelectedItem!.Provider, _selectedPane.CurrentSelectedItem.FullName!);
|
||||
}
|
||||
}
|
||||
|
||||
public void Cut()
|
||||
{
|
||||
_clipboard.Clear();
|
||||
_clipboard.SetCommand<MoveCommand>();
|
||||
}
|
||||
|
||||
public void PasteMerge()
|
||||
{
|
||||
Paste(TransportMode.Merge);
|
||||
}
|
||||
public void PasteOverwrite()
|
||||
{
|
||||
Paste(TransportMode.Overwrite);
|
||||
}
|
||||
|
||||
public void PasteSkip()
|
||||
{
|
||||
Paste(TransportMode.Skip);
|
||||
}
|
||||
|
||||
private void Paste(TransportMode transportMode)
|
||||
{
|
||||
if (_clipboard.CommandType != null)
|
||||
{
|
||||
var command = (ITransportationCommand)Activator.CreateInstance(_clipboard.CommandType!)!;
|
||||
command.TransportMode = transportMode;
|
||||
|
||||
command.Sources.Clear();
|
||||
|
||||
foreach (var item in _clipboard.Content)
|
||||
{
|
||||
command.Sources.Add(item);
|
||||
}
|
||||
|
||||
command.Target = _selectedPane.CurrentLocation is VirtualContainer virtualContainer
|
||||
? virtualContainer.BaseContainer
|
||||
: _selectedPane.CurrentLocation;
|
||||
|
||||
_commandExecutor.ExecuteCommand(command);
|
||||
|
||||
_clipboard.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateContainer()
|
||||
{
|
||||
if (_selectedPane?.CurrentLocation != null)
|
||||
{
|
||||
_coloredConsoleRenderer.ResetColor();
|
||||
MoveToIOLine(2);
|
||||
_coloredConsoleRenderer.Write("New container name: ");
|
||||
var newContainerName = _consoleReader.ReadText(validator: Validator);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(newContainerName))
|
||||
{
|
||||
_selectedPane.CurrentLocation.CreateContainer(newContainerName);
|
||||
}
|
||||
}
|
||||
|
||||
void Validator(string newPath)
|
||||
{
|
||||
if (_selectedPane!.CurrentLocation.IsExists(newPath))
|
||||
{
|
||||
_coloredConsoleRenderer.ForegroundColor = AnsiColor.From8bit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_coloredConsoleRenderer.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HardDelete()
|
||||
{
|
||||
IList<IAbsolutePath> itemsToDelete = null;
|
||||
|
||||
if (_paneStates[_selectedPane!].GetCurrentSelectedItems().Count > 0)
|
||||
{
|
||||
var delete = true;
|
||||
|
||||
if (_paneStates[_selectedPane!].GetCurrentSelectedItems().Count == 1
|
||||
&& _paneStates[_selectedPane!].GetCurrentSelectedItems()[0] is IContainer container
|
||||
&& container.Items.Count > 0)
|
||||
{
|
||||
delete = AskForApprove($"The container '{container.Name}' is not empty.");
|
||||
}
|
||||
|
||||
if (delete)
|
||||
{
|
||||
itemsToDelete = _paneStates[_selectedPane].GetCurrentSelectedItems().Cast<IAbsolutePath>().ToList();
|
||||
}
|
||||
}
|
||||
else if (_selectedPane?.CurrentSelectedItem != null)
|
||||
{
|
||||
bool delete = true;
|
||||
if (_selectedPane?.CurrentSelectedItem is IContainer container && container.Items.Count > 0)
|
||||
{
|
||||
delete = AskForApprove($"The container '{container.Name}' is not empty.");
|
||||
}
|
||||
|
||||
if (delete)
|
||||
{
|
||||
itemsToDelete = new List<IAbsolutePath>()
|
||||
{
|
||||
new AbsolutePath(_selectedPane.CurrentSelectedItem.Provider, _selectedPane.CurrentSelectedItem.FullName!)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToDelete != null)
|
||||
{
|
||||
var deleteCommand = new DeleteCommand();
|
||||
|
||||
foreach (var itemToDelete in itemsToDelete)
|
||||
{
|
||||
deleteCommand.ItemsToDelete.Add(itemToDelete);
|
||||
}
|
||||
|
||||
_commandExecutor.ExecuteCommand(deleteCommand);
|
||||
_clipboard.Clear();
|
||||
}
|
||||
|
||||
bool AskForApprove(string name)
|
||||
{
|
||||
MoveToIOLine(2);
|
||||
_coloredConsoleRenderer.Write(name + " Proceed to delete? (Y/N)");
|
||||
|
||||
while (true)
|
||||
{
|
||||
var key = Console.ReadKey(true);
|
||||
|
||||
if (key.Key == ConsoleKey.Y)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (key.Key == ConsoleKey.N)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
271
src/FileTime.ConsoleUI.App/Application.cs
Normal file
271
src/FileTime.ConsoleUI.App/Application.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.ConsoleUI.App.UI;
|
||||
using FileTime.ConsoleUI.App.Command;
|
||||
using FileTime.Core.Components;
|
||||
using FileTime.Core.Extensions;
|
||||
using FileTime.App.Core.Clipboard;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using FileTime.App.Core.Pane;
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
using FileTime.Core.Command;
|
||||
|
||||
namespace FileTime.ConsoleUI.App
|
||||
{
|
||||
public partial class Application
|
||||
{
|
||||
private readonly List<Pane> _panes = new();
|
||||
private readonly Dictionary<Pane, Render> _renderers = new();
|
||||
private readonly Dictionary<Pane, PaneState> _paneStates = new();
|
||||
private Pane? _selectedPane;
|
||||
|
||||
private readonly List<CommandBinding> _commandBindings = new();
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IClipboard _clipboard;
|
||||
private readonly IColoredConsoleRenderer _coloredConsoleRenderer;
|
||||
private readonly CommandExecutor _commandExecutor;
|
||||
private readonly ConsoleReader _consoleReader;
|
||||
private readonly List<ConsoleKeyInfo> _previousKeys = new();
|
||||
|
||||
public bool IsRunning { get; private set; } = true;
|
||||
|
||||
public Application(
|
||||
IServiceProvider serviceProvider,
|
||||
IClipboard clipboard,
|
||||
IColoredConsoleRenderer coloredConsoleRenderer,
|
||||
CommandExecutor commandExecutor,
|
||||
ConsoleReader consoleReader)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_clipboard = clipboard;
|
||||
_coloredConsoleRenderer = coloredConsoleRenderer;
|
||||
_commandExecutor = commandExecutor;
|
||||
_consoleReader = consoleReader;
|
||||
InitCommandBindings();
|
||||
}
|
||||
|
||||
public void SetContainer(IContainer currentPath)
|
||||
{
|
||||
_selectedPane = CreatePane(currentPath);
|
||||
}
|
||||
|
||||
private Pane CreatePane(IContainer container)
|
||||
{
|
||||
var pane = new Pane(container);
|
||||
_panes.Add(pane);
|
||||
|
||||
var paneState = new PaneState(pane);
|
||||
_paneStates.Add(pane, paneState);
|
||||
|
||||
var renderer = _serviceProvider.GetService<Render>()!;
|
||||
renderer.Init(pane, paneState);
|
||||
_renderers.Add(pane, renderer);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
private void RemovePane(Pane pane)
|
||||
{
|
||||
_panes.Remove(pane);
|
||||
_renderers.Remove(pane);
|
||||
_paneStates.Remove(pane);
|
||||
}
|
||||
|
||||
private void InitCommandBindings()
|
||||
{
|
||||
var commandBindings = new List<CommandBinding>()
|
||||
{
|
||||
new CommandBinding("close pane", Commands.ClosePane, new[] { new ConsoleKeyInfo('q', ConsoleKey.Q, false, false, false) }, ClosePane),
|
||||
new CommandBinding("cursor up", Commands.MoveCursorUp, new[] { new ConsoleKeyInfo('↑', ConsoleKey.UpArrow, false, false, false) }, MoveCursorUp),
|
||||
new CommandBinding("cursor down", Commands.MoveCursorDown, new[] { new ConsoleKeyInfo('↓', ConsoleKey.DownArrow, false, false, false) }, MoveCursorDown),
|
||||
new CommandBinding("cursor page up", Commands.MoveCursorUpPage, new[] { new ConsoleKeyInfo(' ', ConsoleKey.PageUp, false, false, false) }, MoveCursorUpPage),
|
||||
new CommandBinding("cursor page down", Commands.MoveCursorDownPage, new[] { new ConsoleKeyInfo(' ', ConsoleKey.PageDown, false, false, false) }, MoveCursorDownPage),
|
||||
new CommandBinding("go up", Commands.GoUp, new[] { new ConsoleKeyInfo('←', ConsoleKey.LeftArrow, false, false, false) }, GoUp),
|
||||
new CommandBinding("open", Commands.Open, new[] { new ConsoleKeyInfo('→', ConsoleKey.RightArrow, false, false, false) }, Open),
|
||||
new CommandBinding(
|
||||
"go to top",
|
||||
Commands.GoToTop,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('g', ConsoleKey.G, false, false, false),
|
||||
new ConsoleKeyInfo('g', ConsoleKey.G, false, false, false)
|
||||
},
|
||||
MoveCursorToTop),
|
||||
new CommandBinding(
|
||||
"go to bottom",
|
||||
Commands.GoToBottom,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('G', ConsoleKey.G, true, false, false)
|
||||
},
|
||||
MoveCursorToBottom),
|
||||
new CommandBinding(
|
||||
"toggle hidden",
|
||||
Commands.ToggleHidden,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('z', ConsoleKey.Z, false, false, false),
|
||||
new ConsoleKeyInfo('h', ConsoleKey.H, false, false, false)
|
||||
},
|
||||
ToggleHidden),
|
||||
new CommandBinding("select", Commands.Select, new[] { new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false) }, Select),
|
||||
new CommandBinding(
|
||||
"copy",
|
||||
Commands.Copy,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('y', ConsoleKey.Y, false, false, false),
|
||||
new ConsoleKeyInfo('y', ConsoleKey.Y, false, false, false)
|
||||
},
|
||||
Copy),
|
||||
new CommandBinding(
|
||||
"cut",
|
||||
Commands.Cut,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false),
|
||||
new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false)
|
||||
},
|
||||
Cut),
|
||||
new CommandBinding(
|
||||
"paste (merge)",
|
||||
Commands.Paste,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('p', ConsoleKey.P, false, false, false),
|
||||
new ConsoleKeyInfo('p', ConsoleKey.P, false, false, false)
|
||||
},
|
||||
PasteMerge),
|
||||
new CommandBinding(
|
||||
"paste (overwrite)",
|
||||
Commands.Paste,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('p', ConsoleKey.P, false, false, false),
|
||||
new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false)
|
||||
},
|
||||
PasteOverwrite),
|
||||
new CommandBinding(
|
||||
"paste (skip)",
|
||||
Commands.Paste,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('p', ConsoleKey.P, false, false, false),
|
||||
new ConsoleKeyInfo('s', ConsoleKey.S, false, false, false)
|
||||
},
|
||||
PasteSkip),
|
||||
new CommandBinding(
|
||||
"create container",
|
||||
Commands.CreateContainer,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('c', ConsoleKey.C, false, false, false),
|
||||
new ConsoleKeyInfo('c', ConsoleKey.C, false, false, false)
|
||||
},
|
||||
CreateContainer),
|
||||
new CommandBinding(
|
||||
"delete",
|
||||
Commands.CreateContainer,
|
||||
new[]
|
||||
{
|
||||
new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false),
|
||||
new ConsoleKeyInfo('D', ConsoleKey.D, true, false, false)
|
||||
},
|
||||
HardDelete),
|
||||
};
|
||||
|
||||
_commandBindings.AddRange(commandBindings);
|
||||
}
|
||||
|
||||
public void PrintUI()
|
||||
{
|
||||
if (_selectedPane != null)
|
||||
{
|
||||
_renderers[_selectedPane].PrintUI();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ProcessKey(ConsoleKeyInfo keyinfo)
|
||||
{
|
||||
var key = keyinfo.Key;
|
||||
_previousKeys.Add(keyinfo);
|
||||
|
||||
CommandBinding? selectedCommandBinding = _commandBindings.Find(c => AreKeysEqual(c.Keys, _previousKeys));
|
||||
|
||||
if (keyinfo.Key == ConsoleKey.Escape)
|
||||
{
|
||||
_previousKeys.Clear();
|
||||
return true;
|
||||
}
|
||||
else if (_previousKeys.Count == 2 && selectedCommandBinding == null)
|
||||
{
|
||||
HandleNoCommandFound();
|
||||
return false;
|
||||
}
|
||||
else if (selectedCommandBinding != null)
|
||||
{
|
||||
selectedCommandBinding.Invoke();
|
||||
_previousKeys.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.ResetColor();
|
||||
int commandToDisplay = 0;
|
||||
var possibleCommands = _commandBindings.Where(c => AreKeysEqual(c.Keys[0], keyinfo)).ToList();
|
||||
|
||||
if (possibleCommands.Count == 0)
|
||||
{
|
||||
HandleNoCommandFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var commandBinding in possibleCommands)
|
||||
{
|
||||
Console.SetCursorPosition(10, Console.WindowHeight - 1 - possibleCommands.Count + commandToDisplay++);
|
||||
_coloredConsoleRenderer.Write(
|
||||
$"{{0,-{Console.WindowWidth - 10}}}",
|
||||
string.Concat(commandBinding.Keys.Select(k => DisplayKey(k).Map(s => s.Length > 1 ? $" {s} " : s))) + ": " + commandBinding.Name
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
void HandleNoCommandFound()
|
||||
{
|
||||
Console.SetCursorPosition(10, Console.WindowHeight - 2);
|
||||
_coloredConsoleRenderer.Write(
|
||||
$"{{0,-{Console.WindowWidth - 10}}}",
|
||||
"No command found for key(s): " + string.Format("{0,-20}", string.Concat(_previousKeys.Select(k => DisplayKey(k).Map(s => s.Length > 1 ? $" {s} " : s))))
|
||||
);
|
||||
_previousKeys.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static string DisplayKey(ConsoleKeyInfo keyInfo) =>
|
||||
string.IsNullOrWhiteSpace(keyInfo.KeyChar.ToString()) || keyInfo.KeyChar == '\0'
|
||||
? keyInfo.Key.ToString()
|
||||
: keyInfo.KeyChar.ToString();
|
||||
|
||||
private static bool AreKeysEqual(IReadOnlyList<ConsoleKeyInfo> collection1, IReadOnlyList<ConsoleKeyInfo> collection2)
|
||||
{
|
||||
if (collection1.Count != collection2.Count) return false;
|
||||
|
||||
for (var i = 0; i < collection1.Count; i++)
|
||||
{
|
||||
if (!AreKeysEqual(collection1[i], collection2[i])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool AreKeysEqual(ConsoleKeyInfo keyInfo1, ConsoleKeyInfo keyInfo2) =>
|
||||
keyInfo1.Key == keyInfo2.Key && keyInfo1.Modifiers == keyInfo2.Modifiers;
|
||||
|
||||
private static void MoveToIOLine(int left = 0)
|
||||
{
|
||||
Console.SetCursorPosition(left, Console.WindowHeight - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/FileTime.ConsoleUI.App/Command/CommandBinding.cs
Normal file
22
src/FileTime.ConsoleUI.App/Command/CommandBinding.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace FileTime.ConsoleUI.App.Command
|
||||
{
|
||||
public class CommandBinding
|
||||
{
|
||||
private readonly Action _commandHandler;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public ConsoleKeyInfo[] Keys { get; }
|
||||
public Commands Command { get; }
|
||||
|
||||
public CommandBinding(string name, Commands command, ConsoleKeyInfo[] keys, Action commandHandler)
|
||||
{
|
||||
Name = name;
|
||||
Command = command;
|
||||
Keys = keys;
|
||||
_commandHandler = commandHandler;
|
||||
}
|
||||
|
||||
public void Invoke() => _commandHandler();
|
||||
}
|
||||
}
|
||||
22
src/FileTime.ConsoleUI.App/Command/Commands.cs
Normal file
22
src/FileTime.ConsoleUI.App/Command/Commands.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace FileTime.ConsoleUI.App.Command
|
||||
{
|
||||
public enum Commands
|
||||
{
|
||||
ClosePane,
|
||||
Copy,
|
||||
Cut,
|
||||
GoUp,
|
||||
MoveCursorDown,
|
||||
MoveCursorUp,
|
||||
Open,
|
||||
Paste,
|
||||
Select,
|
||||
ToggleHidden,
|
||||
CreateContainer,
|
||||
CreateElement,
|
||||
MoveCursorUpPage,
|
||||
MoveCursorDownPage,
|
||||
GoToTop,
|
||||
GoToBottom,
|
||||
}
|
||||
}
|
||||
14
src/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj
Normal file
14
src/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileTime.Core\FileTime.Core.csproj" />
|
||||
<ProjectReference Include="..\FileTime.App.Core\FileTime.App.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
25
src/FileTime.ConsoleUI.App/UI/Color/AnsiColor.cs
Normal file
25
src/FileTime.ConsoleUI.App/UI/Color/AnsiColor.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace FileTime.ConsoleUI.App.UI.Color
|
||||
{
|
||||
public class AnsiColor : IConsoleColor
|
||||
{
|
||||
public string? Color { get; }
|
||||
public string? Prefix { get; }
|
||||
public string? Postfix { get; }
|
||||
public AnsiColor() { }
|
||||
|
||||
public AnsiColor(string color, string preFix = "5;", string postFix = "m")
|
||||
{
|
||||
Color = color;
|
||||
Prefix = preFix;
|
||||
Postfix = postFix;
|
||||
}
|
||||
|
||||
public static AnsiColor FromRgb(int r, int g, int b) => new($"{r};{g};{b}", "5;", "m");
|
||||
public static AnsiColor From8bit(byte color) => new($"{color}", "5;", "m");
|
||||
|
||||
public override string? ToString()
|
||||
{
|
||||
return Color == null ? null : Prefix + Color + Postfix;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/FileTime.ConsoleUI.App/UI/Color/BasicColor.cs
Normal file
14
src/FileTime.ConsoleUI.App/UI/Color/BasicColor.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace FileTime.ConsoleUI.App.UI.Color
|
||||
{
|
||||
public class BasicColor : IConsoleColor
|
||||
{
|
||||
public BasicColor() { }
|
||||
|
||||
public BasicColor(ConsoleColor color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public ConsoleColor? Color { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
namespace FileTime.ConsoleUI.App.UI.Color
|
||||
{
|
||||
public class ColoredConsoleRenderer : IColoredConsoleRenderer
|
||||
{
|
||||
private readonly IStyles _styles;
|
||||
|
||||
public IConsoleColor? BackgroundColor { get; set; }
|
||||
public IConsoleColor? ForegroundColor { get; set; }
|
||||
|
||||
public ColoredConsoleRenderer(IStyles styles)
|
||||
{
|
||||
_styles = styles;
|
||||
BackgroundColor = _styles.DefaultBackground;
|
||||
ForegroundColor = _styles.DefaultForeground;
|
||||
}
|
||||
|
||||
public void Write(string text) => DoWrite(text);
|
||||
public void Write(char c) => DoWrite(c.ToString());
|
||||
public void Write(string format, params object[] param) => DoWrite(string.Format(format, param));
|
||||
|
||||
private void DoWrite(string text)
|
||||
{
|
||||
if (BackgroundColor is AnsiColor ansiBackground && ForegroundColor is AnsiColor ansiForeground)
|
||||
{
|
||||
var formatting = "\u001b[0m";
|
||||
|
||||
if (ansiBackground.Color != null)
|
||||
{
|
||||
formatting += "\u001b[48;" + ansiBackground.ToString();
|
||||
}
|
||||
|
||||
if (ansiForeground.Color != null)
|
||||
{
|
||||
formatting += "\u001b[38;" + ansiForeground.ToString();
|
||||
}
|
||||
|
||||
Console.Write(formatting + text);
|
||||
}
|
||||
else if (BackgroundColor is BasicColor basicBackground && ForegroundColor is BasicColor basicForeground)
|
||||
{
|
||||
Console.BackgroundColor = basicBackground.Color ?? Console.BackgroundColor;
|
||||
Console.ForegroundColor = basicForeground.Color ?? Console.ForegroundColor;
|
||||
|
||||
Console.Write(text);
|
||||
}
|
||||
else if (BackgroundColor == null && ForegroundColor == null)
|
||||
{
|
||||
Console.Write(text);
|
||||
}
|
||||
else if (BackgroundColor == null || ForegroundColor == null)
|
||||
{
|
||||
throw new Exception($"Either both of {nameof(BackgroundColor)} and {nameof(ForegroundColor)} must be null or neither of them.");
|
||||
}
|
||||
else if (BackgroundColor.GetType() != ForegroundColor.GetType())
|
||||
{
|
||||
throw new Exception($"Type of {nameof(BackgroundColor)} and {nameof(ForegroundColor)} must be the same.");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Unsupported color type: {BackgroundColor.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetColor()
|
||||
{
|
||||
BackgroundColor = _styles.DefaultBackground;
|
||||
ForegroundColor = _styles.DefaultForeground;
|
||||
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Console.SetCursorPosition(0, 0);
|
||||
Write(new string(' ', Console.WindowHeight * Console.WindowWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace FileTime.ConsoleUI.App.UI.Color
|
||||
{
|
||||
public interface IColoredConsoleRenderer
|
||||
{
|
||||
IConsoleColor? BackgroundColor { get; set; }
|
||||
IConsoleColor? ForegroundColor { get; set; }
|
||||
|
||||
void Clear();
|
||||
void ResetColor();
|
||||
void Write(string text);
|
||||
void Write(char c);
|
||||
void Write(string format, params object[] param);
|
||||
}
|
||||
}
|
||||
4
src/FileTime.ConsoleUI.App/UI/Color/IConsoleColor.cs
Normal file
4
src/FileTime.ConsoleUI.App/UI/Color/IConsoleColor.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace FileTime.ConsoleUI.App.UI.Color
|
||||
{
|
||||
public interface IConsoleColor { }
|
||||
}
|
||||
89
src/FileTime.ConsoleUI.App/UI/ConsoleReader.cs
Normal file
89
src/FileTime.ConsoleUI.App/UI/ConsoleReader.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
|
||||
namespace FileTime.ConsoleUI.App.UI
|
||||
{
|
||||
public class ConsoleReader
|
||||
{
|
||||
private readonly IColoredConsoleRenderer _coloredConsoleRenderer;
|
||||
|
||||
public ConsoleReader(IColoredConsoleRenderer coloredConsoleRenderer)
|
||||
{
|
||||
_coloredConsoleRenderer = coloredConsoleRenderer;
|
||||
}
|
||||
public string ReadText(int? maxLength = null, Action<string>? validator = null)
|
||||
{
|
||||
var cursorVisible = false;
|
||||
try
|
||||
{
|
||||
cursorVisible = Console.CursorVisible;
|
||||
}
|
||||
catch { }
|
||||
|
||||
Console.CursorVisible = true;
|
||||
|
||||
var currentConsoleLeft = Console.CursorLeft;
|
||||
var currentConsoleTop = Console.CursorTop;
|
||||
|
||||
maxLength ??= Console.WindowWidth - currentConsoleLeft;
|
||||
|
||||
var input = "";
|
||||
var position = 0;
|
||||
|
||||
_coloredConsoleRenderer.Write($"{{0,-{maxLength}}}", input);
|
||||
|
||||
var key = Console.ReadKey(true);
|
||||
while (key.Key != ConsoleKey.Enter)
|
||||
{
|
||||
if (key.Key == ConsoleKey.Escape)
|
||||
{
|
||||
input = null;
|
||||
break;
|
||||
}
|
||||
else if (key.Key == ConsoleKey.Backspace)
|
||||
{
|
||||
if (position != 0)
|
||||
{
|
||||
input = input.Length > 0
|
||||
? input[..(position - 1)] + input[position..]
|
||||
: input;
|
||||
|
||||
position--;
|
||||
}
|
||||
}
|
||||
else if (key.Key == ConsoleKey.LeftArrow)
|
||||
{
|
||||
if (position > 0)
|
||||
position--;
|
||||
}
|
||||
else if (key.Key == ConsoleKey.RightArrow)
|
||||
{
|
||||
if (position < input.Length)
|
||||
position++;
|
||||
}
|
||||
else if (key.KeyChar != '\0')
|
||||
{
|
||||
var newInput = input[..position] + key.KeyChar;
|
||||
|
||||
if (position < input.Length)
|
||||
{
|
||||
newInput += input[position..];
|
||||
}
|
||||
|
||||
input = newInput;
|
||||
|
||||
position++;
|
||||
}
|
||||
validator?.Invoke(input);
|
||||
|
||||
Console.SetCursorPosition(currentConsoleLeft, currentConsoleTop);
|
||||
_coloredConsoleRenderer.Write($"{{0,-{maxLength}}}", input);
|
||||
|
||||
Console.SetCursorPosition(currentConsoleLeft + position, currentConsoleTop);
|
||||
key = Console.ReadKey();
|
||||
}
|
||||
|
||||
Console.CursorVisible = cursorVisible;
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/FileTime.ConsoleUI.App/UI/IStyles.cs
Normal file
18
src/FileTime.ConsoleUI.App/UI/IStyles.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
|
||||
namespace FileTime.ConsoleUI.App.UI
|
||||
{
|
||||
public interface IStyles
|
||||
{
|
||||
IConsoleColor? DefaultBackground { get; }
|
||||
IConsoleColor? DefaultForeground { get; }
|
||||
IConsoleColor? ContainerBackground { get; }
|
||||
IConsoleColor? ContainerForeground { get; }
|
||||
IConsoleColor? ElementBackground { get; }
|
||||
IConsoleColor? ElementForeground { get; }
|
||||
IConsoleColor? ElementSpecialBackground { get; }
|
||||
IConsoleColor? ElementSpecialForeground { get; }
|
||||
IConsoleColor? SelectedItemBackground { get; }
|
||||
IConsoleColor? SelectedItemForeground { get; }
|
||||
}
|
||||
}
|
||||
9
src/FileTime.ConsoleUI.App/UI/PrintMode.cs
Normal file
9
src/FileTime.ConsoleUI.App/UI/PrintMode.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace FileTime.ConsoleUI.UI.App
|
||||
{
|
||||
public enum PrintMode
|
||||
{
|
||||
Previous,
|
||||
Current,
|
||||
Next
|
||||
}
|
||||
}
|
||||
281
src/FileTime.ConsoleUI.App/UI/Render.cs
Normal file
281
src/FileTime.ConsoleUI.App/UI/Render.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
using FileTime.App.Core.Pane;
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
using FileTime.ConsoleUI.UI.App;
|
||||
using FileTime.Core.Components;
|
||||
using FileTime.Core.Extensions;
|
||||
using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.ConsoleUI.App.UI
|
||||
{
|
||||
public class Render
|
||||
{
|
||||
private const int _contentPaddingTop = 1;
|
||||
private const int _contentPaddingBottom = 2;
|
||||
private readonly int _contentRowCount;
|
||||
private readonly IStyles _appStyle;
|
||||
private readonly IColoredConsoleRenderer _coloredRenderer;
|
||||
|
||||
private int _currentDisplayStartY;
|
||||
|
||||
private const int ITEMPADDINGLEFT = 1;
|
||||
private const int ITEMPADDINGRIGHT = 2;
|
||||
|
||||
private readonly string _paddingLeft;
|
||||
private readonly string _paddingRight;
|
||||
|
||||
public Pane Pane { get; private set; }
|
||||
public PaneState PaneState { get; private set; }
|
||||
|
||||
public int PageSize => Console.WindowHeight - _contentPaddingTop - _contentPaddingBottom;
|
||||
public Render(IColoredConsoleRenderer coloredRenderer, IStyles appStyle)
|
||||
{
|
||||
_coloredRenderer = coloredRenderer;
|
||||
_appStyle = appStyle;
|
||||
|
||||
_paddingLeft = new string(' ', ITEMPADDINGLEFT);
|
||||
_paddingRight = new string(' ', ITEMPADDINGRIGHT);
|
||||
_contentRowCount = Console.WindowHeight - _contentPaddingTop - _contentPaddingBottom;
|
||||
}
|
||||
|
||||
public void Init(Pane pane, PaneState paneState)
|
||||
{
|
||||
if (pane == null) throw new Exception($"{nameof(pane)} can not be null");
|
||||
if (paneState == null) throw new Exception($"{nameof(paneState)} can not be null");
|
||||
|
||||
Pane = pane;
|
||||
Pane.CurrentLocationChanged += (o, e) => _currentDisplayStartY = 0;
|
||||
|
||||
PaneState = paneState;
|
||||
}
|
||||
|
||||
public void PrintUI()
|
||||
{
|
||||
if (Pane != null)
|
||||
{
|
||||
PrintPrompt();
|
||||
PrintPanes();
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintPanes()
|
||||
{
|
||||
var previousColumnWidth = (int)Math.Floor(Console.WindowWidth * 0.15) - 1;
|
||||
var currentColumnWidth = (int)Math.Floor(Console.WindowWidth * 0.4) - 1;
|
||||
var nextColumnWidth = Console.WindowWidth - currentColumnWidth - previousColumnWidth - 2;
|
||||
var currentVirtualContainer = Pane!.CurrentLocation as VirtualContainer;
|
||||
|
||||
if (Pane.CurrentLocation.GetParent() is var parentContainer && parentContainer is not null)
|
||||
{
|
||||
parentContainer.Refresh();
|
||||
|
||||
PrintColumn(
|
||||
currentVirtualContainer != null
|
||||
? currentVirtualContainer.CloneVirtualChainFor(parentContainer, v => v.IsTransitive)
|
||||
: parentContainer,
|
||||
currentVirtualContainer != null
|
||||
? currentVirtualContainer.GetRealContainer()
|
||||
: Pane.CurrentLocation,
|
||||
PrintMode.Previous,
|
||||
0,
|
||||
_contentPaddingTop,
|
||||
previousColumnWidth,
|
||||
_contentRowCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanColumn(
|
||||
0,
|
||||
_contentPaddingTop,
|
||||
previousColumnWidth,
|
||||
_contentRowCount);
|
||||
}
|
||||
|
||||
Pane.CurrentLocation.Refresh();
|
||||
|
||||
CheckAndSetCurrentDisplayStartY();
|
||||
PrintColumn(
|
||||
Pane.CurrentLocation,
|
||||
Pane.CurrentSelectedItem,
|
||||
PrintMode.Current,
|
||||
previousColumnWidth + 1,
|
||||
_contentPaddingTop,
|
||||
currentColumnWidth,
|
||||
_contentRowCount);
|
||||
|
||||
if (Pane.CurrentSelectedItem is IContainer selectedContainer)
|
||||
{
|
||||
selectedContainer.Refresh();
|
||||
|
||||
selectedContainer = currentVirtualContainer != null
|
||||
? currentVirtualContainer.CloneVirtualChainFor(selectedContainer, v => v.IsTransitive)
|
||||
: selectedContainer;
|
||||
|
||||
PrintColumn(
|
||||
selectedContainer,
|
||||
selectedContainer.Items.Count > 0 ? selectedContainer.Items[0] : null,
|
||||
PrintMode.Next,
|
||||
previousColumnWidth + currentColumnWidth + 2,
|
||||
_contentPaddingTop,
|
||||
nextColumnWidth,
|
||||
_contentRowCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanColumn(
|
||||
previousColumnWidth + currentColumnWidth + 2,
|
||||
_contentPaddingTop,
|
||||
nextColumnWidth,
|
||||
_contentRowCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintPrompt()
|
||||
{
|
||||
Console.SetCursorPosition(0, 0);
|
||||
_coloredRenderer.ResetColor();
|
||||
_coloredRenderer.ForegroundColor = AnsiColor.From8bit(2);
|
||||
_coloredRenderer.Write(Environment.UserName + "@" + Environment.MachineName);
|
||||
|
||||
_coloredRenderer.ResetColor();
|
||||
_coloredRenderer.Write(' ');
|
||||
|
||||
_coloredRenderer.ForegroundColor = AnsiColor.From8bit(4);
|
||||
var path = Pane!.CurrentLocation.FullName + "/";
|
||||
_coloredRenderer.Write(path);
|
||||
|
||||
if (Pane.CurrentSelectedItem?.Name != null)
|
||||
{
|
||||
_coloredRenderer.ResetColor();
|
||||
_coloredRenderer.Write($"{{0,-{300 - path.Length}}}", Pane.CurrentSelectedItem.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintColumn(IContainer currentContainer, IItem? currentItem, PrintMode printMode, int startX, int startY, int elementWidth, int availableRows)
|
||||
{
|
||||
var allItem = currentContainer.Containers.Cast<IItem>().Concat(currentContainer.Elements).ToList();
|
||||
var printedItemsCount = 0;
|
||||
var currentY = 0;
|
||||
if (allItem.Count > 0)
|
||||
{
|
||||
var currentIndex = allItem.FindIndex(i => i == currentItem);
|
||||
|
||||
var skipElements = printMode switch
|
||||
{
|
||||
PrintMode.Previous => (currentIndex - (availableRows / 2)).Map(r => r < 0 ? 0 : r),
|
||||
PrintMode.Current => _currentDisplayStartY,
|
||||
PrintMode.Next => 0,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
var maxTextWidth = elementWidth - ITEMPADDINGLEFT - ITEMPADDINGRIGHT;
|
||||
|
||||
var itemsToPrint = currentContainer.Items.Skip(skipElements).Take(availableRows).ToList();
|
||||
printedItemsCount = itemsToPrint.Count;
|
||||
foreach (var item in itemsToPrint)
|
||||
{
|
||||
Console.SetCursorPosition(startX, startY + currentY++);
|
||||
var namePart = item.Name.Length > maxTextWidth
|
||||
? string.Concat(item.Name.AsSpan(0, maxTextWidth - 1), "~")
|
||||
: item.Name;
|
||||
|
||||
var attributePart = "";
|
||||
|
||||
var container = item as IContainer;
|
||||
var element = item as IElement;
|
||||
|
||||
IConsoleColor? backgroundColor = null;
|
||||
IConsoleColor? foregroundColor = null;
|
||||
|
||||
if (container != null)
|
||||
{
|
||||
backgroundColor = _appStyle.ContainerBackground;
|
||||
foregroundColor = _appStyle.ContainerForeground;
|
||||
}
|
||||
else if (element != null)
|
||||
{
|
||||
if (element.IsSpecial)
|
||||
{
|
||||
backgroundColor = _appStyle.ElementSpecialBackground;
|
||||
foregroundColor = _appStyle.ElementSpecialForeground;
|
||||
}
|
||||
else
|
||||
{
|
||||
backgroundColor = _appStyle.ElementBackground;
|
||||
foregroundColor = _appStyle.ElementForeground;
|
||||
}
|
||||
}
|
||||
|
||||
var isSelected = PaneState.ContainsSelectedItem(item.Provider, currentContainer, item.FullName!);
|
||||
if (isSelected)
|
||||
{
|
||||
backgroundColor = _appStyle.SelectedItemBackground;
|
||||
foregroundColor = _appStyle.SelectedItemForeground;
|
||||
}
|
||||
|
||||
if (item == currentItem)
|
||||
{
|
||||
(backgroundColor, foregroundColor) = (foregroundColor, backgroundColor);
|
||||
}
|
||||
|
||||
_coloredRenderer.BackgroundColor = backgroundColor;
|
||||
_coloredRenderer.ForegroundColor = foregroundColor;
|
||||
|
||||
attributePart = container != null ? "" + container.Items.Count : element!.GetPrimaryAttributeText();
|
||||
|
||||
var text = string.Format($"{{0,-{elementWidth}}}", _paddingLeft + (isSelected ? " " : "") + namePart + _paddingRight);
|
||||
text = string.Concat(text.AsSpan(0, text.Length - attributePart.Length - 1), " ", attributePart);
|
||||
|
||||
_coloredRenderer.Write(text);
|
||||
|
||||
_coloredRenderer.ResetColor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_coloredRenderer.BackgroundColor = new BasicColor(ConsoleColor.Red);
|
||||
_coloredRenderer.ForegroundColor = new BasicColor(ConsoleColor.White);
|
||||
Console.SetCursorPosition(startX, startY + currentY++);
|
||||
|
||||
_coloredRenderer.Write($"{{0,-{elementWidth}}}", _paddingLeft + "<empty>" + _paddingRight);
|
||||
}
|
||||
|
||||
var padding = new string(' ', elementWidth);
|
||||
_coloredRenderer.ResetColor();
|
||||
for (var i = 0; i < availableRows - printedItemsCount + 1; i++)
|
||||
{
|
||||
Console.SetCursorPosition(startX, startY + currentY++);
|
||||
_coloredRenderer.Write(padding);
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanColumn(int startX, int startY, int elementWidth, int availableRows)
|
||||
{
|
||||
_coloredRenderer.ResetColor();
|
||||
|
||||
var currentY = 0;
|
||||
var placeholder = new string(' ', elementWidth);
|
||||
for (var i = 0; i < availableRows; i++)
|
||||
{
|
||||
Console.SetCursorPosition(startX, startY + currentY++);
|
||||
_coloredRenderer.Write(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAndSetCurrentDisplayStartY()
|
||||
{
|
||||
const int padding = 5;
|
||||
|
||||
while (Pane.CurrentSelectedIndex < _currentDisplayStartY + padding
|
||||
&& _currentDisplayStartY > 0)
|
||||
{
|
||||
_currentDisplayStartY--;
|
||||
}
|
||||
|
||||
while (Pane.CurrentSelectedIndex > _currentDisplayStartY + _contentRowCount - padding
|
||||
&& _currentDisplayStartY < Pane.CurrentLocation.Items.Count - _contentRowCount)
|
||||
{
|
||||
_currentDisplayStartY++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/FileTime.ConsoleUI.App/UI/Styles.cs
Normal file
39
src/FileTime.ConsoleUI.App/UI/Styles.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using FileTime.ConsoleUI.App.UI.Color;
|
||||
|
||||
namespace FileTime.ConsoleUI.App.UI
|
||||
{
|
||||
public class Styles : IStyles
|
||||
{
|
||||
public IConsoleColor? DefaultBackground { get; }
|
||||
public IConsoleColor? DefaultForeground { get; }
|
||||
public IConsoleColor? ContainerBackground { get; }
|
||||
public IConsoleColor? ContainerForeground { get; }
|
||||
public IConsoleColor? ElementBackground { get; }
|
||||
public IConsoleColor? ElementForeground { get; }
|
||||
public IConsoleColor? ElementSpecialBackground { get; }
|
||||
public IConsoleColor? ElementSpecialForeground { get; }
|
||||
public IConsoleColor? SelectedItemBackground { get; }
|
||||
public IConsoleColor? SelectedItemForeground { get; }
|
||||
|
||||
public Styles(bool useAnsiColors)
|
||||
{
|
||||
if (useAnsiColors)
|
||||
{
|
||||
ContainerForeground = AnsiColor.From8bit(4);
|
||||
ElementForeground = AnsiColor.From8bit(14);
|
||||
ElementSpecialForeground = AnsiColor.From8bit(2);
|
||||
SelectedItemForeground = AnsiColor.From8bit(3);
|
||||
|
||||
DefaultForeground = ElementForeground;
|
||||
SelectedItemBackground = ElementSpecialBackground = ContainerBackground = DefaultBackground = ElementBackground = AnsiColor.From8bit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerBackground = new BasicColor(Console.BackgroundColor);
|
||||
ContainerForeground = new BasicColor(ConsoleColor.Blue);
|
||||
ElementBackground = new BasicColor(Console.BackgroundColor);
|
||||
ElementForeground = new BasicColor(Console.ForegroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user