From 99fe793c167c62e55de007d1d9ded9a03c992002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9A=D0=BE=D0=BB=D0=BE=D1=81=D0=BE=D0=B2?= Date: Mon, 18 Mar 2024 00:57:31 +0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Version=20components=20create.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TLD.sln | 6 ++ .../Resizings/ResizingExtensions.cs | 6 +- src/TUI.Engine/Components/ComponentBase.cs | 12 ++++ src/TUI.Engine/Components/IComponent.cs | 6 ++ .../Containers/ContainerExtensions.cs | 24 +++++++- src/TUI.Engine/Extensions.cs | 5 +- .../Rendering/ContainerCraftsman.cs | 6 +- src/TUI.Engine/Symbols.cs | 57 +++++++++++++++---- src/TUI.Engine/TUI.Engine.csproj | 3 - src/TUI.Engine/Theme/Palette.cs | 6 ++ src/TUI/Controls/Common/StubComponent.cs | 33 +++++++++++ .../Components}/CellsComponentBase.cs | 2 +- .../Components/PanelComponent.cs} | 36 ++++++------ .../Controls => Controls/Components}/Tag.cs | 12 ++-- .../Controls/Components/VersionComponent.cs | 36 ++++++++++++ src/TUI/Controls/Components/VersionType.cs | 10 ++++ .../Components/VersionTypeExtensions.cs | 17 ++++++ .../Controls/Containers/ContentContainer.cs | 19 +++++++ .../Controls/Containers/DashboardContainer.cs | 31 ++++++++++ .../Containers/DependencyContainer.cs | 29 ++++++++++ .../Containers}/HeaderContainer.cs | 8 +-- .../Layouts/DashboardLayout.cs | 47 ++++++--------- .../Statics/CopyrightComponent.cs} | 8 +-- .../Controls/Statics/Hints/AppTypeHints.cs | 11 ++-- .../Controls/Statics/Hints/HotkeysHint.cs | 2 +- .../Controls/Statics/Hints/TagHints.cs | 11 ++-- .../Controls/Statics/Hints/VersionHints.cs | 11 ++-- .../Statics/LogoComponent.cs} | 4 +- src/TUI/Domain/NewFile1.txt | 2 +- src/TUI/Pages/DependenciesPage.cs | 19 ++++--- src/TUI/TUI.csproj | 10 +++- src/TUI/UserInterface/Icons.cs | 32 ++--------- .../TUI.Controls.Tests.csproj | 33 +++++++++++ tests/TUI.Controls.Tests/Usings.cs | 1 + .../VersionComponentTests.cs | 26 +++++++++ .../TUI.Engine.Tests/Draw/DrawStaticTests.cs | 38 +++++++++++++ tests/TUI.Engine.Tests/MockExtensions.cs | 4 ++ .../Primitives/IntegerTests.cs | 2 +- 38 files changed, 482 insertions(+), 143 deletions(-) create mode 100644 src/TUI/Controls/Common/StubComponent.cs rename src/TUI/{Components/Controls => Controls/Components}/CellsComponentBase.cs (95%) rename src/TUI/{Components/Controls/Dashboard.cs => Controls/Components/PanelComponent.cs} (57%) rename src/TUI/{Components/Controls => Controls/Components}/Tag.cs (77%) create mode 100644 src/TUI/Controls/Components/VersionComponent.cs create mode 100644 src/TUI/Controls/Components/VersionType.cs create mode 100644 src/TUI/Controls/Components/VersionTypeExtensions.cs create mode 100644 src/TUI/Controls/Containers/ContentContainer.cs create mode 100644 src/TUI/Controls/Containers/DashboardContainer.cs create mode 100644 src/TUI/Controls/Containers/DependencyContainer.cs rename src/TUI/{Components/Controls => Controls/Containers}/HeaderContainer.cs (88%) rename src/TUI/{Components => Controls}/Layouts/DashboardLayout.cs (66%) rename src/TUI/{Components/Controls/Copyright.cs => Controls/Statics/CopyrightComponent.cs} (62%) rename src/TUI/{Components => }/Controls/Statics/Hints/AppTypeHints.cs (69%) rename src/TUI/{Components => }/Controls/Statics/Hints/HotkeysHint.cs (92%) rename src/TUI/{Components => }/Controls/Statics/Hints/TagHints.cs (69%) rename src/TUI/{Components => }/Controls/Statics/Hints/VersionHints.cs (61%) rename src/TUI/{Components/Controls/Statics/Logo.cs => Controls/Statics/LogoComponent.cs} (92%) create mode 100644 tests/TUI.Controls.Tests/TUI.Controls.Tests.csproj create mode 100644 tests/TUI.Controls.Tests/Usings.cs create mode 100644 tests/TUI.Controls.Tests/VersionComponentTests.cs create mode 100644 tests/TUI.Engine.Tests/Draw/DrawStaticTests.cs diff --git a/TLD.sln b/TLD.sln index be4f9f0..aa4e2cc 100644 --- a/TLD.sln +++ b/TLD.sln @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Engine.Tests", "tests\T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Engine", "src\TUI.Engine\TUI.Engine.csproj", "{38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Controls.Tests", "tests\TUI.Controls.Tests\TUI.Controls.Tests.csproj", "{59A0E843-8664-45B9-AD0C-52B8FE38986A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -28,5 +30,9 @@ Global {38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}.Debug|Any CPU.Build.0 = Debug|Any CPU {38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}.Release|Any CPU.ActiveCfg = Release|Any CPU {38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}.Release|Any CPU.Build.0 = Release|Any CPU + {59A0E843-8664-45B9-AD0C-52B8FE38986A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59A0E843-8664-45B9-AD0C-52B8FE38986A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59A0E843-8664-45B9-AD0C-52B8FE38986A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59A0E843-8664-45B9-AD0C-52B8FE38986A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/src/TUI.Engine/Attributes/Resizings/ResizingExtensions.cs b/src/TUI.Engine/Attributes/Resizings/ResizingExtensions.cs index e502342..df50d2e 100644 --- a/src/TUI.Engine/Attributes/Resizings/ResizingExtensions.cs +++ b/src/TUI.Engine/Attributes/Resizings/ResizingExtensions.cs @@ -18,13 +18,15 @@ internal static class ResizingExtensions } var fixedNodes = container.GetFixedNodes().ToArray(); + var absoluteNodes = container.GetAbsoluteNodes().ToArray(); var fixedHeight = fixedNodes.Sum(s => s.GetFixedSize().Height); var allowableHeight = maxHeight - fixedHeight; - var allowableCount = container.GetNodes().Count - fixedNodes.Length; + var allowableCount = container.GetNodes().Count - fixedNodes.Length - absoluteNodes.Length; var nodeHeight = (allowableHeight / allowableCount).Min(1); - var nodeNumber = nodeIndex + 1 - container.GetFixedNodes(nodeIndex).Sum(c => c.GetFixedSize().Height); + var nodeNumber = nodeIndex + 1 - container.GetFixedNodes(nodeIndex).Count() - + container.GetAbsoluteNodes(nodeIndex).Count(); if (allowableHeight - nodeNumber * nodeHeight < nodeHeight) { diff --git a/src/TUI.Engine/Components/ComponentBase.cs b/src/TUI.Engine/Components/ComponentBase.cs index 121a059..1b37294 100644 --- a/src/TUI.Engine/Components/ComponentBase.cs +++ b/src/TUI.Engine/Components/ComponentBase.cs @@ -10,6 +10,18 @@ public abstract class ComponentBase : NodeBase, IComponent { protected abstract Sketch DrawComponent(Size minSize); + public bool IsRelative { get; private set; } = true; + + public void SetRelative() + { + IsRelative = true; + } + + public void SetAbsolute() + { + IsRelative = false; + } + Sketch IComponent.MakeSketch(Size minSize) => DrawComponent(minSize); #region Alignments diff --git a/src/TUI.Engine/Components/IComponent.cs b/src/TUI.Engine/Components/IComponent.cs index 1beb97f..aa79ee7 100644 --- a/src/TUI.Engine/Components/IComponent.cs +++ b/src/TUI.Engine/Components/IComponent.cs @@ -7,5 +7,11 @@ namespace TUI.Engine.Components; public interface IComponent : INode, IWithAlignment, IWithPadding { + internal bool IsRelative { get; } + + public void SetRelative(); + + public void SetAbsolute(); + internal Sketch MakeSketch(Size minSize); } \ No newline at end of file diff --git a/src/TUI.Engine/Containers/ContainerExtensions.cs b/src/TUI.Engine/Containers/ContainerExtensions.cs index 3b6eb36..a53270d 100644 --- a/src/TUI.Engine/Containers/ContainerExtensions.cs +++ b/src/TUI.Engine/Containers/ContainerExtensions.cs @@ -1,10 +1,30 @@ using TUI.Engine.Attributes.Resizings; +using TUI.Engine.Components; using TUI.Engine.Nodes; namespace TUI.Engine.Containers; internal static class ContainerExtensions { + private static readonly Func AbsoluteNodes = node => node is IComponent { IsRelative: false }; + + private static readonly Func FixedNodes = node => node.ResizingVertical == Resizing.Fixed; + + internal static IEnumerable GetAbsoluteNodes(this IContainer container, int? takeNodeNumber = null) + { + if (takeNodeNumber is not null) + { + return container + .GetNodes() + .Take(takeNodeNumber.Value + 1) + .Where(AbsoluteNodes); + } + + return container + .GetNodes() + .Where(AbsoluteNodes); + } + internal static IEnumerable GetFixedNodes(this IContainer container, int? takeNodeNumber = null) { if (takeNodeNumber is not null) @@ -12,11 +32,11 @@ internal static class ContainerExtensions return container .GetNodes() .Take(takeNodeNumber.Value + 1) - .Where(n => n.ResizingVertical == Resizing.Fixed); + .Where(FixedNodes); } return container .GetNodes() - .Where(n => n.ResizingVertical == Resizing.Fixed); + .Where(FixedNodes); } } \ No newline at end of file diff --git a/src/TUI.Engine/Extensions.cs b/src/TUI.Engine/Extensions.cs index b54b99b..9ef3c11 100644 --- a/src/TUI.Engine/Extensions.cs +++ b/src/TUI.Engine/Extensions.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Text; using System.Text.RegularExpressions; namespace TUI.Engine; @@ -20,9 +21,9 @@ public static class Extensions return array.Any(item => item == findValue); } - public static string Repeat(this char symbol, int repeatCount) + public static string Repeat(this string value, int count) { - return repeatCount < 0 ? string.Empty : new string(symbol, repeatCount); + return count < 0 ? string.Empty : new StringBuilder(value.Length * count).Insert(0, value, count).ToString(); } public static string RemoveColors(this string text) diff --git a/src/TUI.Engine/Rendering/ContainerCraftsman.cs b/src/TUI.Engine/Rendering/ContainerCraftsman.cs index 22d139c..74b4601 100644 --- a/src/TUI.Engine/Rendering/ContainerCraftsman.cs +++ b/src/TUI.Engine/Rendering/ContainerCraftsman.cs @@ -28,7 +28,7 @@ internal sealed class ContainerCraftsman : CraftsmanBase, IDrawable { var node = nodes[nodeNumber]; var nodeSize = node.GetSize(container, nodeNumber, maxSize); - + nextNodePosition = DrawNode(node, container, nextNodePosition, nodeSize); nodeNumber++; } @@ -45,7 +45,9 @@ internal sealed class ContainerCraftsman : CraftsmanBase, IDrawable return GetNextNodePosition(container, containerSize, nodePosition); case IComponent childComponent: var componentSize = _componentCraftsman.Draw(childComponent, nodePosition, maxSize); - return GetNextNodePosition(container, maxSize, nodePosition, componentSize); + return childComponent.IsRelative + ? GetNextNodePosition(container, maxSize, nodePosition, componentSize) + : nodePosition; default: throw new InvalidCastException(); } diff --git a/src/TUI.Engine/Symbols.cs b/src/TUI.Engine/Symbols.cs index ea35302..3857193 100644 --- a/src/TUI.Engine/Symbols.cs +++ b/src/TUI.Engine/Symbols.cs @@ -1,25 +1,58 @@ +using Pastel; +using TUI.Engine.Theme; + namespace TUI.Engine; public static class Symbols { - public const char Space = ' '; - public const char Copyright = '©'; - public const char GitLab = ''; - public const char GitHub = ''; - public const char Git = ''; - public const char LineBreak = '\n'; + public const string Space = " "; + public const string Copyright = "©"; + public const string GitLab = ""; + public const string GitHub = ""; + public const string Git = ""; + public const string LineBreak = "\n"; + public const string NetworkPublic = "󰞉"; + public const string NetworkPrivate = "󰕑"; + public const string Undefined = ""; + public const string Site = ""; + public const string Api = ""; + public const string DockerImage = ""; + public const string NpmPackage = ""; + public const string SEO = "󰚩"; + public const string Auth = ""; + public const string NotFound = ""; public static class Lines { - public const char Vertical = '│'; - public const char Horizontal = '─'; + public const string Vertical = "│"; + public const string Horizontal = "─"; } public static class Angles { - public const char RightTop = '┐'; - public const char LeftBottom = '└'; - public const char LeftTop = '┌'; - public const char RightBottom = '┘'; + public const string RightTop = "┐"; + public const string LeftBottom = "└"; + public const string LeftTop = "┌"; + public const string RightBottom = "┘"; } } + +public static class CharExtensions +{ + public static string Colorized(this string symbol) => + !SymbolColors.ContainsKey(symbol) ? symbol.Hint() : symbol.Pastel(SymbolColors[symbol]); + + private static readonly Dictionary SymbolColors = new() + { + { Symbols.Git, "F14E32" }, + { Symbols.Site, "BF40BF" }, + { Symbols.GitLab, "E24329" }, + { Symbols.GitHub, "ADBAC7" }, + { Symbols.NetworkPublic, "00FFFF" }, + { Symbols.Api, "7F52FF" }, + { Symbols.DockerImage, "086DD7" }, + { Symbols.NpmPackage, "CB0000" }, + { Symbols.SEO, "4285F4" }, + { Symbols.Auth, "FFD700" }, + }; +} \ No newline at end of file diff --git a/src/TUI.Engine/TUI.Engine.csproj b/src/TUI.Engine/TUI.Engine.csproj index 270ccf7..5e00211 100644 --- a/src/TUI.Engine/TUI.Engine.csproj +++ b/src/TUI.Engine/TUI.Engine.csproj @@ -12,9 +12,6 @@ <_Parameter1>$(MSBuildProjectName).Tests - - <_Parameter1>Other.Assembly.Name - diff --git a/src/TUI.Engine/Theme/Palette.cs b/src/TUI.Engine/Theme/Palette.cs index 4b700d0..5ab1765 100644 --- a/src/TUI.Engine/Theme/Palette.cs +++ b/src/TUI.Engine/Theme/Palette.cs @@ -18,6 +18,8 @@ public static class Palette public static string Hint(this string currentText) => currentText.Pastel(HintColor); + public static string Hint(this char currentText) => currentText.ToString().Pastel(HintColor); + public static string Disable(this string currentText) => currentText.RemoveColors().Pastel(HintColor); public static string Warning(this string currentText) => currentText.Pastel(WarningColor); @@ -25,4 +27,8 @@ public static class Palette public static string Error(this string currentText) => currentText.Pastel(ErrorColor); public static string Info(this string currentText) => currentText.Pastel(InfoColor); + + public static string Info(this char currentText) => currentText.ToString().Pastel(InfoColor); + + public static string Info(this int currentText) => currentText.ToString().Pastel(InfoColor); } \ No newline at end of file diff --git a/src/TUI/Controls/Common/StubComponent.cs b/src/TUI/Controls/Common/StubComponent.cs new file mode 100644 index 0000000..8a498ee --- /dev/null +++ b/src/TUI/Controls/Common/StubComponent.cs @@ -0,0 +1,33 @@ +using System.Text; +using TUI.Engine; +using TUI.Engine.Attributes; +using TUI.Engine.Attributes.Orientations; +using TUI.Engine.Components; + +namespace TUI.Controls.Common; + +public class StubComponent : ComponentBase +{ + private readonly Size _size; + + public StubComponent(Size size) + { + _size = size; + SetFixed(Orientation.Horizontal, size.Width); + SetFixed(Orientation.Vertical, size.Height); + } + + protected override Sketch DrawComponent(Size minSize) + { + var builder = new StringBuilder(); + var height = 0; + + while (_size.Height > height) + { + builder.Append(Symbols.Space.Repeat(_size.Width)); + height++; + } + + return new Sketch(builder.ToString()); + } +} \ No newline at end of file diff --git a/src/TUI/Components/Controls/CellsComponentBase.cs b/src/TUI/Controls/Components/CellsComponentBase.cs similarity index 95% rename from src/TUI/Components/Controls/CellsComponentBase.cs rename to src/TUI/Controls/Components/CellsComponentBase.cs index c22e157..a50685c 100644 --- a/src/TUI/Components/Controls/CellsComponentBase.cs +++ b/src/TUI/Controls/Components/CellsComponentBase.cs @@ -4,7 +4,7 @@ using TUI.Engine.Attributes; using TUI.Engine.Attributes.Alignments; using TUI.Engine.Components; -namespace TUI.Components.Controls; +namespace TUI.Controls.Components; public class CellsComponentBase : ComponentBase, IComponent { diff --git a/src/TUI/Components/Controls/Dashboard.cs b/src/TUI/Controls/Components/PanelComponent.cs similarity index 57% rename from src/TUI/Components/Controls/Dashboard.cs rename to src/TUI/Controls/Components/PanelComponent.cs index 7e1f75f..a3536b5 100644 --- a/src/TUI/Components/Controls/Dashboard.cs +++ b/src/TUI/Controls/Components/PanelComponent.cs @@ -3,28 +3,30 @@ using TUI.Engine; using TUI.Engine.Attributes; using TUI.Engine.Components; using TUI.Engine.Theme; +using static TUI.Engine.Symbols; -namespace TUI.Components.Controls; +namespace TUI.Controls.Components; -public class Dashboard : ComponentBase, IComponent +public class PanelComponent : ComponentBase, IComponent { private readonly string _title; - public Dashboard(string title) + public PanelComponent(string title) { _title = title; + SetAbsolute(); } private static void RenderTopLine(StringBuilder builder, Size size, string title) { var halfWidth = (size.Width - title.GetWidth() - (int)Indentation.BorderWidth * 2 - (int)Indentation.Default * 2) / 2; - builder.Append(Symbols.Angles.LeftTop); - builder.Append(Symbols.Lines.Horizontal.Repeat(halfWidth)); - builder.AppendFormat("{0}{1}{0}", Symbols.Space.Repeat(Convert.ToInt32(Indentation.Default)), title); - builder.Append(Symbols.Lines.Horizontal.Repeat(halfWidth)); - builder.Append(Symbols.Angles.RightTop); - builder.Append(Symbols.LineBreak); + builder.Append(Angles.LeftTop); + builder.Append(Lines.Horizontal.Repeat(halfWidth)); + builder.AppendFormat("{0}{1}{0}", Space.Repeat(Convert.ToInt32(Indentation.Default)), title); + builder.Append(Lines.Horizontal.Repeat(halfWidth)); + builder.Append(Angles.RightTop); + builder.Append(LineBreak); } private static void RenderMiddleLine(StringBuilder builder, Size size) @@ -34,10 +36,10 @@ public class Dashboard : ComponentBase, IComponent while (dashboardHeight > 0) { var bodyWidth = size.Width - (int)Indentation.BorderWidth * 2; - builder.Append(Symbols.Lines.Vertical); - builder.Append(Symbols.Space.Repeat(bodyWidth)); - builder.Append(Symbols.Lines.Vertical); - builder.Append(Symbols.LineBreak); + builder.Append(Lines.Vertical); + builder.Append(Space.Repeat(bodyWidth)); + builder.Append(Lines.Vertical); + builder.Append(LineBreak); dashboardHeight--; } @@ -46,10 +48,10 @@ public class Dashboard : ComponentBase, IComponent private static void RenderBottomLine(StringBuilder builder, Size size) { var width = size.Width - (int)Indentation.BorderWidth * 2; - builder.Append(Symbols.Angles.LeftBottom); - builder.Append(Symbols.Lines.Horizontal.Repeat(width)); - builder.Append(Symbols.Angles.RightBottom); - builder.Append(Symbols.LineBreak); + builder.Append(Angles.LeftBottom); + builder.Append(Lines.Horizontal.Repeat(width)); + builder.Append(Angles.RightBottom); + builder.Append(LineBreak); } protected override Sketch DrawComponent(Size minSize) diff --git a/src/TUI/Components/Controls/Tag.cs b/src/TUI/Controls/Components/Tag.cs similarity index 77% rename from src/TUI/Components/Controls/Tag.cs rename to src/TUI/Controls/Components/Tag.cs index 45d76e7..392064c 100644 --- a/src/TUI/Components/Controls/Tag.cs +++ b/src/TUI/Controls/Components/Tag.cs @@ -6,7 +6,7 @@ using TUI.Engine.Components; using TUI.Engine.Theme; using TUI.UserInterface; -namespace TUI.Components.Controls; +namespace TUI.Controls.Components; public class Tag : ComponentBase { @@ -25,11 +25,11 @@ public class Tag : ComponentBase tagBuilder.Append(GetGitTypeImage(_gitType)); tagBuilder.Append(Symbols.Space); - tagBuilder.Append(_tags.Have("public") ? Icons.NetworkPublic : Icons.NetworkPrivate); + tagBuilder.Append(_tags.Have("public") ? Symbols.NetworkPublic : Symbols.NetworkPrivate); tagBuilder.Append(Symbols.Space); - tagBuilder.Append(_tags.Have("seo") ? Icons.SEO : Icons.SEO.Disable()); + tagBuilder.Append(_tags.Have("seo") ? Symbols.SEO : Symbols.SEO.Disable()); tagBuilder.Append(Symbols.Space); - tagBuilder.Append(_tags.Have("auth") ? Icons.Auth : Icons.Auth.Disable()); + tagBuilder.Append(_tags.Have("auth") ? Symbols.Auth : Symbols.Auth.Disable()); tagBuilder.Append(Symbols.Space); tagBuilder.Append(GetApplicationType()); tagBuilder.Append(Symbols.Space); @@ -43,10 +43,10 @@ public class Tag : ComponentBase if (_tags.Have(application.Value)) return application.Key; - return Icons.Undefined; + return Symbols.Undefined; } - private static char GetGitTypeImage(string gitType) => + private static string GetGitTypeImage(string gitType) => gitType switch { "gitlab" => Symbols.GitLab, diff --git a/src/TUI/Controls/Components/VersionComponent.cs b/src/TUI/Controls/Components/VersionComponent.cs new file mode 100644 index 0000000..86babe3 --- /dev/null +++ b/src/TUI/Controls/Components/VersionComponent.cs @@ -0,0 +1,36 @@ +using System.Text; +using TUI.Engine; +using TUI.Engine.Attributes; +using TUI.Engine.Components; + +namespace TUI.Controls.Components; + +public class VersionComponent : ComponentBase +{ + private readonly VersionType _type; + private readonly string _version; + private readonly string? _icon; + + public VersionComponent(VersionType type, string version, string? icon = null) + { + _type = type; + _version = version; + _icon = icon; + } + + protected override Sketch DrawComponent(Size minSize) + { + var builder = new StringBuilder(); + + if (_icon is not null) + { + builder.Append(_icon.Colorized()); + builder.Append(Symbols.Space); + } + + builder.Append(_version); + var sketch = builder.ToString(); + + return new Sketch(_type.Colorize(sketch)); + } +} \ No newline at end of file diff --git a/src/TUI/Controls/Components/VersionType.cs b/src/TUI/Controls/Components/VersionType.cs new file mode 100644 index 0000000..108dc0a --- /dev/null +++ b/src/TUI/Controls/Components/VersionType.cs @@ -0,0 +1,10 @@ +namespace TUI.Controls.Components; + +public enum VersionType +{ + Convention, + ToNew, + SoGood, + BeNice, + TooOld, +} \ No newline at end of file diff --git a/src/TUI/Controls/Components/VersionTypeExtensions.cs b/src/TUI/Controls/Components/VersionTypeExtensions.cs new file mode 100644 index 0000000..3178ca7 --- /dev/null +++ b/src/TUI/Controls/Components/VersionTypeExtensions.cs @@ -0,0 +1,17 @@ +using TUI.Engine.Theme; + +namespace TUI.Controls.Components; + +public static class VersionTypeExtensions +{ + public static string Colorize(this VersionType versionType, string value) => + versionType switch + { + VersionType.TooOld => value.Warning(), + VersionType.ToNew => value.Info(), + VersionType.SoGood => value.Hint(), + VersionType.BeNice => value.Main(), + VersionType.Convention => value.Main(), + _ => value + }; +} \ No newline at end of file diff --git a/src/TUI/Controls/Containers/ContentContainer.cs b/src/TUI/Controls/Containers/ContentContainer.cs new file mode 100644 index 0000000..0eaa58a --- /dev/null +++ b/src/TUI/Controls/Containers/ContentContainer.cs @@ -0,0 +1,19 @@ +using TUI.Engine.Containers; +using TUI.Engine.Nodes; + +namespace TUI.Controls.Containers; + +public class ContentContainer : ContainerBase +{ + private readonly Nodes _children = new(); + + public void AddChildren(INode node) + { + _children.Add(node); + } + + public override Nodes GetNodes() + { + return _children; + } +} \ No newline at end of file diff --git a/src/TUI/Controls/Containers/DashboardContainer.cs b/src/TUI/Controls/Containers/DashboardContainer.cs new file mode 100644 index 0000000..ac27e73 --- /dev/null +++ b/src/TUI/Controls/Containers/DashboardContainer.cs @@ -0,0 +1,31 @@ +using TUI.Controls.Components; +using TUI.Engine.Attributes.Orientations; +using TUI.Engine.Containers; +using TUI.Engine.Nodes; + +namespace TUI.Controls.Containers; + +public class DashboardContainer : ContainerBase +{ + private readonly Nodes _children = new(); + private readonly ContentContainer _content; + + public DashboardContainer() + { + var panel = new PanelComponent("Dependencies"); + _content = new ContentContainer(); + _content.SetOrientationVertical(); + SetOrientationVertical(); + + _children.Add(panel); + _children.Add(_content); + } + + public void AddChildren(IContainer node) + { + node.SetFixed(Orientation.Vertical, 1); + _content.AddChildren(node); + } + + public override Nodes GetNodes() => _children; +} \ No newline at end of file diff --git a/src/TUI/Controls/Containers/DependencyContainer.cs b/src/TUI/Controls/Containers/DependencyContainer.cs new file mode 100644 index 0000000..22569c7 --- /dev/null +++ b/src/TUI/Controls/Containers/DependencyContainer.cs @@ -0,0 +1,29 @@ +using TUI.Controls.Common; +using TUI.Controls.Components; +using TUI.Engine; +using TUI.Engine.Attributes; +using TUI.Engine.Attributes.Alignments; +using TUI.Engine.Attributes.Orientations; +using TUI.Engine.Containers; +using TUI.Engine.Nodes; +using TUI.Engine.Theme; + +namespace TUI.Controls.Containers; + +public class DependencyContainer : ContainerBase +{ + private const int VersionColumnWidth = 10; + + public override Nodes GetNodes() + { + var stub = new StubComponent(new Size(20, 1)); + stub.SetPadding(Level.Normal); + + var version = new VersionComponent(VersionType.Convention, "10.20.30", Symbols.Site); + version.SetPadding(Level.Normal); + version.SetAlignment(Horizontal.Right); + version.SetFixed(Orientation.Horizontal, VersionColumnWidth); + + return new Nodes { stub, version, version, }; + } +} \ No newline at end of file diff --git a/src/TUI/Components/Controls/HeaderContainer.cs b/src/TUI/Controls/Containers/HeaderContainer.cs similarity index 88% rename from src/TUI/Components/Controls/HeaderContainer.cs rename to src/TUI/Controls/Containers/HeaderContainer.cs index cb8ceee..4090a80 100644 --- a/src/TUI/Components/Controls/HeaderContainer.cs +++ b/src/TUI/Controls/Containers/HeaderContainer.cs @@ -1,11 +1,11 @@ -using TUI.Components.Controls.Statics; -using TUI.Components.Controls.Statics.Hints; +using TUI.Controls.Statics; +using TUI.Controls.Statics.Hints; using TUI.Engine.Attributes.Alignments; using TUI.Engine.Containers; using TUI.Engine.Nodes; using TUI.Engine.Theme; -namespace TUI.Components.Controls; +namespace TUI.Controls.Containers; public class HeaderContainer : ContainerBase, IContainer { @@ -27,7 +27,7 @@ public class HeaderContainer : ContainerBase, IContainer hotkeysHints.SetPadding(Indentation.Default); hotkeysHints.SetAlignment(Horizontal.Left); - var logo = new Logo(); + var logo = new LogoComponent(); logo.SetAlignment(Horizontal.Right); logo.SetPaddingLeft(Indentation.Default); logo.SetPaddingBottom(Indentation.Default); diff --git a/src/TUI/Components/Layouts/DashboardLayout.cs b/src/TUI/Controls/Layouts/DashboardLayout.cs similarity index 66% rename from src/TUI/Components/Layouts/DashboardLayout.cs rename to src/TUI/Controls/Layouts/DashboardLayout.cs index fefa559..9efb3a7 100644 --- a/src/TUI/Components/Layouts/DashboardLayout.cs +++ b/src/TUI/Controls/Layouts/DashboardLayout.cs @@ -5,49 +5,34 @@ using TUI.Engine.Containers; using TUI.Engine.Nodes; using TUI.Engine.Theme; -namespace TUI.Components.Layouts; +namespace TUI.Controls.Layouts; public class DashboardLayout : ContainerBase, IContainer { - public DashboardLayout() + private readonly INode _header; + private readonly INode _footer; + private readonly INode _dashboard; + + public DashboardLayout(INode header, INode dashboard, IComponent footer) { SetOrientationVertical(); SetAdaptive(Orientation.Horizontal); SetAdaptive(Orientation.Vertical); - } - private INode _header; - private INode _footer; - private INode _dashboard; + header.SetFixed(Orientation.Vertical, 6); + footer.SetFixed(Orientation.Vertical, 1); + footer.SetPaddingRight(Level.Normal); + footer.SetAlignment(Horizontal.Right); + footer.SetAlignment(Vertical.Bottom); + + _header = header; + _footer = footer; + _dashboard = dashboard; + } public override Nodes GetNodes() => new() { _header, _dashboard, _footer }; - - public void AddDashboard(IComponent dashboard) - { - _dashboard = dashboard; - } - - public void AddHeader(IContainer header) - { - header.SetFixed(Orientation.Vertical, 6); - _header = header; - } - - public void AddFooter(IComponent footer) - { - footer.SetFixed(Orientation.Vertical, 1); - footer.SetPaddingRight(Level.Normal); - footer.SetAlignment(Horizontal.Right); - footer.SetAlignment(Vertical.Bottom); - _footer = footer; - } - - public string Render() - { - throw new NotImplementedException(); - } } \ No newline at end of file diff --git a/src/TUI/Components/Controls/Copyright.cs b/src/TUI/Controls/Statics/CopyrightComponent.cs similarity index 62% rename from src/TUI/Components/Controls/Copyright.cs rename to src/TUI/Controls/Statics/CopyrightComponent.cs index eaf419e..5e6be7f 100644 --- a/src/TUI/Components/Controls/Copyright.cs +++ b/src/TUI/Controls/Statics/CopyrightComponent.cs @@ -3,16 +3,16 @@ using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -namespace TUI.Components.Controls; +namespace TUI.Controls.Statics; -public class Copyright : StaticComponentBase +public class CopyrightComponent : StaticComponentBase { protected override void RenderWithCache(StringBuilder builder) { - builder.Append(Symbols.Copyright); + builder.Append(Symbols.Copyright.Info()); builder.Append(Symbols.Space); builder.Append("Kolosov A. aka \"dnwSilver\"".Hint()); builder.Append(Symbols.Space); - builder.Append(DateTime.Now.Year); + builder.Append(DateTime.Now.Year.Info()); } } diff --git a/src/TUI/Components/Controls/Statics/Hints/AppTypeHints.cs b/src/TUI/Controls/Statics/Hints/AppTypeHints.cs similarity index 69% rename from src/TUI/Components/Controls/Statics/Hints/AppTypeHints.cs rename to src/TUI/Controls/Statics/Hints/AppTypeHints.cs index 2f7d959..ee432b2 100644 --- a/src/TUI/Components/Controls/Statics/Hints/AppTypeHints.cs +++ b/src/TUI/Controls/Statics/Hints/AppTypeHints.cs @@ -2,18 +2,17 @@ using System.Text; using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -using TUI.UserInterface; -namespace TUI.Components.Controls.Statics.Hints; +namespace TUI.Controls.Statics.Hints; public class AppTypeHints : StaticComponentBase { private readonly Dictionary _hints = new() { - { Icons.NpmPackage, "package" }, - { Icons.DockerImage, "image" }, - { Icons.Site, "site" }, - { Icons.Api, "api" } + { Symbols.NpmPackage, "package" }, + { Symbols.DockerImage, "image" }, + { Symbols.Site, "site" }, + { Symbols.Api, "api" } }; protected override void RenderWithCache(StringBuilder builder) diff --git a/src/TUI/Components/Controls/Statics/Hints/HotkeysHint.cs b/src/TUI/Controls/Statics/Hints/HotkeysHint.cs similarity index 92% rename from src/TUI/Components/Controls/Statics/Hints/HotkeysHint.cs rename to src/TUI/Controls/Statics/Hints/HotkeysHint.cs index 12c80ba..a6ca871 100644 --- a/src/TUI/Components/Controls/Statics/Hints/HotkeysHint.cs +++ b/src/TUI/Controls/Statics/Hints/HotkeysHint.cs @@ -3,7 +3,7 @@ using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -namespace TUI.Components.Controls.Statics.Hints; +namespace TUI.Controls.Statics.Hints; public class HotkeysHint : StaticComponentBase { diff --git a/src/TUI/Components/Controls/Statics/Hints/TagHints.cs b/src/TUI/Controls/Statics/Hints/TagHints.cs similarity index 69% rename from src/TUI/Components/Controls/Statics/Hints/TagHints.cs rename to src/TUI/Controls/Statics/Hints/TagHints.cs index 766f52f..912c605 100644 --- a/src/TUI/Components/Controls/Statics/Hints/TagHints.cs +++ b/src/TUI/Controls/Statics/Hints/TagHints.cs @@ -2,18 +2,17 @@ using System.Text; using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -using TUI.UserInterface; -namespace TUI.Components.Controls.Statics.Hints; +namespace TUI.Controls.Statics.Hints; public class TagHints : StaticComponentBase { private readonly Dictionary _hints = new() { - { Icons.Auth, "Auth" }, - { Icons.NetworkPublic, "WWW" }, - { Icons.SEO, "SEO" }, - { Icons.GitLab, "VCS" } + { Symbols.Auth, "Auth" }, + { Symbols.NetworkPublic, "WWW" }, + { Symbols.SEO, "SEO" }, + { Symbols.Git, "VCS" } }; protected override void RenderWithCache(StringBuilder builder) diff --git a/src/TUI/Components/Controls/Statics/Hints/VersionHints.cs b/src/TUI/Controls/Statics/Hints/VersionHints.cs similarity index 61% rename from src/TUI/Components/Controls/Statics/Hints/VersionHints.cs rename to src/TUI/Controls/Statics/Hints/VersionHints.cs index ee49809..1a41614 100644 --- a/src/TUI/Components/Controls/Statics/Hints/VersionHints.cs +++ b/src/TUI/Controls/Statics/Hints/VersionHints.cs @@ -1,18 +1,19 @@ using System.Text; +using TUI.Controls.Components; using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -namespace TUI.Components.Controls.Statics.Hints; +namespace TUI.Controls.Statics.Hints; public class VersionHints : StaticComponentBase { private readonly Dictionary _hints = new() { - { "󰎔", "too new".Info() }, - { "", "so good".Hint() }, - { "", "be nice".Main() }, - { "󰬟", "too old".Warning() } + { "󰎔", VersionType.ToNew.Colorize("too new") }, + { "", VersionType.SoGood.Colorize("so good") }, + { "", VersionType.BeNice.Colorize("be nice") }, + { "󰬟", VersionType.TooOld.Colorize("too old") } }; protected override void RenderWithCache(StringBuilder builder) diff --git a/src/TUI/Components/Controls/Statics/Logo.cs b/src/TUI/Controls/Statics/LogoComponent.cs similarity index 92% rename from src/TUI/Components/Controls/Statics/Logo.cs rename to src/TUI/Controls/Statics/LogoComponent.cs index bed96db..6f58008 100644 --- a/src/TUI/Components/Controls/Statics/Logo.cs +++ b/src/TUI/Controls/Statics/LogoComponent.cs @@ -3,9 +3,9 @@ using TUI.Engine; using TUI.Engine.Components; using TUI.Engine.Theme; -namespace TUI.Components.Controls.Statics; +namespace TUI.Controls.Statics; -public class Logo : StaticComponentBase +public class LogoComponent : StaticComponentBase { protected override void RenderWithCache(StringBuilder builder) { diff --git a/src/TUI/Domain/NewFile1.txt b/src/TUI/Domain/NewFile1.txt index 9f63c19..e9fb9e2 100644 --- a/src/TUI/Domain/NewFile1.txt +++ b/src/TUI/Domain/NewFile1.txt @@ -2,7 +2,7 @@ 󰘳 1 󱓟 releases  select prev 󰘳 2 󰧑 competencies  select next 󰘳 3  dependencies 󰬌 toggle head - 󰘳 4 󰬘 quit + 󰘳 4 󰬘 quit 󰎔 too new  Auth  package  so good 󰞉 WWW 󰡨 image diff --git a/src/TUI/Pages/DependenciesPage.cs b/src/TUI/Pages/DependenciesPage.cs index 164d5e1..f9956e3 100644 --- a/src/TUI/Pages/DependenciesPage.cs +++ b/src/TUI/Pages/DependenciesPage.cs @@ -1,6 +1,7 @@ using System.Diagnostics; -using TUI.Components.Controls; -using TUI.Components.Layouts; +using TUI.Controls.Containers; +using TUI.Controls.Layouts; +using TUI.Controls.Statics; using TUI.Engine.Rendering.Canvas; namespace TUI.Pages; @@ -14,12 +15,14 @@ public class DependenciesPage ICanvas canvas = new ConsoleCanvas(); var header = new HeaderContainer(); - var copyright = new Copyright(); - var dashboard = new Dashboard("Dependencies"); - var layout = new DashboardLayout(); - layout.AddHeader(header); - layout.AddFooter(copyright); - layout.AddDashboard(dashboard); + var copyright = new CopyrightComponent(); + var dashboard = new DashboardContainer(); + var layout = new DashboardLayout(header, dashboard, copyright); + var dependency = new DependencyContainer(); + dashboard.AddChildren(dependency); + dashboard.AddChildren(dependency); + dashboard.AddChildren(dependency); + dashboard.AddChildren(dependency); // CommandLine = new CommandLine(); // DependenciesView = new DependenciesView(); diff --git a/src/TUI/TUI.csproj b/src/TUI/TUI.csproj index ee7b7f3..1250cb0 100644 --- a/src/TUI/TUI.csproj +++ b/src/TUI/TUI.csproj @@ -20,7 +20,15 @@ - + + <_Parameter1>$(MSBuildProjectName).Tests + + + <_Parameter1>$(MSBuildProjectName).Controls.Tests + + + + diff --git a/src/TUI/UserInterface/Icons.cs b/src/TUI/UserInterface/Icons.cs index b86cc29..63ceaea 100644 --- a/src/TUI/UserInterface/Icons.cs +++ b/src/TUI/UserInterface/Icons.cs @@ -1,35 +1,15 @@ -using Pastel; -using TUI.Engine.Theme; +using TUI.Engine; namespace TUI.UserInterface; public static class Icons { - public readonly static Dictionary Applications = new() + public static readonly Dictionary Applications = new() { - { NpmPackage, "package" }, - { DockerImage, "image" }, - { Site, "site" }, - { Api, "api" } + { Symbols.NpmPackage, "package" }, + { Symbols.DockerImage, "image" }, + { Symbols.Site, "site" }, + { Symbols.Api, "api" } }; - - public static string GitLab => GetIcon("", "E24329"); - public static string GitHub => GetIcon("", "ADBAC7"); - public static string Git => GetIcon("", "F14E32"); - public static string NetworkPublic => GetIcon("󰞉", "00FFFF"); - public static string NetworkPrivate => GetIcon("󰕑"); - public static string Undefined => GetIcon(""); - public static string Site => GetIcon("", "BF40BF"); - public static string Api => GetIcon("", "7F52FF"); - public static string DockerImage => GetIcon("󰡨", "086DD7"); - public static string NpmPackage => GetIcon("", "CB0000"); - public static string SEO => GetIcon("󰚩", "4285F4"); - public static string Auth => GetIcon("", "FFD700"); - public static string NotFound => GetIcon(""); - - private static string GetIcon(string icon, string? activeColor = null) - { - return activeColor != null ? icon.Pastel(activeColor) : icon.Hint(); - } } \ No newline at end of file diff --git a/tests/TUI.Controls.Tests/TUI.Controls.Tests.csproj b/tests/TUI.Controls.Tests/TUI.Controls.Tests.csproj new file mode 100644 index 0000000..de51f70 --- /dev/null +++ b/tests/TUI.Controls.Tests/TUI.Controls.Tests.csproj @@ -0,0 +1,33 @@ + + + + net7.0 + enable + enable + + false + true + TUI.Engine.Tests + TUI.Engine.Tests + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/tests/TUI.Controls.Tests/Usings.cs b/tests/TUI.Controls.Tests/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/tests/TUI.Controls.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/tests/TUI.Controls.Tests/VersionComponentTests.cs b/tests/TUI.Controls.Tests/VersionComponentTests.cs new file mode 100644 index 0000000..5822173 --- /dev/null +++ b/tests/TUI.Controls.Tests/VersionComponentTests.cs @@ -0,0 +1,26 @@ +using FluentAssertions; +using TUI.Controls.Components; +using TUI.Engine.Attributes; +using TUI.Engine.Components; + +namespace TUI.Engine.Tests +{ + public class VersionComponentTests + { + [Theory] + [Trait("Category", nameof(Sketch))] + [InlineData(VersionType.Convention, "\u001b[38;2;132;186;100m10.12.33\u001b[0m")] + [InlineData(VersionType.BeNice, "\u001b[38;2;132;186;100m10.12.33\u001b[0m")] + [InlineData(VersionType.SoGood, "\u001b[38;2;113;121;126m10.12.33\u001b[0m")] + [InlineData(VersionType.ToNew, "\u001b[38;2;37;121;159m10.12.33\u001b[0m")] + [InlineData(VersionType.TooOld, "\u001b[38;2;236;151;6m10.12.33\u001b[0m")] + public void DrawSketchVersionTypes(VersionType versionType, string expected) + { + var version = new VersionComponent(versionType, "10.12.33"); + + var sketch = (version as IComponent).MakeSketch(new Size(10, 2)); + + sketch.ToString().Should().Be(expected); + } + } +} \ No newline at end of file diff --git a/tests/TUI.Engine.Tests/Draw/DrawStaticTests.cs b/tests/TUI.Engine.Tests/Draw/DrawStaticTests.cs new file mode 100644 index 0000000..93a6222 --- /dev/null +++ b/tests/TUI.Engine.Tests/Draw/DrawStaticTests.cs @@ -0,0 +1,38 @@ +using Moq; +using TUI.Engine.Attributes; +using TUI.Engine.Nodes; +using TUI.Engine.Rendering; +using TUI.Engine.Rendering.Canvas; +using TUI.Engine.Tests.Stubs; + +namespace TUI.Engine.Tests.Draw; + +public class DrawStaticTests : ComponentBaseTests +{ + [Fact] + [Trait("Category", nameof(IDrawable.Draw))] + public void DrawStaticComponentVerticalOrientation() + { + var canvas = Mock.Of(w => w.Size == new Size(6, 4)); + + var firstComponent = Prepare.Component(); + firstComponent.SetContent("First"); + firstComponent.SetRelative(); + var secondComponent = Prepare.Component(); + secondComponent.SetContent("Second"); + secondComponent.SetAbsolute(); + var thirdComponent = Prepare.Component(); + thirdComponent.SetContent("Third"); + + var root = Prepare.Container(firstComponent, secondComponent, thirdComponent); + root.SetOrientationVertical(); + + Craftsman(canvas).Draw(root, Position.Default, canvas.Size); + + Mock.Get(canvas).VerifyPositionOnce(Position.Default); + Mock.Get(canvas).VerifyPositionTimes(0, 2, 2); + Mock.Get(canvas).Verify(w => w.Paint("First"), Times.Once()); + Mock.Get(canvas).Verify(w => w.Paint("Second"), Times.Once()); + Mock.Get(canvas).Verify(w => w.Paint("Third"), Times.Once()); + } +} \ No newline at end of file diff --git a/tests/TUI.Engine.Tests/MockExtensions.cs b/tests/TUI.Engine.Tests/MockExtensions.cs index 3322533..f430f49 100644 --- a/tests/TUI.Engine.Tests/MockExtensions.cs +++ b/tests/TUI.Engine.Tests/MockExtensions.cs @@ -10,6 +10,10 @@ public static class MockExtensions { mock.Verify(w => w.SetPencil(new Position(left, top)), Times.Exactly(1)); } + public static void VerifyPositionTimes(this Mock mock, int left, int top, int times) where T : class, ICanvas + { + mock.Verify(w => w.SetPencil(new Position(left, top)), Times.Exactly(times)); + } public static void VerifyPositionOnce(this Mock mock, Position position) where T : class, ICanvas { diff --git a/tests/TUI.Engine.Tests/Primitives/IntegerTests.cs b/tests/TUI.Engine.Tests/Primitives/IntegerTests.cs index ed6d113..57a6e8c 100644 --- a/tests/TUI.Engine.Tests/Primitives/IntegerTests.cs +++ b/tests/TUI.Engine.Tests/Primitives/IntegerTests.cs @@ -1,6 +1,6 @@ using FluentAssertions; -namespace TUI.Engine.Tests.Draw; +namespace TUI.Engine.Tests.Primitives; public class IntegerTests {