void RenderUstr(ConsoleDriver driver, ustring ustr, int col, int line, int width) { int byteLen = ustr.Length; int used = 0; for (int i = 0; i < byteLen;) { (var rune, var size) = Utf8.DecodeRune(ustr, i, i - byteLen); var count = Rune.ColumnWidth(rune); if (used + count >= width) { break; } driver.AddRune(rune); used += count; i += size; } for (; used < width; used++) { driver.AddRune(' '); } }
// A slightly adapted method from gui.cs: https://github.com/migueldeicaza/gui.cs/blob/fc1faba7452ccbdf49028ac49f0c9f0f42bbae91/Terminal.Gui/Views/ListView.cs#L433-L461 private void RenderUstr(ConsoleDriver driver, ustring ustr, int col, int line, int width) { int used = 0; int index = 0; while (index < ustr.Length) { (var rune, var size) = Utf8.DecodeRune(ustr, index, index - ustr.Length); var count = Rune.ColumnWidth(rune); if (used + count > width) { break; } driver.AddRune(rune); used += count; index += size; } while (used < width) { driver.AddRune(' '); used++; } }
/// <summary> /// Renders the current <see cref="Model"/> on the specified line <paramref name="y"/> /// </summary> /// <param name="driver"></param> /// <param name="colorScheme"></param> /// <param name="y"></param> /// <param name="availableWidth"></param> public virtual void Draw(ConsoleDriver driver, ColorScheme colorScheme, int y, int availableWidth) { // true if the current line of the tree is the selected one and control has focus bool isSelected = tree.IsSelected(Model) && tree.HasFocus; Attribute lineColor = isSelected ? colorScheme.Focus : colorScheme.Normal; driver.SetAttribute(lineColor); // Everything on line before the expansion run and branch text Rune [] prefix = GetLinePrefix(driver).ToArray(); Rune expansion = GetExpandableSymbol(driver); string lineBody = tree.AspectGetter(Model) ?? ""; tree.Move(0, y); // if we have scrolled to the right then bits of the prefix will have dispeared off the screen int toSkip = tree.ScrollOffsetHorizontal; // Draw the line prefix (all paralell lanes or whitespace and an expand/collapse/leaf symbol) foreach (Rune r in prefix) { if (toSkip > 0) { toSkip--; } else { driver.AddRune(r); availableWidth -= Rune.ColumnWidth(r); } } // pick color for expanded symbol if (tree.Style.ColorExpandSymbol || tree.Style.InvertExpandSymbolColors) { Attribute color; if (tree.Style.ColorExpandSymbol) { color = isSelected ? tree.ColorScheme.HotFocus : tree.ColorScheme.HotNormal; } else { color = lineColor; } if (tree.Style.InvertExpandSymbolColors) { color = new Attribute(color.Background, color.Foreground); } driver.SetAttribute(color); } if (toSkip > 0) { toSkip--; } else { driver.AddRune(expansion); availableWidth -= Rune.ColumnWidth(expansion); } // horizontal scrolling has already skipped the prefix but now must also skip some of the line body if (toSkip > 0) { if (toSkip > lineBody.Length) { lineBody = ""; } else { lineBody = lineBody.Substring(toSkip); } } // If body of line is too long if (lineBody.Sum(l => Rune.ColumnWidth(l)) > availableWidth) { // remaining space is zero and truncate the line lineBody = new string (lineBody.TakeWhile(c => (availableWidth -= Rune.ColumnWidth(c)) >= 0).ToArray()); availableWidth = 0; } else { // line is short so remaining width will be whatever comes after the line body availableWidth -= lineBody.Length; } // default behaviour is for model to use the color scheme // of the tree view var modelColor = lineColor; // if custom color delegate invoke it if (tree.ColorGetter != null) { var modelScheme = tree.ColorGetter(Model); // if custom color scheme is defined for this Model if (modelScheme != null) { // use it modelColor = isSelected ? modelScheme.Focus : modelScheme.Normal; } } driver.SetAttribute(modelColor); driver.AddStr(lineBody); driver.SetAttribute(lineColor); if (availableWidth > 0) { driver.AddStr(new string (' ', availableWidth)); } driver.SetAttribute(colorScheme.Normal); }
void RenderLine(ConsoleDriver driver, IHasStats toRender, int col, int line, int width) { string suffix = " "; //Get relation to player if (toRender is IActor a) { var world = a.CurrentLocation.World; var relationship = world.Relationships.SumBetween(a, world.Player); if (relationship < -40) { suffix = "---"; } else if (relationship < -20) { suffix = "-- "; } else if (relationship < 0) { suffix = "- "; } else if (relationship > 40) { suffix = "+++"; } else if (relationship > 20) { suffix = "++ "; } else if (relationship > 0) { suffix = "+ "; } } //allow for the suffix var ustring = toRender.ToString(); ustring = ustring.Substring(0, Math.Min(ustring.Length, width - 3)) + suffix; ustring = ustring.PadRight(width); int byteLen = ustring.Length; int used = 0; for (int i = 0; i < byteLen;) { (var rune, var size) = Utf8.DecodeRune(ustring, i, i - byteLen); var count = Rune.ColumnWidth(rune); if (used + count >= width) { break; } if (rune == '-') { driver.SetAttribute(_red); } else if (rune == '+') { driver.SetAttribute(_green); } else { driver.SetAttribute(_normal); } driver.AddRune(rune); used += count; i += size; } for (; used < width; used++) { driver.AddRune(' '); } }