Version components create.

This commit is contained in:
Kolosov Alexandr 2024-03-18 00:57:31 +05:00
parent 268c25e604
commit 99fe793c16
38 changed files with 482 additions and 143 deletions

View File

@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Engine.Tests", "tests\T
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Engine", "src\TUI.Engine\TUI.Engine.csproj", "{38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUI.Engine", "src\TUI.Engine\TUI.Engine.csproj", "{38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{38E7E2DD-40C1-4B7C-9A7A-E3677AD55431}.Release|Any CPU.Build.0 = 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 EndGlobalSection
EndGlobal EndGlobal

View File

@ -18,13 +18,15 @@ internal static class ResizingExtensions
} }
var fixedNodes = container.GetFixedNodes().ToArray(); var fixedNodes = container.GetFixedNodes().ToArray();
var absoluteNodes = container.GetAbsoluteNodes().ToArray();
var fixedHeight = fixedNodes.Sum(s => s.GetFixedSize().Height); var fixedHeight = fixedNodes.Sum(s => s.GetFixedSize().Height);
var allowableHeight = maxHeight - fixedHeight; 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 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) if (allowableHeight - nodeNumber * nodeHeight < nodeHeight)
{ {

View File

@ -10,6 +10,18 @@ public abstract class ComponentBase : NodeBase, IComponent
{ {
protected abstract Sketch DrawComponent(Size minSize); 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); Sketch IComponent.MakeSketch(Size minSize) => DrawComponent(minSize);
#region Alignments #region Alignments

View File

@ -7,5 +7,11 @@ namespace TUI.Engine.Components;
public interface IComponent : INode, IWithAlignment, IWithPadding public interface IComponent : INode, IWithAlignment, IWithPadding
{ {
internal bool IsRelative { get; }
public void SetRelative();
public void SetAbsolute();
internal Sketch MakeSketch(Size minSize); internal Sketch MakeSketch(Size minSize);
} }

View File

@ -1,10 +1,30 @@
using TUI.Engine.Attributes.Resizings; using TUI.Engine.Attributes.Resizings;
using TUI.Engine.Components;
using TUI.Engine.Nodes; using TUI.Engine.Nodes;
namespace TUI.Engine.Containers; namespace TUI.Engine.Containers;
internal static class ContainerExtensions internal static class ContainerExtensions
{ {
private static readonly Func<INode, bool> AbsoluteNodes = node => node is IComponent { IsRelative: false };
private static readonly Func<INode, bool> FixedNodes = node => node.ResizingVertical == Resizing.Fixed;
internal static IEnumerable<INode> 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<INode> GetFixedNodes(this IContainer container, int? takeNodeNumber = null) internal static IEnumerable<INode> GetFixedNodes(this IContainer container, int? takeNodeNumber = null)
{ {
if (takeNodeNumber is not null) if (takeNodeNumber is not null)
@ -12,11 +32,11 @@ internal static class ContainerExtensions
return container return container
.GetNodes() .GetNodes()
.Take(takeNodeNumber.Value + 1) .Take(takeNodeNumber.Value + 1)
.Where(n => n.ResizingVertical == Resizing.Fixed); .Where(FixedNodes);
} }
return container return container
.GetNodes() .GetNodes()
.Where(n => n.ResizingVertical == Resizing.Fixed); .Where(FixedNodes);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Globalization; using System.Globalization;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace TUI.Engine; namespace TUI.Engine;
@ -20,9 +21,9 @@ public static class Extensions
return array.Any(item => item == findValue); 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) public static string RemoveColors(this string text)

View File

@ -45,7 +45,9 @@ internal sealed class ContainerCraftsman : CraftsmanBase, IDrawable<IContainer>
return GetNextNodePosition(container, containerSize, nodePosition); return GetNextNodePosition(container, containerSize, nodePosition);
case IComponent childComponent: case IComponent childComponent:
var componentSize = _componentCraftsman.Draw(childComponent, nodePosition, maxSize); var componentSize = _componentCraftsman.Draw(childComponent, nodePosition, maxSize);
return GetNextNodePosition(container, maxSize, nodePosition, componentSize); return childComponent.IsRelative
? GetNextNodePosition(container, maxSize, nodePosition, componentSize)
: nodePosition;
default: default:
throw new InvalidCastException(); throw new InvalidCastException();
} }

View File

@ -1,25 +1,58 @@
using Pastel;
using TUI.Engine.Theme;
namespace TUI.Engine; namespace TUI.Engine;
public static class Symbols public static class Symbols
{ {
public const char Space = ' '; public const string Space = " ";
public const char Copyright = '©'; public const string Copyright = "©";
public const char GitLab = ''; public const string GitLab = "";
public const char GitHub = ''; public const string GitHub = "";
public const char Git = ''; public const string Git = "";
public const char LineBreak = '\n'; 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 static class Lines
{ {
public const char Vertical = '│'; public const string Vertical = "│";
public const char Horizontal = '─'; public const string Horizontal = "─";
} }
public static class Angles public static class Angles
{ {
public const char RightTop = '┐'; public const string RightTop = "┐";
public const char LeftBottom = '└'; public const string LeftBottom = "└";
public const char LeftTop = '┌'; public const string LeftTop = "┌";
public const char RightBottom = '┘'; 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<string, string> 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" },
};
}

View File

@ -12,9 +12,6 @@
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Tests</_Parameter1> <_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
</AssemblyAttribute> </AssemblyAttribute>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Other.Assembly.Name</_Parameter1>
</AssemblyAttribute>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -18,6 +18,8 @@ public static class Palette
public static string Hint(this string currentText) => currentText.Pastel(HintColor); 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 Disable(this string currentText) => currentText.RemoveColors().Pastel(HintColor);
public static string Warning(this string currentText) => currentText.Pastel(WarningColor); 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 Error(this string currentText) => currentText.Pastel(ErrorColor);
public static string Info(this string currentText) => currentText.Pastel(InfoColor); 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);
} }

View File

@ -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());
}
}

