Revert "Fixes #1743 - CharMap renders painfully slow"

This reverts commit 3b5d8e9780.
This commit is contained in:
Charlie Kindel
2022-11-02 15:33:16 -06:00
parent 3b5d8e9780
commit 9945c2dd54
7 changed files with 111 additions and 128 deletions

View File

@@ -683,7 +683,7 @@ namespace Terminal.Gui {
public abstract void Move (int col, int row);
/// <summary>
/// Adds the specified rune to the display at the current cursor position.
/// Adds the specified rune to the display at the current cursor position
/// </summary>
/// <param name="rune">Rune to add.</param>
public abstract void AddRune (Rune rune);
@@ -717,11 +717,10 @@ namespace Terminal.Gui {
col >= 0 && row >= 0 && col < Cols && row < Rows && clip.Contains (col, row);
/// <summary>
/// Adds the <paramref name="str"/> to the display at the cursor position.
/// Adds the specified
/// </summary>
/// <param name="str">String.</param>
public abstract void AddStr (ustring str);
/// <summary>
/// Prepare the driver and set the key and mouse events handlers.
/// </summary>

View File

@@ -3080,17 +3080,12 @@ namespace Terminal.Gui {
/// <param name="view">The view.</param>
/// <param name="method">The method name.</param>
/// <returns><see langword="true"/> if it's overridden, <see langword="false"/> otherwise.</returns>
public static bool IsOverridden (View view, string method)
public bool IsOverridden (View view, string method)
{
MethodInfo m = view.GetType ().GetMethod (method,
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.DeclaredOnly);
if (m == null) {
return false;
}
return m.GetBaseDefinition ().DeclaringType != m.DeclaringType;
Type t = view.GetType ();
MethodInfo m = t.GetMethod (method);
return (m.DeclaringType == t || m.ReflectedType == t) && m.GetBaseDefinition ().DeclaringType == typeof (Responder);
}
}
}

View File

@@ -462,7 +462,7 @@ namespace Terminal.Gui {
return;
}
Driver.SetAttribute (Host.HasFocus ? ColorScheme.Focus : GetNormalColor ());
Driver.SetAttribute (GetNormalColor ());
if ((vertical && Bounds.Height == 0) || (!vertical && Bounds.Width == 0)) {
return;
@@ -613,13 +613,13 @@ namespace Terminal.Gui {
int posBarOffset;
///<inheritdoc/>
public override bool MouseEvent (MouseEvent mouseEvent)
public override bool MouseEvent (MouseEvent me)
{
if (mouseEvent.Flags != MouseFlags.Button1Pressed && mouseEvent.Flags != MouseFlags.Button1DoubleClicked &&
!mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) &&
mouseEvent.Flags != MouseFlags.Button1Released && mouseEvent.Flags != MouseFlags.WheeledDown &&
mouseEvent.Flags != MouseFlags.WheeledUp && mouseEvent.Flags != MouseFlags.WheeledRight &&
mouseEvent.Flags != MouseFlags.WheeledLeft && mouseEvent.Flags != MouseFlags.Button1TripleClicked) {
if (me.Flags != MouseFlags.Button1Pressed && me.Flags != MouseFlags.Button1DoubleClicked &&
!me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) &&
me.Flags != MouseFlags.Button1Released && me.Flags != MouseFlags.WheeledDown &&
me.Flags != MouseFlags.WheeledUp && me.Flags != MouseFlags.WheeledRight &&
me.Flags != MouseFlags.WheeledLeft && me.Flags != MouseFlags.Button1TripleClicked) {
return false;
}
@@ -630,24 +630,24 @@ namespace Terminal.Gui {
Host.SetFocus ();
}
int location = vertical ? mouseEvent.Y : mouseEvent.X;
int location = vertical ? me.Y : me.X;
int barsize = vertical ? Bounds.Height : Bounds.Width;
int posTopLeftTee = vertical ? posTopTee + 1 : posLeftTee + 1;
int posBottomRightTee = vertical ? posBottomTee + 1 : posRightTee + 1;
barsize -= 2;
var pos = Position;
if (mouseEvent.Flags != MouseFlags.Button1Released
if (me.Flags != MouseFlags.Button1Released
&& (Application.MouseGrabView == null || Application.MouseGrabView != this)) {
Application.GrabMouse (this);
} else if (mouseEvent.Flags == MouseFlags.Button1Released && Application.MouseGrabView != null && Application.MouseGrabView == this) {
} else if (me.Flags == MouseFlags.Button1Released && Application.MouseGrabView != null && Application.MouseGrabView == this) {
lastLocation = -1;
Application.UngrabMouse ();
return true;
}
if (showScrollIndicator && (mouseEvent.Flags == MouseFlags.WheeledDown || mouseEvent.Flags == MouseFlags.WheeledUp ||
mouseEvent.Flags == MouseFlags.WheeledRight || mouseEvent.Flags == MouseFlags.WheeledLeft)) {
return Host.MouseEvent (mouseEvent);
if (showScrollIndicator && (me.Flags == MouseFlags.WheeledDown || me.Flags == MouseFlags.WheeledUp ||
me.Flags == MouseFlags.WheeledRight || me.Flags == MouseFlags.WheeledLeft)) {
return Host.MouseEvent (me);
}
if (location == 0) {
@@ -668,7 +668,7 @@ namespace Terminal.Gui {
//}
if (lastLocation > -1 || (location >= posTopLeftTee && location <= posBottomRightTee
&& mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) {
&& me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) {
if (lastLocation == -1) {
lastLocation = location;
posBarOffset = keepContentAlwaysInViewport ? Math.Max (location - posTopLeftTee, 1) : 0;

View File

@@ -32,7 +32,6 @@ namespace Terminal.Gui {
private class ContentView : View {
public ContentView (Rect frame) : base (frame)
{
CanFocus = true;
}
}
@@ -326,7 +325,7 @@ namespace Terminal.Gui {
{
Driver.SetAttribute (GetNormalColor ());
SetViewsNeedsDisplay ();
//Clear ();
Clear ();
var savedClip = ClipToBounds ();
OnDrawContent (new Rect (ContentOffset,
@@ -508,7 +507,7 @@ namespace Terminal.Gui {
{
if (me.Flags != MouseFlags.WheeledDown && me.Flags != MouseFlags.WheeledUp &&
me.Flags != MouseFlags.WheeledRight && me.Flags != MouseFlags.WheeledLeft &&
// me.Flags != MouseFlags.Button1Pressed && me.Flags != MouseFlags.Button1Clicked &&
me.Flags != MouseFlags.Button1Pressed && me.Flags != MouseFlags.Button1Clicked &&
!me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) {
return false;
}

View File

@@ -44,10 +44,6 @@
"WSL": {
"commandName": "WSL2",
"distributionName": ""
},
"Charmap": {
"commandName": "Project",
"commandLineArgs": "\"Character Map\""
}
}
}

View File

@@ -2,7 +2,6 @@
//#define BASE_DRAW_CONTENT
using NStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -12,12 +11,11 @@ using Rune = System.Rune;
namespace UICatalog.Scenarios {
/// <summary>
/// This Scenario demonstrates building a custom control (a class deriving from View) that:
/// - Provides a "Character Map" application (like Windows' charmap.exe).
/// - Provides a simple "Character Map" application (like Windows' charmap.exe).
/// - Helps test unicode character rendering in Terminal.Gui
/// - Illustrates how to use ScrollView to do infinite scrolling
/// </summary>
[ScenarioMetadata (Name: "Character Map",
Description: "A Unicode character set viewier built as a custom control using the ScrollView control.")]
[ScenarioMetadata (Name: "Character Map", Description: "A Unicode character set viewier built as a custom control using the ScrollView control.")]
[ScenarioCategory ("Text and Formatting")]
[ScenarioCategory ("Controls")]
[ScenarioCategory ("ScrollView")]
@@ -28,15 +26,28 @@ namespace UICatalog.Scenarios {
_charMap = new CharMap () {
X = 0,
Y = 0,
Width = CharMap.RowWidth + 2,
Height = Dim.Fill (),
Start = 0x2500,
ColorScheme = Colors.Dialog,
CanFocus = true,
};
Win.Add (_charMap);
var label = new Label ("Jump To Unicode Block:") { X = Pos.Right (_charMap) + 1, Y = Pos.Y (_charMap) };
Win.Add (label);
(ustring radioLabel, int start, int end) CreateRadio (ustring title, int start, int end)
{
return ($"{title} (U+{start:x5}-{end:x5})", start, end);
}
var radioItems = new (ustring radioLabel, int start, int end) [] {
CreateRadio("ASCII Control Characters", 0x00, 0x1F),
CreateRadio("ASCII Control Characterss", 0x00, 0x1F),
CreateRadio("C0 Control Characters", 0x80, 0x9f),
CreateRadio("Hangul Jamo", 0x1100, 0x11ff), // This is where wide chars tend to start
CreateRadio("Currency Symbols", 0x20A0, 0x20CF),
CreateRadio("Letter-like Symbols", 0x2100, 0x214F),
CreateRadio("Letterlike Symbols", 0x2100, 0x214F),
CreateRadio("Arrows", 0x2190, 0x21ff),
CreateRadio("Mathematical symbols", 0x2200, 0x22ff),
CreateRadio("Miscellaneous Technical", 0x2300, 0x23ff),
@@ -44,25 +55,17 @@ namespace UICatalog.Scenarios {
CreateRadio("Miscellaneous Symbols", 0x2600, 0x26ff),
CreateRadio("Dingbats", 0x2700, 0x27ff),
CreateRadio("Braille", 0x2800, 0x28ff),
CreateRadio("Miscellaneous Symbols & Arrows", 0x2b00, 0x2bff),
CreateRadio("Alphabetic Pres. Forms", 0xFB00, 0xFb4f),
CreateRadio("Cuneiform Num. and Punct.", 0x12400, 0x1240f),
CreateRadio("Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff),
CreateRadio("Alphabetic Presentation Forms", 0xFB00, 0xFb4f),
CreateRadio("Cuneiform Numbers and Punctuation", 0x12400, 0x1240f),
CreateRadio("Chess Symbols", 0x1FA00, 0x1FA0f),
CreateRadio("End", CharMap.MaxCodePointVal - 16, CharMap.MaxCodePointVal),
};
(ustring radioLabel, int start, int end) CreateRadio (ustring title, int start, int end)
{
return ($"{title} (U+{start:x5}-{end:x5})", start, end);
}
Win.Add (_charMap);
var label = new Label ("Jump To Unicode Block:") { X = Pos.Right (_charMap) + 1, Y = Pos.Y (_charMap) };
Win.Add (label);
var jumpList = new RadioGroup (radioItems.Select (t => t.radioLabel).ToArray ()) {
X = Pos.X (label),
Y = Pos.Bottom (label),
Width = radioItems.Max (r => r.radioLabel.Length) + 3,
Width = Dim.Fill (),
SelectedItem = 8
};
jumpList.SelectedItemChanged += (args) => {
@@ -73,9 +76,11 @@ namespace UICatalog.Scenarios {
jumpList.Refresh ();
jumpList.SetFocus ();
}
_charMap.Width = Dim.Fill () - jumpList.Width;
public override void Run ()
{
base.Run ();
}
}
@@ -93,90 +98,97 @@ namespace UICatalog.Scenarios {
SetNeedsDisplay ();
}
}
int _start = 0x2500;
public const int COLUMN_WIDTH = 3;
public const int ROW_HEIGHT = 1;
public const int H_SPACE = 2;
public const int V_SPACE = 2;
public static int MaxCodePointVal => 0x10FFFF;
public static int RowLabelWidth => $"U+{MaxCodePointVal:x5}".Length;
public static int RowWidth => RowLabelWidth + (COLUMN_WIDTH * 16);
// Row Header + space + (space + char + space)
public static int RowHeaderWidth => $"U+{MaxCodePointVal:x5}".Length;
public static int RowWidth => RowHeaderWidth + (H_SPACE * 16);
public CharMap ()
{
ColorScheme = Colors.Dialog;
CanFocus = true;
ContentSize = new Size (CharMap.RowWidth, MaxCodePointVal / 16);
ShowVerticalScrollIndicator = true;
ShowHorizontalScrollIndicator = false;
LayoutComplete += (args) => {
if (Bounds.Width < RowWidth) {
if (Bounds.Width <= RowWidth) {
ShowHorizontalScrollIndicator = true;
} else {
ShowHorizontalScrollIndicator = false;
// Snap 1st column into view if it's been scrolled horizontally
ContentOffset = new Point (0, ContentOffset.Y);
SetNeedsDisplay ();
}
};
DrawContent += CharMap_DrawContent;
#if DRAW_CONTENT
AddCommand (Command.ScrollUp, () => { ScrollUp (1); return true; });
AddCommand (Command.ScrollDown, () => { ScrollDown (1); return true; });
AddCommand (Command.ScrollLeft, () => { ScrollLeft (1); return true; });
AddCommand (Command.ScrollRight, () => { ScrollRight (1); return true; });
DrawContent += CharMap_DrawContent;
#endif
}
private void CharMap_DrawContent (Rect viewport)
{
var oldClip = Driver.Clip;
Driver.Clip = Frame;
// Redraw doesn't know about the scroll indicators, so if off, add one to height
if (!ShowHorizontalScrollIndicator) {
Driver.Clip = new Rect (Frame.X, Frame.Y, Frame.Width, Frame.Height + 1);
}
Driver.SetAttribute (HasFocus ? ColorScheme.HotFocus : ColorScheme.Focus);
Move (0, 0);
Driver.AddStr (new string (' ', RowLabelWidth + 1));
for (int hexDigit = 0; hexDigit < 16; hexDigit++) {
var x = ContentOffset.X + RowLabelWidth + (hexDigit * COLUMN_WIDTH);
if (x > RowLabelWidth - 2) {
Move (x, 0);
Driver.AddStr ($" {hexDigit:x} ");
}
}
//Move (RowWidth, 0);
//Driver.AddRune (' ');
//Rune ReplaceNonPrintables (Rune c)
//{
// if (c < 0x20) {
// return new Rune (c + 0x2400); // U+25A1 □ WHITE SQUARE
// } else {
// return c;
// }
//}
var firstColumnX = viewport.X + RowLabelWidth;
for (int row = -ContentOffset.Y, y = 0; row <= (-ContentOffset.Y) + (Bounds.Height / ROW_HEIGHT); row++, y += ROW_HEIGHT) {
int val = (row) * 16;
Driver.SetAttribute (GetNormalColor ());
Move (firstColumnX, y + 1);
Driver.AddStr (new string (' ', 16 * COLUMN_WIDTH));
ContentSize = new Size (CharMap.RowWidth, MaxCodePointVal / 16 + Frame.Height - 1);
for (int header = 0; header < 16; header++) {
Move (viewport.X + RowHeaderWidth + (header * H_SPACE), 0);
Driver.AddStr ($" {header:x} ");
}
for (int row = 0, y = 0; row < viewport.Height / 2 - 1; row++, y += V_SPACE) {
int val = (-viewport.Y + row) * 16;
if (val < MaxCodePointVal) {
Driver.SetAttribute (GetNormalColor ());
for (int col = 0; col < 16; col++) {
var rune = new Rune ((uint)((uint)val + col));
//if (rune >= 0x00D800 && rune <= 0x00DFFF) {
// if (col == 0) {
// Driver.AddStr ("Reserved for surrogate pairs.");
// }
// continue;
//}
Move (firstColumnX + (col * COLUMN_WIDTH) + 1, y + 1);
Driver.AddRune (rune);
}
var rowLabel = $"U+{val / 16:x4}x";
Move (0, y + 1);
Driver.SetAttribute (HasFocus ? ColorScheme.HotFocus : ColorScheme.Focus);
var rowLabel = $"U+{val / 16:x4}x ";
Driver.AddStr (rowLabel);
var prevColWasWide = false;
for (int col = 0; col < 16; col++) {
var rune = new Rune ((uint)((uint)(-viewport.Y + row) * 16 + col));
Move (viewport.X + RowHeaderWidth + (col * H_SPACE) + (prevColWasWide ? 0 : 1), y + 1);
if (rune >= 0x00D800 && rune <= 0x00DFFF) {
if (col == 0) {
Driver.AddStr ("Reserved to surrogate pairs.");
}
continue;
}
Driver.AddRune (rune);
//prevColWasWide = Rune.ColumnWidth (rune) > 1;
}
}
}
Driver.Clip = oldClip;
}
#if BASE_DRAW_CONTENT
public override void OnDrawContent (Rect viewport)
{
CharMap_DrawContent (viewport);
base.OnDrawContent (viewport);
}
#endif
public override bool ProcessKey (KeyEvent kb)
{
if (kb.Key == Key.PageDown) {
ContentOffset = new Point (0, ContentOffset.Y - Bounds.Height / 2 + 1);
return true;
}
if (kb.Key == Key.PageUp) {
if (ContentOffset.Y + Bounds.Height / 2 - 1 < 0) {
ContentOffset = new Point (0, ContentOffset.Y + Bounds.Height / 2 - 1);
} else {
ContentOffset = Point.Empty;
}
return true;
}
return base.ProcessKey (kb);
}
protected override void Dispose (bool disposing)

View File

@@ -4062,23 +4062,5 @@ This is a tes
Assert.False (view.IsKeyPress);
Assert.True (view.IsKeyUp);
}
[Fact, AutoInitShutdown]
public void IsOverridden_False_IfNotOverriden ()
{
var view = new DerivedView () { Text = "Derived View does not override MouseEvent or Redraw", Width = 10, Height = 10 };
Assert.False (View.IsOverridden (view, "MouseEvent"));
Assert.False (View.IsOverridden (view, "Redraw"));
}
[Fact, AutoInitShutdown]
public void IsOverridden_True_IfOverriden ()
{
var view = new ScrollBarView () { Text = "ScrollBarView overrides both MouseEvent and Redraw", Width = 10, Height = 10 };
Assert.True (View.IsOverridden (view, "MouseEvent"));
Assert.True (View.IsOverridden (view, "Redraw"));
}
}
}