Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Commit

Permalink
Modify text visualizer to better handle newlines and unprintable cont…
Browse files Browse the repository at this point in the history
…rol characters

Fixes bonsai-rx#1670
  • Loading branch information
PathogenDavid committed Apr 29, 2024
1 parent d3317bb commit 1c1a76a
Showing 1 changed file with 74 additions and 11 deletions.
85 changes: 74 additions & 11 deletions Bonsai.Design/ObjectTextVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
using System.Windows.Forms;
using Bonsai;
using Bonsai.Design;
using System.Diagnostics;
using System.Drawing;
using System.Reactive;
using System.Text.RegularExpressions;
using System.Text;

[assembly: TypeVisualizer(typeof(ObjectTextVisualizer), Target = typeof(object))]

Expand All @@ -30,27 +31,87 @@ public class ObjectTextVisualizer : BufferedVisualizer
/// <inheritdoc/>
protected override void ShowBuffer(IList<Timestamped<object>> values)
{
if (values.Count > 0)
if (values.Count == 0)
return;

var sb = new StringBuilder();

// Add new values to the buffer (and only the ones which might appear)
for (int i = Math.Max(0, values.Count - bufferSize); i < values.Count; i++)
{
var rawText = values[i].Value?.ToString() ?? string.Empty;
sb.Clear();
sb.EnsureCapacity(rawText.Length + rawText.Length / 16); // Arbitrary extra space for control characters
MakeDisplayString(rawText, sb);
DisplayString(sb.ToString());
}

// Update the visual representation of the buffer
Debug.Assert(buffer.Count <= bufferSize);
sb.Clear();
foreach (var line in buffer)
{
base.ShowBuffer(values);
textBox.Text = string.Join(Environment.NewLine, buffer);
textPanel.Invalidate();
if (sb.Length > 0)
sb.Append(Environment.NewLine);
sb.Append(line);
}
textBox.Text = sb.ToString();
textPanel.Invalidate();
}

/// <inheritdoc/>
public override void Show(object value)
{
value ??= string.Empty;
var text = value.ToString();
text = Regex.Replace(text, @"\r|\n", string.Empty);
buffer.Enqueue(text);
while (buffer.Count > bufferSize)
var rawText = value?.ToString() ?? string.Empty;
var stringBuilder = new StringBuilder(rawText.Length);
MakeDisplayString(rawText, stringBuilder);
DisplayString(stringBuilder.ToString());
}

/// <summary>Converts the specified string for display in this visualizer</summary>
/// <param name="rawText">The raw text to be converted</param>
/// <param name="stringBuilder">The string builder which receives the display string</param>
protected virtual void MakeDisplayString(string rawText, StringBuilder stringBuilder)
{
foreach (char c in rawText)
{
buffer.Dequeue();
switch (c)
{
// Carriage returns are presumed to be followed by line feeds, skip them entirely
case '\r':
continue;
// Newlines become space so that things like multi-line JSON or matricies are still visible
case '\n':
case '\x0085': // Next line character (NEL)
case '\x2028': // Unicode line separator
case '\x2029': // Unicode paragraph separator
stringBuilder.Append(' ');
break;
case '\t':
stringBuilder.Append(c);
break;
// Replace all other control characters with the unknown replacement character
case < ' ': // C0 control characters
case '\x007F': // Delete
case >= '\x0080' and <= '\x009F': // C1 control characters
stringBuilder.Append('\xFFFD');
break;
default:
stringBuilder.Append(c);
break;
}
}
}

private void DisplayString(string value)
{
// Loop instead of simple if because the buffer size may have decreased
while (buffer.Count >= bufferSize)
buffer.Dequeue();

buffer.Enqueue(value);
}

/// <inheritdoc/>
public override void Load(IServiceProvider provider)
{
Expand Down Expand Up @@ -106,7 +167,9 @@ public override void Unload()
{
bufferSize = 0;
textBox.Dispose();
textPanel.Dispose();
textBox = null;
textPanel = null;
buffer = null;
}
}
Expand Down

0 comments on commit 1c1a76a

Please sign in to comment.