using Client.ConsoleForms; using Client.ConsoleForms.Parameters; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Tofvesson.Collections; namespace Client.ConsoleForms.Graphics { public abstract class View { protected delegate void EventAction(); public delegate void ViewEvent(View v); protected static readonly Padding DEFAULT_PADDING = new AbsolutePadding(0, 0, 0, 0); protected internal readonly Padding padding; protected readonly Gravity gravity; protected readonly bool vCenter, hCenter; protected readonly string back_data; public char Border { get; set; } public bool DrawBorder { get; set; } public ConsoleColor BorderColor { get; set; } public ConsoleColor BackgroundColor { get; set; } public ConsoleColor TextColor { get; set; } public int ContentWidth { get; protected set; } public int ContentHeight { get; protected set; } public abstract Region Occlusion { get; } // Reports dimensions of entire view public Region ContentOcclusion { get => Occlusion; }// Reports dimensions of contents (SHOULD for most applications be smaller than or equal in size to Occlusion) public bool Dirty { get; set; } // Flag for whether or not view requires re-rendering public LangManager I18n { get; private set; } // Translation public ViewEvent OnBackEvent { get; set; } // Callback for [ESC] key public ViewEvent OnClose { get; set; } // Callback called immediately before controller removes view from render queue public View(ViewData parameters, LangManager lang) { padding = new AbsolutePadding(parameters.AttribueAsInt("padding_left"), parameters.AttribueAsInt("padding_right"), parameters.AttribueAsInt("padding_top"), parameters.AttribueAsInt("padding_bottom")); gravity = (Gravity)parameters.AttribueAsInt("gravity"); BorderColor = (ConsoleColor)parameters.AttribueAsInt("border", (int)ConsoleColor.Blue); BackgroundColor = (ConsoleColor)parameters.AttribueAsInt("color_background", (int)ConsoleColor.White); TextColor = (ConsoleColor)parameters.AttribueAsInt("color_text", (int)ConsoleColor.Black); Border = ' '; DrawBorder = true;// parameters.attributes.ContainsKey("border"); I18n = lang; back_data = parameters.GetAttribute("back"); // Do check to ensure that gravity flags are valid Enums.LayoutCheck(ref gravity); vCenter = !Enums.HasFlag(gravity, Gravity.LEFT) && !Enums.HasFlag(gravity, Gravity.RIGHT); hCenter = !Enums.HasFlag(gravity, Gravity.TOP) && !Enums.HasFlag(gravity, Gravity.BOTTOM); } public void ResetRenderColors() => SetRenderColors(BackgroundColor, TextColor); public void SetRenderColors(ConsoleColor bg, ConsoleColor fg) { Console.BackgroundColor = bg; Console.ForegroundColor = fg; } public void Draw(Tuple t) => Draw(t.Item1, t.Item2); public void Draw(int left, int top) => Draw(left, ref top); public void Draw(int left, ref int top) { Dirty = false; if (DrawBorder) _DrawBorder(left, top); DrawPadding(ref left, ref top); _Draw(left, ref top); } public virtual void _DrawBorder(int left, int top) { Console.BackgroundColor = BorderColor; Console.SetCursorPosition(left - 1 - padding.Left(), top - 1 - padding.Top()); Console.Write(Filler(Border, ContentWidth + padding.Left() + padding.Right() + 4)); for (int i = 0; i < ContentHeight + padding.Top() + padding.Bottom(); ++i) { Console.SetCursorPosition(left - padding.Left() - 1, top - padding.Top() + i); Console.Write(Filler(Border, 2)); Console.SetCursorPosition(left + ContentWidth + padding.Left() + padding.Right() - 1, top - padding.Top() + i); Console.Write(Filler(Border, 2)); } Console.SetCursorPosition(left - padding.Left() - 1, top + ContentHeight + padding.Bottom()); Console.Write(Filler(Border, ContentWidth + padding.Left() + padding.Right() + 4)); Console.BackgroundColor = ConsoleColor.Black; } public virtual void DrawPadding(ref int left, ref int top) { Console.BackgroundColor = BackgroundColor; // Top padding for(int i = 0; i TriggerKeyEvent(new ConsoleController.KeyEvent(info)); public virtual void TriggerKeyEvent(ConsoleController.KeyEvent info) => HandleKeyEvent(info, true, true); protected void DrawTopPadding(int left, ref int top) => DrawPadding(left, ref top, padding.Top()); protected void DrawBottomPadding(int left, ref int top) => DrawPadding(left, ref top, padding.Bottom()); private void DrawPadding(int left, ref int top, int count) { for (int i = 0; i < count; ++i) { Console.SetCursorPosition(left, top++); Console.Write(Filler(' ', ContentWidth)); } } protected EventAction ParseAction(ViewData data) { bool.TryParse(data?.GetAttribute("close") ?? "false", out bool close); bool.TryParse(data?.GetAttribute("exit") ?? "false", out bool exit); return ParseAction(data.GetAttribute("event"), close, exit); } protected EventAction ParseAction(string action, bool close, bool triggerExit = false) { string[] components; if (action == null || !action.Contains(':') || (components = action.Split(':')).Length != 2) return () => { if (close) ConsoleController.singleton.CloseView(this); if (triggerExit) ConsoleController.singleton.ShouldExit = true; }; var views = ConsoleController.LoadResourceViews(components[0], I18n); var view = views.GetNamed(components[1]); return () => { if (close) ConsoleController.singleton.CloseView(this); ConsoleController.singleton.AddView(view); if (triggerExit) ConsoleController.singleton.ShouldExit = true; }; } protected internal static string Filler(char c, int count) { if (count == 0) return ""; StringBuilder builder = new StringBuilder(count); for (int i = 0; i < count; ++i) builder.Append(c); return builder.ToString(); } } }