View File

@ -4,7 +4,7 @@ using TUI.Engine.Attributes;
using TUI.Engine.Attributes.Alignments; using TUI.Engine.Attributes.Alignments;
using TUI.Engine.Components; using TUI.Engine.Components;
namespace TUI.Components.Controls; namespace TUI.Controls.Components;
public class CellsComponentBase : ComponentBase, IComponent public class CellsComponentBase : ComponentBase, IComponent
{ {

View File

@ -3,28 +3,30 @@ using TUI.Engine;
using TUI.Engine.Attributes; using TUI.Engine.Attributes;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; 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; private readonly string _title;
public Dashboard(string title) public PanelComponent(string title)
{ {
_title = title; _title = title;
SetAbsolute();
} }
private static void RenderTopLine(StringBuilder builder, Size size, string title) private static void RenderTopLine(StringBuilder builder, Size size, string title)
{ {
var halfWidth = (size.Width - title.GetWidth() - (int)Indentation.BorderWidth * 2 - var halfWidth = (size.Width - title.GetWidth() - (int)Indentation.BorderWidth * 2 -
(int)Indentation.Default * 2) / 2; (int)Indentation.Default * 2) / 2;
builder.Append(Symbols.Angles.LeftTop); builder.Append(Angles.LeftTop);
builder.Append(Symbols.Lines.Horizontal.Repeat(halfWidth)); builder.Append(Lines.Horizontal.Repeat(halfWidth));
builder.AppendFormat("{0}{1}{0}", Symbols.Space.Repeat(Convert.ToInt32(Indentation.Default)), title); builder.AppendFormat("{0}{1}{0}", Space.Repeat(Convert.ToInt32(Indentation.Default)), title);
builder.Append(Symbols.Lines.Horizontal.Repeat(halfWidth)); builder.Append(Lines.Horizontal.Repeat(halfWidth));
builder.Append(Symbols.Angles.RightTop); builder.Append(Angles.RightTop);
builder.Append(Symbols.LineBreak); builder.Append(LineBreak);
} }
private static void RenderMiddleLine(StringBuilder builder, Size size) private static void RenderMiddleLine(StringBuilder builder, Size size)
@ -34,10 +36,10 @@ public class Dashboard : ComponentBase, IComponent
while (dashboardHeight > 0) while (dashboardHeight > 0)
{ {
var bodyWidth = size.Width - (int)Indentation.BorderWidth * 2; var bodyWidth = size.Width - (int)Indentation.BorderWidth * 2;
builder.Append(Symbols.Lines.Vertical); builder.Append(Lines.Vertical);
builder.Append(Symbols.Space.Repeat(bodyWidth)); builder.Append(Space.Repeat(bodyWidth));
builder.Append(Symbols.Lines.Vertical); builder.Append(Lines.Vertical);
builder.Append(Symbols.LineBreak); builder.Append(LineBreak);
dashboardHeight--; dashboardHeight--;
} }
@ -46,10 +48,10 @@ public class Dashboard : ComponentBase, IComponent
private static void RenderBottomLine(StringBuilder builder, Size size) private static void RenderBottomLine(StringBuilder builder, Size size)
{ {
var width = size.Width - (int)Indentation.BorderWidth * 2; var width = size.Width - (int)Indentation.BorderWidth * 2;
builder.Append(Symbols.Angles.LeftBottom); builder.Append(Angles.LeftBottom);
builder.Append(Symbols.Lines.Horizontal.Repeat(width)); builder.Append(Lines.Horizontal.Repeat(width));
builder.Append(Symbols.Angles.RightBottom); builder.Append(Angles.RightBottom);
builder.Append(Symbols.LineBreak); builder.Append(LineBreak);
} }
protected override Sketch DrawComponent(Size minSize) protected override Sketch DrawComponent(Size minSize)

View File

@ -6,7 +6,7 @@ using TUI.Engine.Components;
using TUI.Engine.Theme; using TUI.Engine.Theme;
using TUI.UserInterface; using TUI.UserInterface;
namespace TUI.Components.Controls; namespace TUI.Controls.Components;
public class Tag : ComponentBase public class Tag : ComponentBase
{ {
@ -25,11 +25,11 @@ public class Tag : ComponentBase
tagBuilder.Append(GetGitTypeImage(_gitType)); tagBuilder.Append(GetGitTypeImage(_gitType));
tagBuilder.Append(Symbols.Space); 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(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(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(Symbols.Space);
tagBuilder.Append(GetApplicationType()); tagBuilder.Append(GetApplicationType());
tagBuilder.Append(Symbols.Space); tagBuilder.Append(Symbols.Space);
@ -43,10 +43,10 @@ public class Tag : ComponentBase
if (_tags.Have(application.Value)) if (_tags.Have(application.Value))
return application.Key; return application.Key;
return Icons.Undefined; return Symbols.Undefined;
} }
private static char GetGitTypeImage(string gitType) => private static string GetGitTypeImage(string gitType) =>
gitType switch gitType switch
{ {
"gitlab" => Symbols.GitLab, "gitlab" => Symbols.GitLab,

View File

@ -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));
}
}

View File

@ -0,0 +1,10 @@
namespace TUI.Controls.Components;
public enum VersionType
{
Convention,
ToNew,
SoGood,
BeNice,
TooOld,
}

View File

@ -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
};
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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, };
}
}

