using Microsoft.Extensions.Logging;
namespace Terminal.Gui.Drivers;
///
/// Implementation of that uses native dotnet
/// methods e.g.
///
public class NetOutput : OutputBase, IConsoleOutput
{
private readonly bool _isWinPlatform;
///
/// Creates a new instance of the class.
///
public NetOutput ()
{
Logging.Logger.LogInformation ($"Creating {nameof (NetOutput)}");
Console.OutputEncoding = Encoding.UTF8;
PlatformID p = Environment.OSVersion.Platform;
if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows)
{
_isWinPlatform = true;
}
}
///
public void Write (ReadOnlySpan text)
{
Console.Out.Write (text);
}
///
public Size GetWindowSize ()
{
if (ConsoleDriver.RunningUnitTests)
{
// For unit tests, we return a default size.
return Size.Empty;
}
return new (Console.WindowWidth, Console.WindowHeight);
}
///
public void SetCursorPosition (int col, int row) { SetCursorPositionImpl (col, row); }
private Point? _lastCursorPosition;
///
protected override void AppendOrWriteAttribute (StringBuilder output, Attribute attr, TextStyle redrawTextStyle)
{
if (Application.Force16Colors)
{
output.Append (EscSeqUtils.CSI_SetForegroundColor (attr.Foreground.GetAnsiColorCode ()));
output.Append (EscSeqUtils.CSI_SetBackgroundColor (attr.Background.GetAnsiColorCode ()));
}
else
{
EscSeqUtils.CSI_AppendForegroundColorRGB (
output,
attr.Foreground.R,
attr.Foreground.G,
attr.Foreground.B
);
EscSeqUtils.CSI_AppendBackgroundColorRGB (
output,
attr.Background.R,
attr.Background.G,
attr.Background.B
);
}
EscSeqUtils.CSI_AppendTextStyleChange (output, redrawTextStyle, attr.Style);
}
///
protected override void Write (StringBuilder output)
{
Console.Out.Write (output);
}
///
protected override bool SetCursorPositionImpl (int col, int row)
{
if (_lastCursorPosition is { } && _lastCursorPosition.Value.X == col && _lastCursorPosition.Value.Y == row)
{
return true;
}
_lastCursorPosition = new (col, row);
if (_isWinPlatform)
{
// Could happens that the windows is still resizing and the col is bigger than Console.WindowWidth.
try
{
Console.SetCursorPosition (col, row);
return true;
}
catch (Exception)
{
return false;
}
}
// + 1 is needed because non-Windows is based on 1 instead of 0 and
// Console.CursorTop/CursorLeft isn't reliable.
EscSeqUtils.CSI_WriteCursorPosition (Console.Out, row + 1, col + 1);
return true;
}
///
public void Dispose ()
{
}
private EscSeqUtils.DECSCUSR_Style? _currentDecscusrStyle;
///
public override void SetCursorVisibility (CursorVisibility visibility)
{
if (visibility != CursorVisibility.Invisible)
{
if (_currentDecscusrStyle is null || _currentDecscusrStyle != (EscSeqUtils.DECSCUSR_Style)(((int)visibility >> 24) & 0xFF))
{
_currentDecscusrStyle = (EscSeqUtils.DECSCUSR_Style)(((int)visibility >> 24) & 0xFF);
Write (EscSeqUtils.CSI_SetCursorStyle ((EscSeqUtils.DECSCUSR_Style)_currentDecscusrStyle));
}
Write (EscSeqUtils.CSI_ShowCursor);
}
else
{
Write (EscSeqUtils.CSI_HideCursor);
}
}
}