Merge branch 'v2_develop' into v2_3836_setupfakefriver-after-fix

This commit is contained in:
Tig
2024-12-05 09:09:54 -07:00
committed by GitHub
7 changed files with 122 additions and 26 deletions

View File

@@ -1411,7 +1411,7 @@ public class TextFormatter
if (textFormatter is { Alignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
@@ -1426,7 +1426,7 @@ public class TextFormatter
if (textFormatter is { VerticalAlignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
@@ -1451,7 +1451,7 @@ public class TextFormatter
}
else if (textFormatter is { Alignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
else if (GetRuneWidth (text, tabWidth, textDirection) > width)
{
@@ -1470,7 +1470,7 @@ public class TextFormatter
}
else if (textFormatter is { VerticalAlignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
else if (runes.Count - zeroLength > width)
{
@@ -1526,7 +1526,7 @@ public class TextFormatter
}
else
{
textCount = words.Sum (arg => arg.GetRuneCount ());
textCount = words.Sum (arg => arg.GetRuneCount ()) - text.EnumerateRunes ().Sum (r => r.GetColumns () == 0 ? 1 : 0);
}
int spaces = words.Length > 1 ? (width - textCount) / (words.Length - 1) : 0;
@@ -1936,7 +1936,7 @@ public class TextFormatter
private static int GetRuneWidth (Rune rune, int tabWidth, TextDirection textDirection = TextDirection.LeftRight_TopBottom)
{
int runeWidth = IsHorizontalDirection (textDirection) ? rune.GetColumns () : 1;
int runeWidth = IsHorizontalDirection (textDirection) ? rune.GetColumns () : rune.GetColumns () == 0 ? 0 : 1;
if (rune.Value == '\t')
{

View File

@@ -690,11 +690,11 @@ public partial class View // Keyboard APIs
#if DEBUG
if (Application.KeyBindings.TryGet (key, out KeyBinding b))
{
Debug.WriteLine (
$"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command.");
}
//if (Application.KeyBindings.TryGet (key, out KeyBinding b))
//{
// Debug.WriteLine (
// $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command.");
//}
// TODO: This is a "prototype" debug check. It may be too annoying vs. useful.
// Scour the bindings up our View hierarchy

View File

@@ -561,8 +561,9 @@ public partial class View // Layout APIs
{
SuperView?.SetNeedsDraw ();
}
else
else if (Application.TopLevels.Count == 1)
{
// If this is the only TopLevel, we need to redraw the screen
Application.ClearScreenNextIteration = true;
}
}
@@ -801,7 +802,7 @@ public partial class View // Layout APIs
{
foreach (Toplevel tl in Application.TopLevels)
{
// tl.SetNeedsDraw ();
// tl.SetNeedsDraw ();
}
}

View File

@@ -42,7 +42,7 @@
},
"All Views Tester": {
"commandName": "Project",
"commandLineArgs": "\"All Views Tester\" -b"
"commandLineArgs": "\"All Views Tester\" -b -t 5000"
},
"Charmap": {
"commandName": "Project",

View File

@@ -148,14 +148,15 @@ public class Scenario : IDisposable
/// </summary>
public virtual void Main () { }
private const uint MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
private const uint ABORT_TIMEOUT_MS = 2500;
private const int DEMO_KEY_PACING_MS = 1; // Must be non-zero
private const uint BENCHMARK_MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
private const int BENCHMARK_KEY_PACING = 1; // Must be non-zero
public static uint BenchmarkTimeout { get; set; } = 2500;
private readonly object _timeoutLock = new ();
private object? _timeout;
private Stopwatch? _stopwatch;
private readonly BenchmarkResults _benchmarkResults = new BenchmarkResults ();
private readonly BenchmarkResults _benchmarkResults = new ();
public void StartBenchmark ()
{
@@ -178,7 +179,7 @@ public class Scenario : IDisposable
return _benchmarkResults;
}
private List<Key> _demoKeys;
private List<Key>? _demoKeys;
private int _currentDemoKey = 0;
private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
@@ -187,7 +188,7 @@ public class Scenario : IDisposable
{
lock (_timeoutLock!)
{
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (ABORT_TIMEOUT_MS), ForceCloseCallback);
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (BenchmarkTimeout), ForceCloseCallback);
}
Application.Iteration += OnApplicationOnIteration;
@@ -218,7 +219,7 @@ public class Scenario : IDisposable
private void OnApplicationOnIteration (object? s, IterationEventArgs a)
{
BenchmarkResults.IterationCount++;
if (BenchmarkResults.IterationCount > MAX_NATURAL_ITERATIONS + (_demoKeys.Count* DEMO_KEY_PACING_MS))
if (BenchmarkResults.IterationCount > BENCHMARK_MAX_NATURAL_ITERATIONS + (_demoKeys.Count * BENCHMARK_KEY_PACING))
{
Application.RequestStop ();
}
@@ -232,7 +233,7 @@ public class Scenario : IDisposable
_demoKeys = GetDemoKeyStrokes ();
Application.AddTimeout (
new TimeSpan (0, 0, 0, 0, DEMO_KEY_PACING_MS),
new TimeSpan (0, 0, 0, 0, BENCHMARK_KEY_PACING),
() =>
{
if (_currentDemoKey >= _demoKeys.Count)
@@ -271,7 +272,7 @@ public class Scenario : IDisposable
}
}
Debug.WriteLine ($@" Failed to Quit with {Application.QuitKey} after {ABORT_TIMEOUT_MS}ms and {BenchmarkResults.IterationCount} iterations. Force quit.");
Debug.WriteLine ($@" Failed to Quit with {Application.QuitKey} after {BenchmarkTimeout}ms and {BenchmarkResults.IterationCount} iterations. Force quit.");
Application.RequestStop ();

View File

@@ -148,6 +148,10 @@ public class UICatalogApp
benchmarkFlag.AddAlias ("-b");
benchmarkFlag.AddAlias ("--b");
Option<uint> benchmarkTimeout = new Option<uint> ("--timeout", getDefaultValue: () => Scenario.BenchmarkTimeout, $"The maximum time in milliseconds to run a benchmark for. Default is {Scenario.BenchmarkTimeout}ms.");
benchmarkTimeout.AddAlias ("-t");
benchmarkTimeout.AddAlias ("--t");
Option<string> resultsFile = new Option<string> ("--file", "The file to save benchmark results to. If not specified, the results will be displayed in a TableView.");
resultsFile.AddAlias ("-f");
resultsFile.AddAlias ("--f");
@@ -165,7 +169,7 @@ public class UICatalogApp
var rootCommand = new RootCommand ("A comprehensive sample library for Terminal.Gui")
{
scenarioArgument, benchmarkFlag, resultsFile, driverOption,
scenarioArgument, benchmarkFlag, benchmarkTimeout, resultsFile, driverOption,
};
rootCommand.SetHandler (
@@ -176,6 +180,7 @@ public class UICatalogApp
Scenario = context.ParseResult.GetValueForArgument (scenarioArgument),
Driver = context.ParseResult.GetValueForOption (driverOption) ?? string.Empty,
Benchmark = context.ParseResult.GetValueForOption (benchmarkFlag),
BenchmarkTimeout = context.ParseResult.GetValueForOption (benchmarkTimeout),
ResultsFile = context.ParseResult.GetValueForOption (resultsFile) ?? string.Empty,
/* etc. */
};
@@ -197,6 +202,8 @@ public class UICatalogApp
return 0;
}
Scenario.BenchmarkTimeout = _options.BenchmarkTimeout;
UICatalogMain (_options);
return 0;
@@ -332,6 +339,7 @@ public class UICatalogApp
// regardless of what's in a config file.
Application.ForceDriver = _forceDriver = options.Driver;
// If a Scenario name has been provided on the commandline
// run it and exit when done.
if (options.Scenario != "none")
@@ -788,7 +796,7 @@ public class UICatalogApp
{
if (_statusBar.NeedsLayout)
{
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
}
return _statusBar.Frame.Height;
})),
@@ -817,7 +825,7 @@ public class UICatalogApp
{
if (_statusBar.NeedsLayout)
{
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
}
return _statusBar.Frame.Height;
})),
@@ -1378,6 +1386,8 @@ public class UICatalogApp
public string Scenario;
public uint BenchmarkTimeout;
public bool Benchmark;
public string ResultsFile;

View File

@@ -4629,6 +4629,90 @@ ssb
Assert.Equal (expectedWrappedText, wrappedText);
}
[Theory]
[InlineData (
"Les Mise\u0301rables",
14,
-1,
false,
new [] { "Les Misérables" },
"Les Misérables"
)]
[InlineData (
"Les Mise\u0328\u0301rables",
14,
-2,
false,
new [] { "Les Misę́rables" },
"Les Misę́rables"
)]
public void Format_Combining_Marks_Alignments (
string text,
int maxWidth,
int widthOffset,
bool wrap,
IEnumerable<string> resultLines,
string expectedText
)
{
Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
// Horizontal text direction
foreach (Alignment alignment in Enum.GetValues (typeof (Alignment)))
{
TextFormatter tf = new () { Text = text, ConstrainToSize = new (maxWidth, 1), WordWrap = wrap, Alignment = alignment };
List<string> list = TextFormatter.Format (
text,
maxWidth,
alignment,
wrap,
tf.PreserveTrailingSpaces,
tf.TabWidth,
tf.Direction,
tf.MultiLine,
tf);
Assert.Equal (list.Count, resultLines.Count ());
Assert.Equal (resultLines, list);
var formattedText = string.Empty;
foreach (string txt in list)
{
formattedText += txt;
}
Assert.Equal (expectedText, formattedText);
}
// Vertical text direction
foreach (Alignment alignment in Enum.GetValues (typeof (Alignment)))
{
TextFormatter tf = new ()
{ Text = text, ConstrainToSize = new (1, maxWidth), WordWrap = wrap, VerticalAlignment = alignment, Direction = TextDirection.TopBottom_LeftRight };
List<string> list = TextFormatter.Format (
text,
maxWidth,
alignment,
wrap,
tf.PreserveTrailingSpaces,
tf.TabWidth,
tf.Direction,
tf.MultiLine,
tf);
Assert.Equal (list.Count, resultLines.Count ());
Assert.Equal (resultLines, list);
var formattedText = string.Empty;
foreach (string txt in list)
{
formattedText += txt;
}
Assert.Equal (expectedText, formattedText);
}
}
public static IEnumerable<object []> FormatEnvironmentNewLine =>
new List<object []>
{