189 lines
5.0 KiB
C#
189 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using DTLib;
|
|
using DTLib.Extensions;
|
|
|
|
namespace launcher_client;
|
|
|
|
public class ConsoleWrapper : IConsoleWrapper
|
|
{
|
|
private List<string> _textLines = new();
|
|
private int _linesUp;
|
|
private string _headerText = "";
|
|
private string _footerText = "";
|
|
|
|
private Timer _consoleSizeCheckTimer;
|
|
|
|
public int TextAreaW;
|
|
public int TextAreaH;
|
|
|
|
|
|
public ConsoleWrapper()
|
|
{
|
|
int lastW = Console.WindowWidth;
|
|
int lastH = Console.WindowHeight;
|
|
_consoleSizeCheckTimer = new Timer(true, 50, () =>
|
|
{
|
|
if(Console.WindowWidth != lastW || Console.WindowHeight != lastH)
|
|
{
|
|
lastW = Console.WindowWidth;
|
|
lastH = Console.WindowHeight;
|
|
Console.Clear();
|
|
DrawGui();
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// starts automatig gui redraw on console size change
|
|
/// </summary>
|
|
public void StartUpdating()
|
|
{
|
|
_consoleSizeCheckTimer.Start();
|
|
}
|
|
|
|
public void StopUpdating()
|
|
{
|
|
_consoleSizeCheckTimer.Stop();
|
|
}
|
|
|
|
public void WriteLine(string msg)
|
|
{
|
|
_textLines.Add(msg);
|
|
DrawGui();
|
|
}
|
|
|
|
public void SetHeader(string s) => _headerText = s;
|
|
|
|
public void SetFooter(string s) => _footerText = s;
|
|
|
|
public void ScrollDown(int lines = 1)
|
|
{
|
|
_linesUp -= lines;
|
|
if (_linesUp < 0)
|
|
_linesUp = 0;
|
|
DrawGui();
|
|
}
|
|
|
|
public void ScrollUp(int lines = 1)
|
|
{
|
|
_linesUp += lines;
|
|
DrawGui();
|
|
}
|
|
|
|
public void DrawGui()
|
|
{
|
|
var b = new ConsoleBuffer();
|
|
TextAreaW = b.Width - 6;
|
|
TextAreaH = b.Height - 6;
|
|
Console.ForegroundColor = ConsoleColor.White;
|
|
Console.CursorVisible = false;
|
|
DrawBorders(b);
|
|
DrawText(b);
|
|
DrawScrollBar(b);
|
|
DrawHeader(b);
|
|
DrawFooter(b);
|
|
b.Print();
|
|
}
|
|
|
|
private void DrawBorders(ConsoleBuffer b)
|
|
{
|
|
b.Write( '┏' + '━'.Multiply(b.Width - 2) + '┓');
|
|
b.Write( '┃' + ' '.Multiply(b.Width - 2) + '┃');
|
|
b.Write( '┣' + '━'.Multiply(b.Width - 4) + "┳━┫");
|
|
for (int y = 0; y < b.Height - 6; y++)
|
|
b.Write('┃' + ' '.Multiply(b.Width - 4) + "┃ ┃");
|
|
b.Write( '┣' + '━'.Multiply(b.Width - 4) + "┻━┫");
|
|
b.Write( '┃' + ' '.Multiply(b.Width - 2) + '┃');
|
|
b.Write( '┗' + '━'.Multiply(b.Width - 2) + '┛');
|
|
}
|
|
|
|
private void DrawScrollBar(ConsoleBuffer b)
|
|
{
|
|
int scrollBarX = b.Width - 2;
|
|
int scrollBarY = 3;
|
|
|
|
int slideH = 0;
|
|
if (_textLines.Count >= TextAreaH)
|
|
slideH = (int)Math.Ceiling((double)TextAreaH * TextAreaH / _textLines.Count);
|
|
int slidePos = (int)Math.Ceiling((double) _linesUp / TextAreaH) + 1;
|
|
for(int y = 0; y < slideH; y++)
|
|
{
|
|
b.SetCursorPosition(scrollBarX, scrollBarY + TextAreaH - y - slidePos);
|
|
b.Write('▒');
|
|
}
|
|
}
|
|
|
|
private void DrawHeader(ConsoleBuffer b)
|
|
{
|
|
b.SetCursorPosition(2, 1);
|
|
b.Write(ChopLongLine(_headerText, b.Width - 4));
|
|
}
|
|
|
|
private void DrawFooter(ConsoleBuffer b)
|
|
{
|
|
b.SetCursorPosition(2, b.Height - 2);
|
|
b.Write(ChopLongLine(_footerText, b.Width - 4));
|
|
}
|
|
|
|
private static string ChopLongLine(string s, int maxLength)
|
|
{
|
|
if (s.Length <= maxLength)
|
|
return s;
|
|
|
|
return s.Remove(maxLength - 3) + "...";
|
|
}
|
|
|
|
private void DrawText(ConsoleBuffer b)
|
|
{
|
|
int textAreaX = 2;
|
|
int textAreaY = 3;
|
|
|
|
var realLines = _textLines
|
|
.SelectMany(s => SplitStringToLines(s, TextAreaW))
|
|
.ToArray();
|
|
|
|
int linesUp = _linesUp + TextAreaH;
|
|
if (linesUp > realLines.Length)
|
|
{
|
|
linesUp = realLines.Length;
|
|
_linesUp = Math.Max(0, realLines.Length - TextAreaH);
|
|
}
|
|
|
|
for (int y = 0; y < TextAreaH; y++)
|
|
{
|
|
b.SetCursorPosition(textAreaX, textAreaY + y);
|
|
int li = realLines.Length - linesUp + y;
|
|
if (li >= realLines.Length)
|
|
break;
|
|
b.Write(realLines[li]);
|
|
}
|
|
}
|
|
|
|
private static ICollection<string> SplitStringToLines(string _s, int lineW)
|
|
{
|
|
var split = _s.Replace("\r", "").Split('\n');
|
|
if (_s.Length <= lineW)
|
|
return split;
|
|
|
|
List<string> lines = new();
|
|
for (int spi = 0; spi < split.Length; spi++)
|
|
{
|
|
string s = split[spi];
|
|
int linesCount = s.Length / lineW;
|
|
if (s.Length % lineW != 0)
|
|
linesCount++;
|
|
|
|
for (int i = 0; i < linesCount; i++)
|
|
lines.Add(s.Substring(i * lineW, Math.Min(lineW, s.Length - i * lineW)));
|
|
}
|
|
|
|
return lines;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
StopUpdating();
|
|
}
|
|
} |