View File

@ -1,11 +1,11 @@
using TUI.Components.Controls.Statics; using TUI.Controls.Statics;
using TUI.Components.Controls.Statics.Hints; using TUI.Controls.Statics.Hints;
using TUI.Engine.Attributes.Alignments; using TUI.Engine.Attributes.Alignments;
using TUI.Engine.Containers; using TUI.Engine.Containers;
using TUI.Engine.Nodes; using TUI.Engine.Nodes;
using TUI.Engine.Theme; using TUI.Engine.Theme;
namespace TUI.Components.Controls; namespace TUI.Controls.Containers;
public class HeaderContainer : ContainerBase, IContainer public class HeaderContainer : ContainerBase, IContainer
{ {
@ -27,7 +27,7 @@ public class HeaderContainer : ContainerBase, IContainer
hotkeysHints.SetPadding(Indentation.Default); hotkeysHints.SetPadding(Indentation.Default);
hotkeysHints.SetAlignment(Horizontal.Left); hotkeysHints.SetAlignment(Horizontal.Left);
var logo = new Logo(); var logo = new LogoComponent();
logo.SetAlignment(Horizontal.Right); logo.SetAlignment(Horizontal.Right);
logo.SetPaddingLeft(Indentation.Default); logo.SetPaddingLeft(Indentation.Default);
logo.SetPaddingBottom(Indentation.Default); logo.SetPaddingBottom(Indentation.Default);

View File

@ -5,49 +5,34 @@ using TUI.Engine.Containers;
using TUI.Engine.Nodes; using TUI.Engine.Nodes;
using TUI.Engine.Theme; using TUI.Engine.Theme;
namespace TUI.Components.Layouts; namespace TUI.Controls.Layouts;
public class DashboardLayout : ContainerBase, IContainer 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(); SetOrientationVertical();
SetAdaptive(Orientation.Horizontal); SetAdaptive(Orientation.Horizontal);
SetAdaptive(Orientation.Vertical); SetAdaptive(Orientation.Vertical);
}
private INode _header; header.SetFixed(Orientation.Vertical, 6);
private INode _footer; footer.SetFixed(Orientation.Vertical, 1);
private INode _dashboard; footer.SetPaddingRight(Level.Normal);
footer.SetAlignment(Horizontal.Right);
footer.SetAlignment(Vertical.Bottom);
_header = header;
_footer = footer;
_dashboard = dashboard;
}
public override Nodes GetNodes() => public override Nodes GetNodes() =>
new() new()
{ {
_header, _dashboard, _footer _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();
}
} }

