source/PoshTui/PoshTui/PoshTui_source.cs
/// PoshTui | Version 0.5.0
/// Class Library /// using System; using System.Collections.ObjectModel; using System.Text; using System.IO; using System.Reflection; using System.Management.Automation; namespace PoshTui { // PoshTui Enumerators public enum MenuItemFocusStyleEnum { HighlightForeground, HighlightBackground } public enum BorderStyleEnum { Unspecified, SingleLight, SingleHeavy, Rounded, Double } // UIColorTheme Class public class UIColorTheme { public string Reset = "\x1b[0m"; public string BorderColor = "\x1b[38;5;230m"; public string AccentColor = "\x1b[38;5;123m"; public string FormTitleColor = "\x1b[38;5;51m"; public string MenuTitleColor = "\x1b[38;5;51m"; public string MenuItemColor = "\x1b[38;5;243m"; public string MenuItemFocusColor = "\x1b[38;5;229m"; public string DescriptionHeaderColor = "\x1b[38;5;229m"; public string MenuItemDescriptionColor = "\x1b[38;5;85m"; public UIColorTheme() { } } // Menu Border Style Classes // Single Border, Light public class MenuBorderSingleLight { public char CornerTopL = '┌'; public char CornerTopR = '┐'; public char Horizontal = '─'; public char CornerBtmL = '└'; public char CornerBtmR = '┘'; public char Vertical = '│'; public char VerticalSeparatorL = '├'; public char VerticalSeparatorR = '┤'; public char Separator = '─'; public char AltSeparator = '┄'; public char AccentChar = '█'; public MenuBorderSingleLight() { } } // Single Border, Heavy public class MenuBorderSingleHeavy { public char CornerTopL = '┏'; public char CornerTopR = '┓'; public char Horizontal = '━'; public char CornerBtmL = '┗'; public char CornerBtmR = '┛'; public char Vertical = '┃'; public char VerticalSeparatorL = '┠'; public char VerticalSeparatorR = '┨'; public char Separator = '─'; public char AltSeparator = '┄'; public char AccentChar = '█'; public MenuBorderSingleHeavy() { } } // Single Border, Rounded public class MenuBorderRounded { public char CornerTopL = '╭'; public char CornerTopR = '╮'; public char Horizontal = '─'; public char CornerBtmL = '╰'; public char CornerBtmR = '╯'; public char Vertical = '│'; public char VerticalSeparatorL = '├'; public char VerticalSeparatorR = '┤'; public char Separator = '─'; public char AltSeparator = '┄'; public char AccentChar = '█'; public MenuBorderRounded() { } } // Double Border public class MenuBorderDouble { public char CornerTopL = '╔'; public char CornerTopR = '╗'; public char Horizontal = '═'; public char CornerBtmL = '╚'; public char CornerBtmR = '╝'; public char Vertical = '║'; public char VerticalSeparatorL = '╟'; public char VerticalSeparatorR = '╢'; public char Separator = '─'; public char AltSeparator = '╍'; public char AccentChar = '█'; public MenuBorderDouble() { } } // Menu Item/UI Element Classes // Menu Item Class Definition public class MenuItem { public string DisplayName; public string Description; public ScriptBlock OnConfirm; public MenuItem() { } public void SetDisplayName(string displayName) { DisplayName = displayName; } public void SetDescription(string description) { Description = description; } public void SetOnConfirmScriptBlock(ScriptBlock scriptBlock) { OnConfirm = scriptBlock; } } public class ConsoleForm { public int FormId = 0; public string Name = "PoshTui ConsoleForm"; public int UIWidth = 208; public BorderStyleEnum UIBorderStyle; public string FormTitle = "ConsoleForm Title"; public string MenuTitle = "Menu Title"; public MenuItem[] MenuItems; public MenuItemFocusStyleEnum MenuItemFocusStyle = MenuItemFocusStyleEnum.HighlightBackground; public UIColorTheme ColorTheme = new UIColorTheme(); public ConsoleForm() { } public void AddMenuItem(MenuItem[] items) { if (MenuItems == null) { MenuItems = items; } else { var combined = new MenuItem[MenuItems.Length + items.Length]; MenuItems.CopyTo(combined, 0); items.CopyTo(combined, MenuItems.Length); MenuItems = combined; } } public void Show() { // Set up border style object border = UIBorderStyle switch { BorderStyleEnum.SingleLight => new MenuBorderSingleLight(), BorderStyleEnum.SingleHeavy => new MenuBorderSingleHeavy(), BorderStyleEnum.Rounded => new MenuBorderRounded(), BorderStyleEnum.Double => new MenuBorderDouble(), _ => new MenuBorderSingleLight() }; // Use reflection to access border chars char GetBorderChar(string name) => (char)border.GetType().GetField(name).GetValue(border); // Color theme var color = ColorTheme; // Console encoding Console.OutputEncoding = Encoding.Unicode; int charFillCount = UIWidth - 2; string EmptyFill = new string(' ', charFillCount); string HorizontalFill = new string(GetBorderChar("Horizontal"), charFillCount); string SeparatorFill = new string(GetBorderChar("Separator"), charFillCount); string SeparatorAltFill = new string(GetBorderChar("AltSeparator"), charFillCount); string AccentFill = new string(GetBorderChar("AccentChar"), charFillCount); int menuTitlePadding = (int)Math.Floor((UIWidth - MenuTitle.Length) / 2.0); string CenteredMenuTitle = MenuTitle.PadLeft(MenuTitle.Length + menuTitlePadding).PadRight(UIWidth - 2); string LineBorderTop = $"{color.BorderColor}{GetBorderChar("CornerTopL")}{HorizontalFill}{GetBorderChar("CornerTopR")}{color.Reset}"; string LineFormTitle = $"{color.BorderColor}{GetBorderChar("Vertical")} {color.FormTitleColor} [{FormTitle}]{color.Reset}{new string(' ', UIWidth - FormTitle.Length - 6)}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"; string LineBorderSeparator = $"{color.BorderColor}{GetBorderChar("Vertical")}{SeparatorFill}{GetBorderChar("Vertical")}{color.Reset}"; string LineMenuTitle = $"{color.BorderColor}{GetBorderChar("Vertical")}{color.MenuTitleColor}{CenteredMenuTitle}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"; string LineEmpty = $"{color.BorderColor}{GetBorderChar("Vertical")}{EmptyFill}{GetBorderChar("Vertical")}{color.Reset}"; string LineBorderSeparatorAlt = $"{color.BorderColor}{GetBorderChar("Vertical")}{SeparatorAltFill}{GetBorderChar("Vertical")}{color.Reset}"; string LineFullBlock = $"{color.BorderColor}{GetBorderChar("Vertical")}{color.AccentColor}{AccentFill}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"; string LineBorderBottom = $"{color.BorderColor}{GetBorderChar("CornerBtmL")}{HorizontalFill}{GetBorderChar("CornerBtmR")}{color.Reset}"; string MenuItemDescriptionHeader = "Item Details"; int selectedIndex = 0; Console.CursorVisible = false; void Redraw() { Console.Write("\x1b[2J\x1b[H"); // Clear and home cursor Console.WriteLine(LineBorderTop); Console.WriteLine(LineFormTitle); Console.WriteLine(LineBorderSeparator); Console.WriteLine(LineMenuTitle); Console.WriteLine(LineBorderSeparatorAlt); Console.WriteLine(LineEmpty); for (int i = 0; i < MenuItems.Length; i++) { var item = MenuItems[i]; int itemPadding = (int)Math.Floor((UIWidth - item.DisplayName.Length) / 2.0); string centeredItem = item.DisplayName.PadLeft(item.DisplayName.Length + itemPadding).PadRight(UIWidth - 2); if (i == selectedIndex) { string centeredItemFocus = centeredItem; Console.WriteLine($"{color.BorderColor}{GetBorderChar("Vertical")}{centeredItemFocus}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"); } else { Console.WriteLine($"{color.BorderColor}{GetBorderChar("Vertical")}{color.MenuItemColor}{centeredItem}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"); } } int detailsTitlePadding = (int)Math.Floor((UIWidth - MenuItemDescriptionHeader.Length) / 2.0); int itemInfoPadding = (int)Math.Floor((UIWidth - MenuItems[selectedIndex].Description.Length) / 2.0); string centeredInfoTag = MenuItemDescriptionHeader.PadLeft(MenuItemDescriptionHeader.Length + detailsTitlePadding).PadRight(UIWidth - 2); string centeredInfo = MenuItems[selectedIndex].Description.PadLeft(MenuItems[selectedIndex].Description.Length + itemInfoPadding).PadRight(UIWidth - 2); string LineInfoHeader = $"{color.BorderColor}{GetBorderChar("Vertical")}{color.DescriptionHeaderColor}{centeredInfoTag}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"; string LineInfo = $"{color.BorderColor}{GetBorderChar("Vertical")}{color.MenuItemDescriptionColor}{centeredInfo}{color.BorderColor}{GetBorderChar("Vertical")}{color.Reset}"; Console.WriteLine(LineEmpty); Console.WriteLine(LineBorderSeparator); Console.WriteLine(LineInfoHeader); Console.WriteLine(LineBorderSeparator); Console.WriteLine(LineEmpty); Console.WriteLine(LineInfo); Console.WriteLine(LineEmpty); Console.WriteLine(LineBorderSeparator); Console.WriteLine(LineFullBlock); Console.WriteLine(LineBorderSeparator); Console.WriteLine(LineEmpty); Console.WriteLine(LineBorderBottom); } Redraw(); while (true) { var key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { selectedIndex = (selectedIndex - 1 + MenuItems.Length) % MenuItems.Length; Redraw(); } else if (key.Key == ConsoleKey.DownArrow) { selectedIndex = (selectedIndex + 1) % MenuItems.Length; Redraw(); } else if (key.Key == ConsoleKey.Enter) { Console.Clear(); MenuItems[selectedIndex].OnConfirm?.Invoke(); break; } } Console.CursorVisible = true; } } } |