mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Fixed almost all issues * code comments * fixed copilot suggestion * Add Unicode filtering and improve context menu handling Enabled nullable reference types for better null safety. Added a Unicode category filter to `CharacterMap` via the new `ShowUnicodeCategory` property and `OptionSelector`. Updated rendering logic to dynamically manage visible rows based on the filter, improving performance and usability. Refactored menu items to include the Unicode category selector. Enhanced `TextView` context menu handling to support mouse-based positioning. Performed miscellaneous code cleanup and added comments for improved readability and maintainability. * Fix Unicode rendering and simplify CombiningMarks Updated `RuneExtensions.GetColumns` to handle specific Unicode glyphs (I Ching symbols) rendered as double-width in Windows Terminal, despite being single-width per Unicode. Added a workaround to return `2` for these glyphs and fallback to `UnicodeCalculator.GetWidth` for others. Simplified `CombiningMarks` by removing examples for Unicode characters `\u0600` and `\u0301`, streamlining the scenario. Referenced PR #4255 for context on the workaround. * Update RuneTests with new Unicode test cases and fixes Added new test cases for Unicode characters U+d7b0 (ힰ) and U+f61e () with expected parameters. Updated the test case for U+4dc0 (䷀) to adjust the second parameter from 1 to 2 and added references to the Microsoft Terminal Unicode width overrides file and GitHub issue #19389. Existing test cases for other Unicode characters remain unchanged. * Update Terminal.Gui/Views/CharMap/CharMap.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update comments in GetColumns method for clarity Updated comments in the `GetColumns` method of the `RuneExtensions` class to replace "HACK" with "TODO" and reference issue #4259 instead of pull request #4255. This change clarifies that the code is a temporary measure and should be removed once the issue is resolved. No functional changes were made to the code logic. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
@@ -24,6 +21,33 @@ public class CharacterMap : Scenario
|
||||
private Label? _errorLabel;
|
||||
private TableView? _categoryList;
|
||||
private CharMap? _charMap;
|
||||
private OptionSelector? _unicodeCategorySelector;
|
||||
|
||||
public override List<Key> GetDemoKeyStrokes ()
|
||||
{
|
||||
List<Key> keys = new ();
|
||||
|
||||
for (var i = 0; i < 200; i++)
|
||||
{
|
||||
keys.Add (Key.CursorDown);
|
||||
}
|
||||
|
||||
// Category table
|
||||
keys.Add (Key.Tab.WithShift);
|
||||
|
||||
// Block elements
|
||||
keys.Add (Key.B);
|
||||
keys.Add (Key.L);
|
||||
|
||||
keys.Add (Key.Tab);
|
||||
|
||||
for (var i = 0; i < 200; i++)
|
||||
{
|
||||
keys.Add (Key.CursorLeft);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Don't create a Window, just return the top-level view
|
||||
public override void Main ()
|
||||
@@ -39,9 +63,9 @@ public class CharacterMap : Scenario
|
||||
{
|
||||
X = 0,
|
||||
Y = 1,
|
||||
Height = Dim.Fill (),
|
||||
// SchemeName = "Base"
|
||||
Height = Dim.Fill ()
|
||||
|
||||
// SchemeName = "Base"
|
||||
};
|
||||
top.Add (_charMap);
|
||||
|
||||
@@ -50,7 +74,8 @@ public class CharacterMap : Scenario
|
||||
X = Pos.Right (_charMap) + 1,
|
||||
Y = Pos.Y (_charMap),
|
||||
HotKeySpecifier = (Rune)'_',
|
||||
Text = "_Jump To:",
|
||||
Text = "_Jump To:"
|
||||
|
||||
//SchemeName = "Dialog"
|
||||
};
|
||||
top.Add (jumpLabel);
|
||||
@@ -60,7 +85,8 @@ public class CharacterMap : Scenario
|
||||
X = Pos.Right (jumpLabel) + 1,
|
||||
Y = Pos.Y (_charMap),
|
||||
Width = 17,
|
||||
Caption = "e.g. 01BE3 or ✈",
|
||||
Caption = "e.g. 01BE3 or ✈"
|
||||
|
||||
//SchemeName = "Dialog"
|
||||
};
|
||||
top.Add (jumpEdit);
|
||||
@@ -89,10 +115,12 @@ public class CharacterMap : Scenario
|
||||
|
||||
jumpEdit.Accepting += JumpEditOnAccept;
|
||||
|
||||
_categoryList = new () {
|
||||
X = Pos.Right (_charMap),
|
||||
Y = Pos.Bottom (jumpLabel),
|
||||
Height = Dim.Fill (),
|
||||
_categoryList = new ()
|
||||
{
|
||||
X = Pos.Right (_charMap),
|
||||
Y = Pos.Bottom (jumpLabel),
|
||||
Height = Dim.Fill ()
|
||||
|
||||
//SchemeName = "Dialog"
|
||||
};
|
||||
_categoryList.FullRowSelect = true;
|
||||
@@ -165,7 +193,7 @@ public class CharacterMap : Scenario
|
||||
),
|
||||
new (
|
||||
"_Options",
|
||||
new MenuItemv2 [] { CreateMenuShowWidth () }
|
||||
[CreateMenuShowWidth (), CreateMenuUnicodeCategorySelector ()]
|
||||
)
|
||||
]
|
||||
};
|
||||
@@ -317,6 +345,7 @@ public class CharacterMap : Scenario
|
||||
CheckedState = _charMap!.ShowGlyphWidths ? CheckState.Checked : CheckState.None
|
||||
};
|
||||
var item = new MenuItemv2 { CommandView = cb };
|
||||
|
||||
item.Action += () =>
|
||||
{
|
||||
if (_charMap is { })
|
||||
@@ -328,29 +357,48 @@ public class CharacterMap : Scenario
|
||||
return item;
|
||||
}
|
||||
|
||||
public override List<Key> GetDemoKeyStrokes ()
|
||||
private MenuItemv2 CreateMenuUnicodeCategorySelector ()
|
||||
{
|
||||
List<Key> keys = new ();
|
||||
// First option is "All" (no filter), followed by all UnicodeCategory names
|
||||
string [] allCategoryNames = Enum.GetNames<UnicodeCategory> ();
|
||||
var options = new string [allCategoryNames.Length + 1];
|
||||
options [0] = "All";
|
||||
Array.Copy (allCategoryNames, 0, options, 1, allCategoryNames.Length);
|
||||
|
||||
for (var i = 0; i < 200; i++)
|
||||
// TODO: When #4126 is merged update this to use OptionSelector<UnicodeCategory?>
|
||||
var selector = new OptionSelector
|
||||
{
|
||||
keys.Add (Key.CursorDown);
|
||||
}
|
||||
AssignHotKeysToCheckBoxes = true,
|
||||
Options = options
|
||||
};
|
||||
|
||||
// Category table
|
||||
keys.Add (Key.Tab.WithShift);
|
||||
_unicodeCategorySelector = selector;
|
||||
|
||||
// Block elements
|
||||
keys.Add (Key.B);
|
||||
keys.Add (Key.L);
|
||||
// Default to "All"
|
||||
selector.SelectedItem = 0;
|
||||
_charMap!.ShowUnicodeCategory = null;
|
||||
|
||||
keys.Add (Key.Tab);
|
||||
selector.SelectedItemChanged += (s, e) =>
|
||||
{
|
||||
int? idx = selector.SelectedItem;
|
||||
|
||||
for (var i = 0; i < 200; i++)
|
||||
{
|
||||
keys.Add (Key.CursorLeft);
|
||||
}
|
||||
if (idx is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return keys;
|
||||
if (idx.Value == 0)
|
||||
{
|
||||
_charMap.ShowUnicodeCategory = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Map index to UnicodeCategory (offset by 1 because 0 is "All")
|
||||
UnicodeCategory cat = Enum.GetValues<UnicodeCategory> () [idx.Value - 1];
|
||||
_charMap.ShowUnicodeCategory = cat;
|
||||
}
|
||||
};
|
||||
|
||||
return new() { CommandView = selector };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,22 +11,78 @@ public class CombiningMarks : Scenario
|
||||
var top = new Toplevel ();
|
||||
|
||||
top.DrawComplete += (s, e) =>
|
||||
{
|
||||
top.Move (0, 0);
|
||||
top.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
|
||||
top.Move (0, 2);
|
||||
top.AddStr ("\u0301\u0301\u0328<- \"\\u301\\u301\\u328]\" using AddStr.");
|
||||
top.Move (0, 3);
|
||||
top.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u301\\u301\\u328]\" using AddStr.");
|
||||
top.Move (0, 4);
|
||||
top.AddRune ('[');
|
||||
top.AddRune ('a');
|
||||
top.AddRune ('\u0301');
|
||||
top.AddRune ('\u0301');
|
||||
top.AddRune ('\u0328');
|
||||
top.AddRune (']');
|
||||
top.AddStr ("<- \"[a\\u301\\u301\\u328]\" using AddRune for each.");
|
||||
};
|
||||
{
|
||||
// Forces reset _lineColsOffset because we're dealing with direct draw
|
||||
Application.ClearScreenNextIteration = true;
|
||||
|
||||
var i = -1;
|
||||
top.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("\u0301<- \"\\u0301\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\u0301]<- \"[\\u0301]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[ \u0301]<- \"[ \\u0301]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\u0301 ]<- \"[\\u0301 ]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("\u0301\u0301\u0328<- \"\\u0301\\u0301\\u0328\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\u0301\u0301\u0328]<- \"[\\u0301\\u0301\\u0328]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u0301\\u0301\\u0328]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddRune ('[');
|
||||
top.AddRune ('a');
|
||||
top.AddRune ('\u0301');
|
||||
top.AddRune ('\u0301');
|
||||
top.AddRune ('\u0328');
|
||||
top.AddRune (']');
|
||||
top.AddStr ("<- \"[a\\u0301\\u0301\\u0328]\" using AddRune for each.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u0301\\u0301\\u0328]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("\u00ad<- \"\\u00ad\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\u00ad]<- \"[\\u00ad]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddRune ('[');
|
||||
top.AddRune ('\u00ad');
|
||||
top.AddRune (']');
|
||||
top.AddStr ("<- \"[\\u00ad]\" using AddRune for each.");
|
||||
i++;
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("From now on we are using TextFormatter");
|
||||
TextFormatter tf = new () { Text = "[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using TextFormatter." };
|
||||
tf.Draw (new (0, ++i, tf.Text.Length, 1), top.GetAttributeForRole (VisualRole.Normal), top.GetAttributeForRole (VisualRole.Normal));
|
||||
tf.Text = "[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using TextFormatter.";
|
||||
tf.Draw (new (0, ++i, tf.Text.Length, 1), top.GetAttributeForRole (VisualRole.Normal), top.GetAttributeForRole (VisualRole.Normal));
|
||||
i++;
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("From now on we are using Surrogate pairs with combining diacritics");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\ud835\udc4b\u0302]<- \"[\\ud835\\udc4b\\u0302]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\ud83d\udc68\ud83e\uddd2]<- \"[\\ud83d\\udc68\\ud83e\\uddd2]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("\u200d<- \"\\u200d\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\u200d]<- \"[\\u200d]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\ud83d\udc68\u200d\ud83e\uddd2]<- \"[\\ud83d\\udc68\\u200d\\ud83e\\uddd2]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\U0001F469\U0001F9D2]<- \"[\\U0001F469\\U0001F9D2]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\U0001F469\u200D\U0001F9D2]<- \"[\\U0001F469\\u200D\\U0001F9D2]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\U0001F468\U0001F469\U0001F9D2]<- \"[\\U0001F468\\U0001F469\\U0001F9D2]\" using AddStr.");
|
||||
top.Move (0, ++i);
|
||||
top.AddStr ("[\U0001F468\u200D\U0001F469\u200D\U0001F9D2]<- \"[\\U0001F468\\u200D\\U0001F469\\u200D\\U0001F9D2]\" using AddStr.");
|
||||
};
|
||||
|
||||
Application.Run (top);
|
||||
top.Dispose ();
|
||||
|
||||
Reference in New Issue
Block a user