Skip to content

Commit

Permalink
Fixes #666. Refactor ConsoleDrivers to simplify and remove duplicat…
Browse files Browse the repository at this point in the history
…ed code (#2612)

* Added ClipRegion; cleaned up driver code

* clip region unit tests

* api docs

* Moved color stuff from ConsoleDriver to Color.cs

* Removes unused ConsoleDriver APIs

* Code cleanup and Removes unused ConsoleDriver APIs

* Code cleanup and Removes unused ConsoleDriver APIs

* Work around #2610

* adjusted unit tests

* initial commit

* Made Rows, Cols, Top, Left virtual

* Made Clipboard non-virtual

* Made EnableConsoleScrolling  non-virtual

* Made Contents non-virtual

* Pulled Row/Col up

* Made MoveTo virtual; fixed stupid FakeDriver cursor issue

* Made CurrentAttribute non-virtual

* Made SetAttribute  non-virtual

* Moved clipboard code out

* Code cleanup

* Removes dependecy on NStack from ConsoleDrivers - WIP

* Fixed unit tests

* Fixed unit tests

* Added list of unit tests needed

* Did some perf testing; tweaked code and charmap to address

* Brough in code from PR #2264 (but commented)

* Tons of code cleanup

* Fighting with ScrollView

* Fixing bugs

* Fixed TabView tests

* Fixed View.Visible test that was not really working

* Fixed unit tests

* Cleaned up clipboard APIs in attempt to track down unit test failure

* Add Cut_Preserves_Selection test

* Removed invalid code

* Removed invalid test code; unit tests now pass

* EscSeq* - Adjusted naming, added more sequences, made code more consistent, simplified, etc...

* Added CSI_SetGraphicsRendition

* NetDriver code cleanup

* code cleanup

* Cleaned up color handling in NetDriver

* refixed tabview unit test

* WindowsDriver color code cleanup

* WindowsDriver color code cleanup

* CursesDriver color code cleanup

* CursesDriver - Adding _BOLD has no effect. Further up the stack we cast the return of ColorToCursesColor from int to short and the _BOLD values don't fit in a short.

* CursesDriver color code - make code more accurate

* CursesDriver color code - make code more accurate

* Simplified ConsoleDriver.GetColors API

* Simplified ConsoleDriver.GetColors API further

* Improved encapslation of Attribute; prep for TrueColor & other attributes like blink

* Fixes #2249. CharacterMap isn't refreshing well non-BMP code points on scroll.

* Use GetRange to take some of the runes before convert to string.

* Attempting to fix unit tests not being cleaned up

* Fixes #2658 - ConsoleDriver.IsRuneSupported

* Fixes #2658 - ConsoleDriver.IsRuneSupported (for WindowsDriver)

* Check all the range values and not only the max value.

* Reducing code.

* Fixes #2674 - Unit test process doesn't exit

* Changed Cell to support IsDirty and list of Runes

* add support for rendering TrueColor output on Windows merging veeman & tznind code

* add colorconverter changes

* fixed merged v2_develop

* Fixing merge bugs

* Fixed merge bugs

* Fixed merge bugs - all unit tests pass

* Debugging netdriver

* More netdriver diag

* API docs for escutils

* Update unicode scenario to stress more stuff

* Contents: Now a 2D array of Cells; WIP

* AddRune and ClearContents no longer virtual/abstract

* WindowsDriver renders correctly again

* Progress on Curses

* Progress on Curses

* broke windowsdriver

* Cleaned up FakeMainLoop

* Cleaned up some build warnings

* Removed _init from AutoInitShutdown as it's not needed anymore

* Removed unused var

* Removed unused var

* Fixed nullabiltiy warning in LineCanvas

* Fixed charmap crash

* Fixes #2758 in v2

* Port testonfail fix to v2

* Remove EnableConsoleScrolling

* Backport #2764 from develop (clear last line)

* Remove uneeded usings

* Progress on unicode

* Merged in changes from PR #2786, Fixes #2784

* revamp charmap rendering

* Charmap option to show glyph widths

* Fixed issue with wide glpyhs being overwritten

* Fixed charmap startcodepoint change issue

* Added abiltiy to see ncurses verison/lib

* Fought with CursesDriver; giving up for now. See notes.

* Leverage Wcwidth nuget library instaed of our own tables

* enhanced charmap Details dialog

* Final attempt at fixing curses

---------

Co-authored-by: BDisp <bd.bdisp@gmail.com>
Co-authored-by: adstep <stephensonadamj@gmail.com>
  • Loading branch information
3 people authored Aug 9, 2023
1 parent f3979b2 commit 0df485a
Show file tree
Hide file tree
Showing 101 changed files with 12,555 additions and 11,820 deletions.
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @migueldeicaza @tig
* @tig

/docs/ @tig @bdisp @tznind

# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/dotnet-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:

- name: Test
run: |
sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
dotnet test --no-restore --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings
mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:

#- name: Test to generate Code Coverage Report
# run: |
# sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
# dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings
# mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ docfx/api
docs/

UnitTests/TestResults
TestResults

#git merge files
*.orig
Expand Down
96 changes: 29 additions & 67 deletions Terminal.Gui/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Reflection;
using System.IO;
using System.Text.Json.Serialization;
using static Terminal.Gui.ConfigurationManager;

namespace Terminal.Gui {
/// <summary>
Expand Down Expand Up @@ -55,42 +54,7 @@ public static partial class Application {

// For Unit testing - ignores UseSystemConsole
internal static bool _forceFakeConsole;

private static bool? _enableConsoleScrolling;
/// <summary>
/// The current <see cref="ConsoleDriver.EnableConsoleScrolling"/> used in the terminal.
/// </summary>
/// <remarks>
/// <para>
/// If <see langword="false"/> (the default) the height of the Terminal.Gui application (<see cref="ConsoleDriver.Rows"/>)
/// tracks to the height of the visible console view when the console is resized. In this case
/// scrolling in the console will be disabled and all <see cref="ConsoleDriver.Rows"/> will remain visible.
/// </para>
/// <para>
/// If <see langword="true"/> then height of the Terminal.Gui application <see cref="ConsoleDriver.Rows"/> only tracks
/// the height of the visible console view when the console is made larger (the application will only grow in height, never shrink).
/// In this case console scrolling is enabled and the contents (<see cref="ConsoleDriver.Rows"/> high) will scroll
/// as the console scrolls.
/// </para>
/// This API was previously named 'HeightAsBuffer` but was renamed to make its purpose more clear.
/// </remarks>
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
public static bool EnableConsoleScrolling {
get {
if (Driver == null) {
return _enableConsoleScrolling.HasValue && _enableConsoleScrolling.Value;
}
return Driver.EnableConsoleScrolling;
}
set {
_enableConsoleScrolling = value;
if (Driver == null) {
return;
}
Driver.EnableConsoleScrolling = value;
}
}


private static List<CultureInfo> _cachedSupportedCultures;

/// <summary>
Expand Down Expand Up @@ -164,7 +128,9 @@ private static List<CultureInfo> GetSupportedCultures ()
// calledViaRunT: If false (default) all state will be reset. If true the state will not be reset.
internal static void InternalInit (Func<Toplevel> topLevelFactory, ConsoleDriver driver = null, IMainLoopDriver mainLoopDriver = null, bool calledViaRunT = false)
{
if (_initialized && driver == null) return;
if (_initialized && driver == null) {
return;
}

if (_initialized) {
throw new InvalidOperationException ("Init has already been called and must be bracketed by Shutdown.");
Expand Down Expand Up @@ -224,7 +190,6 @@ internal static void InternalInit (Func<Toplevel> topLevelFactory, ConsoleDriver
MainLoop = new MainLoop (mainLoopDriver);

try {
Driver.EnableConsoleScrolling = EnableConsoleScrolling;
Driver.Init (OnTerminalResized);
} catch (InvalidOperationException ex) {
// This is a case where the driver is unable to initialize the console.
Expand Down Expand Up @@ -277,6 +242,7 @@ static void ResetState ()

// BUGBUG: OverlappedTop is not cleared here, but it should be?

MainLoop?.Stop();
MainLoop = null;
Driver?.End ();
Driver = null;
Expand All @@ -289,7 +255,6 @@ static void ResetState ()
NotifyStopRunState = null;
_initialized = false;
_mouseGrabView = null;
_enableConsoleScrolling = false;
_lastMouseOwnerView = null;

// Reset synchronization context to allow the user to run async/await,
Expand Down Expand Up @@ -552,7 +517,8 @@ public static void Run (Toplevel view, Func<Exception, bool> errorHandler = null
/// </summary>
public static void Refresh ()
{
Driver.UpdateOffScreen ();
// TODO: Figure out how to remove this call to ClearContents. Refresh should just repaint damaged areas, not clear
Driver.ClearContents();
View last = null;
foreach (var v in _toplevels.Reverse ()) {
if (v.Visible) {
Expand Down Expand Up @@ -674,13 +640,14 @@ public static void RunMainLoopIteration (ref RunState state, bool wait, ref bool
Iteration?.Invoke ();

EnsureModalOrVisibleAlwaysOnTop (state.Toplevel);
if ((state.Toplevel != Current && Current?.Modal == true)
|| (state.Toplevel != Current && Current?.Modal == false)) {
if (state.Toplevel != Current) {
OverlappedTop?.OnDeactivate (state.Toplevel);
state.Toplevel = Current;
OverlappedTop?.OnActivate (state.Toplevel);
Top.SetSubViewNeedsDisplay ();
Refresh ();
} else if (Current.SuperView == null && Current?.Modal == true) {
Refresh ();
}
if (Driver.EnsureCursorVisibility ()) {
state.Toplevel.SetNeedsDisplay ();
Expand All @@ -690,42 +657,41 @@ public static void RunMainLoopIteration (ref RunState state, bool wait, ref bool
}
firstIteration = false;

if (state.Toplevel != Top
&& (!Top._needsDisplay.IsEmpty || Top._subViewNeedsDisplay || Top.LayoutNeeded)) {
state.Toplevel.SetNeedsDisplay (state.Toplevel.Bounds);
if (state.Toplevel != Top &&
(Top.NeedsDisplay|| Top.SubViewNeedsDisplay || Top.LayoutNeeded)) {
state.Toplevel.SetNeedsDisplay (state.Toplevel.Frame);
Top.Clear ();
Top.Draw ();
foreach (var top in _toplevels.Reverse ()) {
if (top != Top && top != state.Toplevel) {
top.SetNeedsDisplay ();
top.SetSubViewNeedsDisplay ();
top.Clear ();
top.Draw ();
}
}
}
if (_toplevels.Count == 1 && state.Toplevel == Top
&& (Driver.Cols != state.Toplevel.Frame.Width || Driver.Rows != state.Toplevel.Frame.Height)
&& (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._subViewNeedsDisplay || state.Toplevel.LayoutNeeded)) {

Driver.SetAttribute (Colors.TopLevel.Normal);
state.Toplevel.Clear (new Rect (0, 0, Driver.Cols, Driver.Rows));
&& (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded)) {

state.Toplevel.Clear ();
}

if (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._subViewNeedsDisplay || state.Toplevel.LayoutNeeded
|| OverlappedChildNeedsDisplay ()) {
if (state.Toplevel.NeedsDisplay ||
state.Toplevel.SubViewNeedsDisplay ||
state.Toplevel.LayoutNeeded ||
OverlappedChildNeedsDisplay ()) {
state.Toplevel.Clear ();
state.Toplevel.Draw ();
//if (state.Toplevel.SuperView != null) {
// state.Toplevel.SuperView?.OnRenderLineCanvas ();
//} else {
// state.Toplevel.OnRenderLineCanvas ();
//}
state.Toplevel.PositionCursor ();
Driver.Refresh ();
} else {
Driver.UpdateCursor ();
}
if (state.Toplevel != Top && !state.Toplevel.Modal
&& (!Top._needsDisplay.IsEmpty || Top._subViewNeedsDisplay || Top.LayoutNeeded)) {
if (state.Toplevel != Top &&
!state.Toplevel.Modal &&
(Top.NeedsDisplay|| Top.SubViewNeedsDisplay || Top.LayoutNeeded)) {
Top.Draw ();
}
}
Expand All @@ -735,7 +701,7 @@ public static void RunMainLoopIteration (ref RunState state, bool wait, ref bool
/// </summary>
public static void DoEvents ()
{
MainLoop.Driver.Wakeup ();
MainLoop.MainLoopDriver.Wakeup ();
}

/// <summary>
Expand Down Expand Up @@ -1011,7 +977,6 @@ static void OnTerminalResized ()
{
var full = new Rect (0, 0, Driver.Cols, Driver.Rows);
TerminalResized?.Invoke (new ResizedEventArgs () { Cols = full.Width, Rows = full.Height });
Driver.Clip = full;
foreach (var t in _toplevels) {
t.SetRelativeLayout (full);
t.LayoutSubviews ();
Expand Down Expand Up @@ -1073,7 +1038,7 @@ public static void GrabMouse (View view)
if (!OnGrabbingMouse (view)) {
OnGrabbedMouse (view);
_mouseGrabView = view;
Driver.UncookMouse ();
//Driver.UncookMouse ();
}
}

Expand All @@ -1087,7 +1052,7 @@ public static void UngrabMouse ()
if (!OnUnGrabbingMouse (_mouseGrabView)) {
OnUnGrabbedMouse (_mouseGrabView);
_mouseGrabView = null;
Driver.CookMouse ();
//Driver.CookMouse ();
}
}

Expand Down Expand Up @@ -1132,10 +1097,7 @@ static void OnUnGrabbedMouse (View view)

static void ProcessMouseEvent (MouseEvent me)
{
bool OutsideBounds (Point p, Rect r)
{
return p.X < 0 || p.X > r.Right || p.Y < 0 || p.Y > r.Bottom;
}
static bool OutsideBounds (Point p, Rect r) => p.X < 0 || p.X > r.Right || p.Y < 0 || p.Y > r.Bottom;

if (IsMouseDisabled) {
return;
Expand Down
Loading

0 comments on commit 0df485a

Please sign in to comment.