namespace Terminal.Gui;
///
/// Represents a single row/column in a Terminal.Gui rendering surface (e.g. and
/// ).
///
public record struct Cell (Attribute? Attribute = null, bool IsDirty = false, Rune Rune = default)
{
/// The attributes to use when drawing the Glyph.
public Attribute? Attribute { get; set; } = Attribute;
///
/// Gets or sets a value indicating whether this has been modified since the
/// last time it was drawn.
///
public bool IsDirty { get; set; } = IsDirty;
private Rune _rune = Rune;
/// The character to display. If is , then is ignored.
public Rune Rune
{
get => _rune;
set
{
CombiningMarks.Clear ();
_rune = value;
}
}
private List _combiningMarks;
///
/// The combining marks for that when combined makes this Cell a combining sequence. If
/// empty, then is ignored.
///
///
/// Only valid in the rare case where is a combining sequence that could not be normalized to a
/// single Rune.
///
internal List CombiningMarks
{
get => _combiningMarks ?? [];
private set => _combiningMarks = value ?? [];
}
///
public override string ToString () { return $"[{Rune}, {Attribute}]"; }
/// Converts the string into a .
/// The string to convert.
/// The to use.
///
public static List ToCellList (string str, Attribute? attribute = null)
{
List cells = new ();
foreach (Rune rune in str.EnumerateRunes ())
{
cells.Add (new () { Rune = rune, Attribute = attribute });
}
return cells;
}
///
/// Splits a string into a List that will contain a for each line.
///
/// The string content.
/// The color scheme.
/// A for each line.
public static List> StringToLinesOfCells (string content, Attribute? attribute = null)
{
List cells = content.EnumerateRunes ()
.Select (x => new Cell { Rune = x, Attribute = attribute })
.ToList ();
return SplitNewLines (cells);
}
/// Converts a generic collection into a string.
/// The enumerable cell to convert.
///
public static string ToString (IEnumerable cells)
{
var str = string.Empty;
foreach (Cell cell in cells)
{
str += cell.Rune.ToString ();
}
return str;
}
/// Converts a generic collection into a string.
/// The enumerable cell to convert.
///
public static string ToString (List> cellsList)
{
var str = string.Empty;
for (var i = 0; i < cellsList.Count; i++)
{
IEnumerable cellList = cellsList [i];
str += ToString (cellList);
if (i + 1 < cellsList.Count)
{
str += Environment.NewLine;
}
}
return str;
}
// Turns the string into cells, this does not split the contents on a newline if it is present.
internal static List StringToCells (string str, Attribute? attribute = null)
{
List cells = [];
foreach (Rune rune in str.ToRunes ())
{
cells.Add (new () { Rune = rune, Attribute = attribute });
}
return cells;
}
internal static List ToCells (IEnumerable runes, Attribute? attribute = null)
{
List cells = new ();
foreach (Rune rune in runes)
{
cells.Add (new () { Rune = rune, Attribute = attribute });
}
return cells;
}
private static List> SplitNewLines (List cells)
{
List> lines = [];
int start = 0, i = 0;
var hasCR = false;
// ASCII code 13 = Carriage Return.
// ASCII code 10 = Line Feed.
for (; i < cells.Count; i++)
{
if (cells [i].Rune.Value == 13)
{
hasCR = true;
continue;
}
if (cells [i].Rune.Value == 10)
{
if (i - start > 0)
{
lines.Add (cells.GetRange (start, hasCR ? i - 1 - start : i - start));
}
else
{
lines.Add (StringToCells (string.Empty));
}
start = i + 1;
hasCR = false;
}
}
if (i - start >= 0)
{
lines.Add (cells.GetRange (start, i - start));
}
return lines;
}
///
/// Splits a rune cell list into a List that will contain a for each line.
///
/// The cells list.
///
public static List> ToCells (List cells) { return SplitNewLines (cells); }
}
| | | | | | | | | | |