View File

@ -3,16 +3,16 @@ using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; 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) protected override void RenderWithCache(StringBuilder builder)
{ {
builder.Append(Symbols.Copyright); builder.Append(Symbols.Copyright.Info());
builder.Append(Symbols.Space); builder.Append(Symbols.Space);
builder.Append("Kolosov A. aka \"dnwSilver\"".Hint()); builder.Append("Kolosov A. aka \"dnwSilver\"".Hint());
builder.Append(Symbols.Space); builder.Append(Symbols.Space);
builder.Append(DateTime.Now.Year); builder.Append(DateTime.Now.Year.Info());
} }
} }

View File

@ -2,18 +2,17 @@ using System.Text;
using TUI.Engine; using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; using TUI.Engine.Theme;
using TUI.UserInterface;
namespace TUI.Components.Controls.Statics.Hints; namespace TUI.Controls.Statics.Hints;
public class AppTypeHints : StaticComponentBase public class AppTypeHints : StaticComponentBase
{ {
private readonly Dictionary<string, string> _hints = new() private readonly Dictionary<string, string> _hints = new()
{ {
{ Icons.NpmPackage, "package" }, { Symbols.NpmPackage, "package" },
{ Icons.DockerImage, "image" }, { Symbols.DockerImage, "image" },
{ Icons.Site, "site" }, { Symbols.Site, "site" },
{ Icons.Api, "api" } { Symbols.Api, "api" }
}; };
protected override void RenderWithCache(StringBuilder builder) protected override void RenderWithCache(StringBuilder builder)

View File

@ -3,7 +3,7 @@ using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; using TUI.Engine.Theme;
namespace TUI.Components.Controls.Statics.Hints; namespace TUI.Controls.Statics.Hints;
public class HotkeysHint : StaticComponentBase public class HotkeysHint : StaticComponentBase
{ {

View File

@ -2,18 +2,17 @@ using System.Text;
using TUI.Engine; using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; using TUI.Engine.Theme;
using TUI.UserInterface;
namespace TUI.Components.Controls.Statics.Hints; namespace TUI.Controls.Statics.Hints;
public class TagHints : StaticComponentBase public class TagHints : StaticComponentBase
{ {
private readonly Dictionary<string, string> _hints = new() private readonly Dictionary<string, string> _hints = new()
{ {
{ Icons.Auth, "Auth" }, { Symbols.Auth, "Auth" },
{ Icons.NetworkPublic, "WWW" }, { Symbols.NetworkPublic, "WWW" },
{ Icons.SEO, "SEO" }, { Symbols.SEO, "SEO" },
{ Icons.GitLab, "VCS" } { Symbols.Git, "VCS" }
}; };
protected override void RenderWithCache(StringBuilder builder) protected override void RenderWithCache(StringBuilder builder)

View File

@ -1,18 +1,19 @@
using System.Text; using System.Text;
using TUI.Controls.Components;
using TUI.Engine; using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; using TUI.Engine.Theme;
namespace TUI.Components.Controls.Statics.Hints; namespace TUI.Controls.Statics.Hints;
public class VersionHints : StaticComponentBase public class VersionHints : StaticComponentBase
{ {
private readonly Dictionary<string, string> _hints = new() private readonly Dictionary<string, string> _hints = new()
{ {
{ "󰎔", "too new".Info() }, { "󰎔", VersionType.ToNew.Colorize("too new") },
{ "", "so good".Hint() }, { "", VersionType.SoGood.Colorize("so good") },
{ "", "be nice".Main() }, { "", VersionType.BeNice.Colorize("be nice") },
{ "󰬟", "too old".Warning() } { "󰬟", VersionType.TooOld.Colorize("too old") }
}; };
protected override void RenderWithCache(StringBuilder builder) protected override void RenderWithCache(StringBuilder builder)

View File

@ -3,9 +3,9 @@ using TUI.Engine;
using TUI.Engine.Components; using TUI.Engine.Components;
using TUI.Engine.Theme; 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) protected override void RenderWithCache(StringBuilder builder)
{ {

View File

@ -1,6 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using TUI.Components.Controls; using TUI.Controls.Containers;
using TUI.Components.Layouts; using TUI.Controls.Layouts;
using TUI.Controls.Statics;
using TUI.Engine.Rendering.Canvas; using TUI.Engine.Rendering.Canvas;
namespace TUI.Pages; namespace TUI.Pages;
@ -14,12 +15,14 @@ public class DependenciesPage
ICanvas canvas = new ConsoleCanvas(); ICanvas canvas = new ConsoleCanvas();
var header = new HeaderContainer(); var header = new HeaderContainer();
var copyright = new Copyright(); var copyright = new CopyrightComponent();
var dashboard = new Dashboard("Dependencies"); var dashboard = new DashboardContainer();
var layout = new DashboardLayout(); var layout = new DashboardLayout(header, dashboard, copyright);
layout.AddHeader(header); var dependency = new DependencyContainer();
layout.AddFooter(copyright); dashboard.AddChildren(dependency);
layout.AddDashboard(dashboard); dashboard.AddChildren(dependency);
dashboard.AddChildren(dependency);
dashboard.AddChildren(dependency);
// CommandLine = new CommandLine(); // CommandLine = new CommandLine();
// DependenciesView = new DependenciesView(); // DependenciesView = new DependenciesView();

View File

@ -20,7 +20,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\TUI.Engine\TUI.Engine.csproj" /> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
</AssemblyAttribute>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Controls.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TUI.Engine\TUI.Engine.csproj"/>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,35 +1,15 @@
using Pastel; using TUI.Engine;
using TUI.Engine.Theme;
namespace TUI.UserInterface; namespace TUI.UserInterface;
public static class Icons public static class Icons
{ {
public readonly static Dictionary<string, string> Applications = new() public static readonly Dictionary<string, string> Applications = new()
{ {
{ NpmPackage, "package" }, { Symbols.NpmPackage, "package" },
{ DockerImage, "image" }, { Symbols.DockerImage, "image" },
{ Site, "site" }, { Symbols.Site, "site" },
{ Api, "api" } { 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();
}
} }

View File

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<RootNamespace>TUI.Engine.Tests</RootNamespace>
<AssemblyName>TUI.Engine.Tests</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="7.0.0-alpha.3"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/>
<PackageReference Include="Moq" Version="4.20.70"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\TUI\TUI.csproj"/>
</ItemGroup>
</Project>

View File

@ -0,0 +1 @@
global using Xunit;

View File

@ -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);
}
}
}

View File

@ -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<INode>.Draw))]
public void DrawStaticComponentVerticalOrientation()
{
var canvas = Mock.Of<ICanvas>(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());
}
}

View File

@ -10,6 +10,10 @@ public static class MockExtensions
{ {
mock.Verify(w => w.SetPencil(new Position(left, top)), Times.Exactly(1)); mock.Verify(w => w.SetPencil(new Position(left, top)), Times.Exactly(1));
} }
public static void VerifyPositionTimes<T>(this Mock<T> 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<T>(this Mock<T> mock, Position position) where T : class, ICanvas public static void VerifyPositionOnce<T>(this Mock<T> mock, Position position) where T : class, ICanvas
{ {

View File

@ -1,6 +1,6 @@
using FluentAssertions; using FluentAssertions;
namespace TUI.Engine.Tests.Draw; namespace TUI.Engine.Tests.Primitives;
public class IntegerTests public class IntegerTests
{ {