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(); protected static readonly Padding DEFAULT_PADDING = new AbsolutePadding(0, 0, 0, 0); protected 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; } public bool Dirty { get; set; } public LangManager I18n { get; private set; } 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); _Draw(left + 1, ref top); } public virtual void _DrawBorder(int left, int top) { Console.BackgroundColor = BorderColor; Console.SetCursorPosition(left - 1, top - 1); Console.Write(Filler(Border, ContentWidth + 2)); for (int i = -1; i < ContentHeight; ++i) { Console.SetCursorPosition(left-1, top + i); Console.Write(Filler(Border, 2)); Console.SetCursorPosition(left + ContentWidth + 1, top + i); Console.Write(Filler(Border, 2)); } Console.SetCursorPosition(left-1, top + ContentHeight); Console.Write(Filler(Border, ContentWidth + 4)); Console.BackgroundColor = ConsoleColor.Black; } protected abstract void _Draw(int left, ref int top); public virtual bool HandleKeyEvent(ConsoleController.KeyEvent info, bool inFocus) { if (back_data.Length != 0 && info.ValidEvent && inFocus && info.Event.Key == ConsoleKey.Escape) { info.ValidEvent = false; ParseAction(back_data, true)(); } return false; } 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"), out bool close); return ParseAction(data.GetAttribute("event"), close); } protected EventAction ParseAction(string action, bool close) { string[] components; if (action == null || !action.Contains(':') || (components = action.Split(':')).Length != 2) return () => { }; var views = ConsoleController.LoadResourceViews(components[0], I18n); var view = views.GetNamed(components[1]); return () => { if (close) ConsoleController.singleton.CloseView(this); ConsoleController.singleton.AddView(view); }; } protected 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(); } } }