diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
new file mode 100644
index 000000000..f734ea7b5
--- /dev/null
+++ b/.github/workflows/dotnetcore.yml
@@ -0,0 +1,25 @@
+name: .NET Core
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.1.101
+ - name: Install dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: Test
+ run: dotnet test --no-restore --verbosity normal
diff --git a/Designer/Designer.csproj b/Designer/Designer.csproj
index 545c2b0b9..84de5ca1d 100644
--- a/Designer/Designer.csproj
+++ b/Designer/Designer.csproj
@@ -8,6 +8,7 @@
Designer
Designer
v4.7.2
+ win-x86
diff --git a/Example/Example.csproj b/Example/Example.csproj
index dc751b396..001459c47 100644
--- a/Example/Example.csproj
+++ b/Example/Example.csproj
@@ -8,6 +8,7 @@
Terminal
Terminal
v4.7.2
+ win-x64
diff --git a/Terminal.Gui/Core.cs b/Terminal.Gui/Core.cs
index ad1fb8549..1d405ffc1 100644
--- a/Terminal.Gui/Core.cs
+++ b/Terminal.Gui/Core.cs
@@ -899,10 +899,7 @@ namespace Terminal.Gui {
Move (frame.X, frame.Y);
}
- ///
- /// Gets or sets a value indicating whether this has focus.
- ///
- /// true if has focus; otherwise, false.
+ ///
public override bool HasFocus {
get {
return base.HasFocus;
@@ -925,12 +922,14 @@ namespace Terminal.Gui {
}
}
+ ///
public override bool OnEnter ()
{
Enter?.Invoke (this, new EventArgs ());
return base.OnEnter ();
}
+ ///
public override bool OnLeave ()
{
Leave?.Invoke (this, new EventArgs ());
@@ -1072,11 +1071,11 @@ namespace Terminal.Gui {
}
///
- /// Invoked when a character key is pressed and occurs after the key down event.
+ /// Invoked when a character key is pressed and occurs after the key up event.
///
public event EventHandler KeyPress;
- /// Contains the details about the key that produced the event.
+ ///
public override bool ProcessKey (KeyEvent keyEvent)
{
KeyPress?.Invoke (this, new KeyEventEventArgs(keyEvent));
@@ -1086,7 +1085,7 @@ namespace Terminal.Gui {
return false;
}
- /// Contains the details about the key that produced the event.
+ ///
public override bool ProcessHotKey (KeyEvent keyEvent)
{
KeyPress?.Invoke (this, new KeyEventEventArgs (keyEvent));
@@ -1098,7 +1097,7 @@ namespace Terminal.Gui {
return false;
}
- /// Contains the details about the key that produced the event.
+ ///
public override bool ProcessColdKey (KeyEvent keyEvent)
{
KeyPress?.Invoke (this, new KeyEventEventArgs(keyEvent));
@@ -1145,6 +1144,7 @@ namespace Terminal.Gui {
return false;
}
+
///
/// Finds the first view in the hierarchy that wants to get the focus if nothing is currently focused, otherwise, it does nothing.
///
@@ -1415,15 +1415,13 @@ namespace Terminal.Gui {
layoutNeeded = false;
}
- ///
- /// Returns a that represents the current .
- ///
- /// A that represents the current .
+ ///
public override string ToString ()
{
return $"{GetType ().Name}({Id})({Frame})";
}
+ ///
public override bool OnMouseEnter (MouseEvent mouseEvent)
{
if (!base.OnMouseEnter (mouseEvent)) {
@@ -1433,6 +1431,7 @@ namespace Terminal.Gui {
return true;
}
+ ///
public override bool OnMouseLeave (MouseEvent mouseEvent)
{
if (!base.OnMouseLeave (mouseEvent)) {
@@ -1475,10 +1474,25 @@ namespace Terminal.Gui {
///
public class Toplevel : View {
///
- /// This flag is checked on each iteration of the mainloop and it continues
- /// running until this flag is set to false.
+ /// Gets or sets whether the for this is running or not. Setting
+ /// this property to false will cause the MainLoop to exit.
///
- public bool Running;
+ public bool Running { get; set; }
+
+ ///
+ /// Fired once the Toplevel's has started it's first iteration.
+ /// Subscribe to this event to perform tasks when the has been laid out and focus has been set.
+ /// changes. A Ready event handler is a good place to finalize initialization after calling `(topLevel)`.
+ ///
+ public event EventHandler Ready;
+
+ ///
+ /// Called from Application.RunLoop after the has entered it's first iteration of the loop.
+ ///
+ internal virtual void OnReady ()
+ {
+ Ready?.Invoke (this, EventArgs.Empty);
+ }
///
/// Initializes a new instance of the class with the specified absolute layout.
@@ -1513,6 +1527,10 @@ namespace Terminal.Gui {
return new Toplevel (new Rect (0, 0, Driver.Cols, Driver.Rows));
}
+ ///
+ /// Gets or sets a value indicating whether this can focus.
+ ///
+ /// true if can focus; otherwise, false.
public override bool CanFocus {
get => true;
}
@@ -1534,6 +1552,7 @@ namespace Terminal.Gui {
///
public bool HasStatusBar { get; set; }
+ ///
public override bool ProcessKey (KeyEvent keyEvent)
{
if (base.ProcessKey (keyEvent))
@@ -1585,6 +1604,7 @@ namespace Terminal.Gui {
return false;
}
+ ///
public override void Add (View view)
{
if (this == Application.Top) {
@@ -1596,6 +1616,7 @@ namespace Terminal.Gui {
base.Add (view);
}
+ ///
public override void Remove (View view)
{
if (this == Application.Top) {
@@ -1607,6 +1628,7 @@ namespace Terminal.Gui {
base.Remove (view);
}
+ ///
public override void RemoveAll ()
{
if (this == Application.Top) {
@@ -1661,6 +1683,7 @@ namespace Terminal.Gui {
}
}
+ ///
public override void Redraw (Rect region)
{
Application.CurrentView = this;
@@ -1843,6 +1866,7 @@ namespace Terminal.Gui {
contentView.RemoveAll ();
}
+ ///
public override void Redraw (Rect bounds)
{
Application.CurrentView = this;
@@ -1878,6 +1902,7 @@ namespace Terminal.Gui {
//
internal static Point? dragPosition;
Point start;
+ ///
public override bool MouseEvent (MouseEvent mouseEvent)
{
// FIXED:The code is currently disabled, because the
@@ -2414,8 +2439,15 @@ namespace Terminal.Gui {
if (state.Toplevel == null)
throw new ObjectDisposedException ("state");
+ bool firstIteration = true;
for (state.Toplevel.Running = true; state.Toplevel.Running;) {
if (MainLoop.EventsPending (wait)) {
+ // Notify Toplevel it's ready
+ if (firstIteration) {
+ state.Toplevel.OnReady ();
+ }
+ firstIteration = false;
+
MainLoop.MainIteration ();
Iteration?.Invoke (null, EventArgs.Empty);
} else if (wait == false)
@@ -2431,7 +2463,7 @@ namespace Terminal.Gui {
}
}
- internal static bool DebugDrawBounds;
+ internal static bool DebugDrawBounds = false;
// Need to look into why this does not work properly.
static void DrawBounds (View v)
diff --git a/Terminal.Gui/Dialogs/Dialog.cs b/Terminal.Gui/Dialogs/Dialog.cs
index a1f809b97..2aef337d5 100644
--- a/Terminal.Gui/Dialogs/Dialog.cs
+++ b/Terminal.Gui/Dialogs/Dialog.cs
@@ -61,7 +61,9 @@ namespace Terminal.Gui {
Add (button);
}
-
+ ///
+ /// Lays out the subviews for the Dialog.
+ ///
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
@@ -86,6 +88,7 @@ namespace Terminal.Gui {
}
}
+ ///
public override bool ProcessKey (KeyEvent kb)
{
switch (kb.Key) {
diff --git a/Terminal.Gui/Dialogs/FileDialog.cs b/Terminal.Gui/Dialogs/FileDialog.cs
index 069b8eea4..7c9b54374 100644
--- a/Terminal.Gui/Dialogs/FileDialog.cs
+++ b/Terminal.Gui/Dialogs/FileDialog.cs
@@ -212,9 +212,9 @@ namespace Terminal.Gui {
}
}
- public Action<(string,bool)> SelectedChanged;
- public Action DirectoryChanged;
- public Action FileChanged;
+ public Action<(string, bool)> SelectedChanged { get; set; }
+ public Action DirectoryChanged { get; set; }
+ public Action FileChanged { get; set; }
void SelectionChanged ()
{
@@ -494,6 +494,7 @@ namespace Terminal.Gui {
internal bool canceled;
+ ///
public override void WillPresent ()
{
base.WillPresent ();
diff --git a/Terminal.Gui/Drivers/ConsoleDriver.cs b/Terminal.Gui/Drivers/ConsoleDriver.cs
index 92be65a21..32f488674 100644
--- a/Terminal.Gui/Drivers/ConsoleDriver.cs
+++ b/Terminal.Gui/Drivers/ConsoleDriver.cs
@@ -466,9 +466,11 @@ namespace Terminal.Gui {
///
/// Prepare the driver and set the key and mouse events handlers.
///
- ///
- ///
- ///
+ /// The main loop.
+ /// The handler for ProcessKey
+ /// The handler for key down events
+ /// The handler for key up events
+ /// The handler for mouse events
public abstract void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler);
///
diff --git a/Terminal.Gui/Drivers/CursesDriver.cs b/Terminal.Gui/Drivers/CursesDriver.cs
index 1ecfb47a6..95a658108 100644
--- a/Terminal.Gui/Drivers/CursesDriver.cs
+++ b/Terminal.Gui/Drivers/CursesDriver.cs
@@ -17,6 +17,7 @@ namespace Terminal.Gui {
/// This is the Curses driver for the gui.cs/Terminal framework.
///
public class CursesDriver : ConsoleDriver {
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public override int Cols => Curses.Cols;
public override int Rows => Curses.Lines;
@@ -37,7 +38,7 @@ namespace Terminal.Gui {
}
}
- static bool sync;
+ static bool sync = false;
public override void AddRune (Rune rune)
{
if (Clip.Contains (ccol, crow)) {
@@ -51,7 +52,7 @@ namespace Terminal.Gui {
if (sync)
Application.Driver.Refresh ();
ccol++;
- var runeWidth = Rune.ColumnWidth(rune);
+ var runeWidth = Rune.ColumnWidth (rune);
if (runeWidth > 1) {
for (int i = 1; i < runeWidth; i++) {
ccol++;
@@ -66,8 +67,13 @@ namespace Terminal.Gui {
AddRune (rune);
}
- public override void Refresh () => Curses.refresh ();
- public override void UpdateCursor () => Curses.refresh ();
+ public override void Refresh () {
+ Curses.refresh ();
+ if (Curses.CheckWinChange ()) {
+ TerminalResized?.Invoke ();
+ }
+ }
+ public override void UpdateCursor () => Refresh ();
public override void End () => Curses.endwin ();
public override void UpdateScreen () => window.redrawwin ();
public override void SetAttribute (Attribute c) => Curses.attrset (c.value);
@@ -186,7 +192,7 @@ namespace Terminal.Gui {
};
}
- void ProcessInput (Action keyHandler, Action mouseHandler)
+ void ProcessInput (Action keyHandler, Action keyUpHandler, Action mouseHandler)
{
int wch;
var code = Curses.get_wch (out wch);
@@ -206,6 +212,7 @@ namespace Terminal.Gui {
return;
}
keyHandler (new KeyEvent (MapCursesKey (wch)));
+ keyUpHandler (new KeyEvent (MapCursesKey (wch)));
return;
}
@@ -213,7 +220,7 @@ namespace Terminal.Gui {
if (wch == 27) {
Curses.timeout (200);
- code = Curses.get_wch (out wch);
+ code = Curses.get_wch (out int wch2);
if (code == Curses.KEY_CODE_YES)
keyHandler (new KeyEvent (Key.AltMask | MapCursesKey (wch)));
if (code == 0) {
@@ -221,23 +228,28 @@ namespace Terminal.Gui {
// The ESC-number handling, debatable.
// Simulates the AltMask itself by pressing Alt + Space.
- if (wch == (int)Key.Space)
+ if (wch2 == (int)Key.Space)
key = new KeyEvent (Key.AltMask);
- else if (wch - (int)Key.Space >= 'A' && wch - (int)Key.Space <= 'Z')
- key = new KeyEvent ((Key)((uint)Key.AltMask + (wch - (int)Key.Space)));
- else if (wch >= '1' && wch <= '9')
- key = new KeyEvent ((Key)((int)Key.F1 + (wch - '0' - 1)));
- else if (wch == '0')
+ else if (wch2 - (int)Key.Space >= 'A' && wch2 - (int)Key.Space <= 'Z')
+ key = new KeyEvent ((Key)((uint)Key.AltMask + (wch2 - (int)Key.Space)));
+ else if (wch2 >= '1' && wch <= '9')
+ key = new KeyEvent ((Key)((int)Key.F1 + (wch2 - '0' - 1)));
+ else if (wch2 == '0')
key = new KeyEvent (Key.F10);
- else if (wch == 27)
- key = new KeyEvent ((Key)wch);
+ else if (wch2 == 27)
+ key = new KeyEvent ((Key)wch2);
else
- key = new KeyEvent (Key.AltMask | (Key)wch);
+ key = new KeyEvent (Key.AltMask | (Key)wch2);
keyHandler (key);
- } else
+ } else {
keyHandler (new KeyEvent (Key.Esc));
- } else
+ }
+ } else {
keyHandler (new KeyEvent ((Key)wch));
+ }
+ // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above
+ // will not impact KeyUp.
+ keyUpHandler (new KeyEvent ((Key)wch));
}
public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler)
@@ -246,7 +258,7 @@ namespace Terminal.Gui {
Curses.timeout (-1);
(mainLoop.Driver as Mono.Terminal.UnixMainLoop).AddWatch (0, Mono.Terminal.UnixMainLoop.Condition.PollIn, x => {
- ProcessInput (keyHandler, mouseHandler);
+ ProcessInput (keyHandler, keyUpHandler, mouseHandler);
return true;
});
@@ -308,7 +320,7 @@ namespace Terminal.Gui {
Colors.Menu.Focus = Curses.A_BOLD | MakeColor (Curses.COLOR_WHITE, Curses.COLOR_BLACK);
Colors.Menu.HotNormal = Curses.A_BOLD | MakeColor (Curses.COLOR_YELLOW, Curses.COLOR_CYAN);
Colors.Menu.Normal = Curses.A_BOLD | MakeColor (Curses.COLOR_WHITE, Curses.COLOR_CYAN);
- Colors.Menu.Disabled = MakeColor(Curses.COLOR_WHITE, Curses.COLOR_CYAN);
+ Colors.Menu.Disabled = MakeColor (Curses.COLOR_WHITE, Curses.COLOR_CYAN);
Colors.Dialog.Normal = MakeColor (Curses.COLOR_BLACK, Curses.COLOR_WHITE);
Colors.Dialog.Focus = MakeColor (Curses.COLOR_BLACK, Curses.COLOR_CYAN);
@@ -490,6 +502,7 @@ namespace Terminal.Gui {
killpg (0, signal);
return true;
}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
}
diff --git a/Terminal.Gui/Drivers/NetDriver.cs b/Terminal.Gui/Drivers/NetDriver.cs
index 96224c11a..3b7fa188d 100644
--- a/Terminal.Gui/Drivers/NetDriver.cs
+++ b/Terminal.Gui/Drivers/NetDriver.cs
@@ -37,7 +37,7 @@ namespace Terminal.Gui {
dirtyLine [row] = true;
}
- static bool sync;
+ static bool sync = false;
public NetDriver ()
{
@@ -328,6 +328,7 @@ namespace Terminal.Gui {
if (map == (Key)0xffffffff)
return;
keyHandler (new KeyEvent (map));
+ keyUpHandler (new KeyEvent (map));
};
}
diff --git a/Terminal.Gui/Drivers/WindowsDriver.cs b/Terminal.Gui/Drivers/WindowsDriver.cs
index 5fc86fa78..343182dc0 100644
--- a/Terminal.Gui/Drivers/WindowsDriver.cs
+++ b/Terminal.Gui/Drivers/WindowsDriver.cs
@@ -97,7 +97,7 @@ namespace Terminal.Gui {
public void Cleanup ()
{
ConsoleMode = originalConsoleMode;
- ContinueListeningForConsoleEvents = false;
+ //ContinueListeningForConsoleEvents = false;
if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
var err = Marshal.GetLastWin32Error ();
Console.WriteLine ("Error: {0}", err);
@@ -109,7 +109,7 @@ namespace Terminal.Gui {
ScreenBuffer = IntPtr.Zero;
}
- bool ContinueListeningForConsoleEvents = true;
+ //bool ContinueListeningForConsoleEvents = true;
public uint ConsoleMode {
get {
@@ -426,7 +426,7 @@ namespace Terminal.Gui {
}
internal class WindowsDriver : ConsoleDriver, Mono.Terminal.IMainLoopDriver {
- static bool sync;
+ static bool sync = false;
ManualResetEventSlim eventReady = new ManualResetEventSlim (false);
ManualResetEventSlim waitForProbe = new ManualResetEventSlim (false);
MainLoop mainLoop;
@@ -440,15 +440,10 @@ namespace Terminal.Gui {
public WindowsDriver ()
{
- Colors.TopLevel = new ColorScheme ();
-
- Colors.TopLevel.Normal = MakeColor (ConsoleColor.Green, ConsoleColor.Black);
- Colors.TopLevel.Focus = MakeColor (ConsoleColor.White, ConsoleColor.DarkCyan);
- Colors.TopLevel.HotNormal = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.Black);
- Colors.TopLevel.HotFocus = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.DarkCyan);
-
winConsole = new WindowsConsole ();
+ SetupColorsAndBorders ();
+
cols = Console.WindowWidth;
rows = Console.WindowHeight;
WindowsConsole.SmallRect.MakeEmpty (ref damageRegion);
@@ -459,6 +454,54 @@ namespace Terminal.Gui {
Task.Run ((Action)WindowsInputHandler);
}
+ private void SetupColorsAndBorders ()
+ {
+ Colors.TopLevel = new ColorScheme ();
+ Colors.Base = new ColorScheme ();
+ Colors.Dialog = new ColorScheme ();
+ Colors.Menu = new ColorScheme ();
+ Colors.Error = new ColorScheme ();
+
+ Colors.TopLevel.Normal = MakeColor (ConsoleColor.Green, ConsoleColor.Black);
+ Colors.TopLevel.Focus = MakeColor (ConsoleColor.White, ConsoleColor.DarkCyan);
+ Colors.TopLevel.HotNormal = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.Black);
+ Colors.TopLevel.HotFocus = MakeColor (ConsoleColor.DarkBlue, ConsoleColor.DarkCyan);
+
+ Colors.Base.Normal = MakeColor (ConsoleColor.White, ConsoleColor.DarkBlue);
+ Colors.Base.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
+ Colors.Base.HotNormal = MakeColor (ConsoleColor.DarkCyan, ConsoleColor.DarkBlue);
+ Colors.Base.HotFocus = MakeColor (ConsoleColor.Blue, ConsoleColor.Gray);
+
+ Colors.Menu.Normal = MakeColor (ConsoleColor.White, ConsoleColor.DarkGray);
+ Colors.Menu.Focus = MakeColor (ConsoleColor.White, ConsoleColor.Black);
+ Colors.Menu.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.DarkGray);
+ Colors.Menu.HotFocus = MakeColor (ConsoleColor.Yellow, ConsoleColor.Black);
+ Colors.Menu.Disabled = MakeColor (ConsoleColor.Gray, ConsoleColor.DarkGray);
+
+ Colors.Dialog.Normal = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
+ Colors.Dialog.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.DarkGray);
+ Colors.Dialog.HotNormal = MakeColor (ConsoleColor.DarkBlue, ConsoleColor.Gray);
+ Colors.Dialog.HotFocus = MakeColor (ConsoleColor.DarkBlue, ConsoleColor.DarkGray);
+
+ Colors.Error.Normal = MakeColor (ConsoleColor.DarkRed, ConsoleColor.White);
+ Colors.Error.Focus = MakeColor (ConsoleColor.White, ConsoleColor.DarkRed);
+ Colors.Error.HotNormal = MakeColor (ConsoleColor.Black, ConsoleColor.White);
+ Colors.Error.HotFocus = MakeColor (ConsoleColor.Black, ConsoleColor.DarkRed);
+
+ HLine = '\u2500';
+ VLine = '\u2502';
+ Stipple = '\u2592';
+ Diamond = '\u25c6';
+ ULCorner = '\u250C';
+ LLCorner = '\u2514';
+ URCorner = '\u2510';
+ LRCorner = '\u2518';
+ LeftTee = '\u251c';
+ RightTee = '\u2524';
+ TopTee = '\u22a4';
+ BottomTee = '\u22a5';
+ }
+
[StructLayout (LayoutKind.Sequential)]
public struct ConsoleKeyInfoEx {
public ConsoleKeyInfo consoleKeyInfo;
@@ -564,11 +607,24 @@ namespace Terminal.Gui {
case WindowsConsole.EventType.Key:
var map = MapKey (ToConsoleKeyInfoEx (inputEvent.KeyEvent));
if (map == (Key)0xffffffff) {
- KeyEvent key = default;
+ KeyEvent key = new KeyEvent ();
+
// Shift = VK_SHIFT = 0x10
// Ctrl = VK_CONTROL = 0x11
// Alt = VK_MENU = 0x12
+ if (inputEvent.KeyEvent.dwControlKeyState.HasFlag (WindowsConsole.ControlKeyState.CapslockOn)) {
+ inputEvent.KeyEvent.dwControlKeyState &= ~WindowsConsole.ControlKeyState.CapslockOn;
+ }
+
+ if (inputEvent.KeyEvent.dwControlKeyState.HasFlag (WindowsConsole.ControlKeyState.ScrolllockOn)) {
+ inputEvent.KeyEvent.dwControlKeyState &= ~WindowsConsole.ControlKeyState.ScrolllockOn;
+ }
+
+ if (inputEvent.KeyEvent.dwControlKeyState.HasFlag (WindowsConsole.ControlKeyState.NumlockOn)) {
+ inputEvent.KeyEvent.dwControlKeyState &= ~WindowsConsole.ControlKeyState.NumlockOn;
+ }
+
switch (inputEvent.KeyEvent.dwControlKeyState) {
case WindowsConsole.ControlKeyState.RightAltPressed:
case WindowsConsole.ControlKeyState.RightAltPressed |
@@ -617,10 +673,10 @@ namespace Terminal.Gui {
keyUpHandler (key);
} else {
if (inputEvent.KeyEvent.bKeyDown) {
- // Key Down - Fire KeyDown Event and KeyStroke (ProcessKey) Event
keyDownHandler (new KeyEvent (map));
- keyHandler (new KeyEvent (map));
} else {
+ // Key Up - Fire KeyDown Event and KeyStroke (ProcessKey) Event
+ keyHandler (new KeyEvent (map));
keyUpHandler (new KeyEvent (map));
}
}
@@ -807,6 +863,8 @@ namespace Terminal.Gui {
} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) {
mouseFlag = MouseFlags.ReportMousePosition;
+ } else if (mouseEvent.ButtonState == 0 && mouseEvent.EventFlags == 0) {
+ mouseFlag = 0;
}
mouseFlag = SetControlKeyStates (mouseEvent, mouseFlag);
@@ -916,6 +974,9 @@ namespace Terminal.Gui {
case ConsoleKey.OemComma:
case ConsoleKey.OemPlus:
case ConsoleKey.OemMinus:
+ if (keyInfo.KeyChar == 0)
+ return Key.Unknown;
+
return (Key)((uint)keyInfo.KeyChar);
}
@@ -969,48 +1030,10 @@ namespace Terminal.Gui {
public override void Init (Action terminalResized)
{
TerminalResized = terminalResized;
-
- Colors.Base = new ColorScheme ();
- Colors.Dialog = new ColorScheme ();
- Colors.Menu = new ColorScheme ();
- Colors.Error = new ColorScheme ();
-
- HLine = '\u2500';
- VLine = '\u2502';
- Stipple = '\u2592';
- Diamond = '\u25c6';
- ULCorner = '\u250C';
- LLCorner = '\u2514';
- URCorner = '\u2510';
- LRCorner = '\u2518';
- LeftTee = '\u251c';
- RightTee = '\u2524';
- TopTee = '\u22a4';
- BottomTee = '\u22a5';
-
- Colors.Base.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Blue);
- Colors.Base.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Cyan);
- Colors.Base.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Blue);
- Colors.Base.HotFocus = MakeColor (ConsoleColor.Yellow, ConsoleColor.Cyan);
-
- Colors.Menu.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Cyan);
- Colors.Menu.Focus = MakeColor (ConsoleColor.White, ConsoleColor.Black);
- Colors.Menu.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Cyan);
- Colors.Menu.HotFocus = MakeColor (ConsoleColor.Yellow, ConsoleColor.Black);
- Colors.Menu.Disabled = MakeColor (ConsoleColor.DarkGray, ConsoleColor.Cyan);
-
- Colors.Dialog.Normal = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
- Colors.Dialog.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Cyan);
- Colors.Dialog.HotNormal = MakeColor (ConsoleColor.Blue, ConsoleColor.Gray);
- Colors.Dialog.HotFocus = MakeColor (ConsoleColor.Blue, ConsoleColor.Cyan);
-
- Colors.Error.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Red);
- Colors.Error.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
- Colors.Error.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Red);
- Colors.Error.HotFocus = Colors.Error.HotNormal;
- Console.Clear ();
+ SetupColorsAndBorders ();
}
+
void ResizeScreen ()
{
OutputBuffer = new WindowsConsole.CharInfo [Rows * Cols];
diff --git a/Terminal.Gui/Event.cs b/Terminal.Gui/Event.cs
index c4e9b9e1a..169b60084 100644
--- a/Terminal.Gui/Event.cs
+++ b/Terminal.Gui/Event.cs
@@ -45,7 +45,7 @@ namespace Terminal.Gui {
ControlSpace = 0,
///
- /// The key code for the user pressing Control-A
+ /// The key code for the user pressing Control-A
///
ControlA = 1,
///
@@ -288,8 +288,7 @@ namespace Terminal.Gui {
///
/// Describes a keyboard event.
///
- public struct KeyEvent {
-
+ public class KeyEvent {
///
/// Symb olid definition for the key.
///
@@ -321,6 +320,10 @@ namespace Terminal.Gui {
//public bool IsCtrl => ((uint)Key >= 1) && ((uint)Key <= 26);
public bool IsCtrl => (Key & Key.CtrlMask) != 0;
+ public KeyEvent ()
+ {
+ Key = Key.Unknown;
+ }
///
/// Constructs a new KeyEvent from the provided Key value - can be a rune cast into a Key value
///
@@ -328,6 +331,28 @@ namespace Terminal.Gui {
{
Key = k;
}
+
+ public override string ToString ()
+ {
+ string msg = "";
+ var key = this.Key;
+ if ((this.Key & Key.ShiftMask) != 0) {
+ msg += "Shift-";
+ }
+ if ((this.Key & Key.CtrlMask) != 0) {
+ msg += "Ctrl-";
+ }
+ if ((this.Key & Key.AltMask) != 0) {
+ msg += "Alt-";
+ }
+
+ if (string.IsNullOrEmpty (msg)) {
+ msg += $"{(((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)this.KeyValue}" : $"{key}")}";
+ } else {
+ msg += $"{(((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)this.KeyValue}" : $"")}";
+ }
+ return msg;
+ }
}
///
@@ -486,7 +511,7 @@ namespace Terminal.Gui {
/// Returns a that represents the current .
///
/// A that represents the current .
- public override string ToString()
+ public override string ToString ()
{
return $"({X},{Y}:{Flags}";
}
diff --git a/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs
index 09882dbfd..92c0bbca2 100644
--- a/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs
+++ b/Terminal.Gui/MonoCurses/UnmanagedLibrary.cs
@@ -37,7 +37,11 @@ namespace Mono.Terminal.Internal {
const string XamarinIOSObjectClassName = "Foundation.NSObject, Xamarin.iOS";
static bool IsWindows, IsLinux, IsMacOS;
static bool Is64Bit;
+#if GUICS
+ static bool IsMono;
+#else
static bool IsMono, IsUnity, IsXamarinIOS, IsXamarinAndroid, IsXamarin;
+#endif
static bool IsNetCore;
public static bool IsMacOSPlatform => IsMacOS;
@@ -75,7 +79,7 @@ namespace Mono.Terminal.Internal {
IsNetCore = Type.GetType ("System.MathF") != null;
}
#if GUICS
- IsUnity = IsXamarinIOS = IsXamarinAndroid = IsXamarin = false;
+ //IsUnity = IsXamarinIOS = IsXamarinAndroid = IsXamarin = false;
#else
IsUnity = Type.GetType (UnityEngineApplicationClassName) != null;
IsXamarinIOS = Type.GetType (XamarinIOSObjectClassName) != null;
diff --git a/Terminal.Gui/MonoCurses/binding.cs b/Terminal.Gui/MonoCurses/binding.cs
index bd9167801..de1ca1f7e 100644
--- a/Terminal.Gui/MonoCurses/binding.cs
+++ b/Terminal.Gui/MonoCurses/binding.cs
@@ -47,6 +47,7 @@ using System.Runtime.InteropServices;
using Mono.Terminal.Internal;
namespace Unix.Terminal {
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public partial class Curses {
[StructLayout (LayoutKind.Sequential)]
@@ -61,7 +62,7 @@ namespace Unix.Terminal {
static IntPtr curses_handle, curscr_ptr, lines_ptr, cols_ptr;
// If true, uses the DllImport into "ncurses", otherwise "libncursesw.so.5"
- static bool use_naked_driver;
+ //static bool use_naked_driver;
static UnmanagedLibrary curses_library;
static NativeMethods methods;
@@ -451,4 +452,5 @@ namespace Unix.Terminal {
mousemask = lib.GetNativeMethodDelegate ("mousemask");
}
}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
diff --git a/Terminal.Gui/MonoCurses/constants.cs b/Terminal.Gui/MonoCurses/constants.cs
index c2da74157..df19c30e2 100644
--- a/Terminal.Gui/MonoCurses/constants.cs
+++ b/Terminal.Gui/MonoCurses/constants.cs
@@ -5,6 +5,7 @@
using System;
namespace Unix.Terminal {
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public partial class Curses {
public const int A_NORMAL = unchecked((int)0x0);
public const int A_STANDOUT = unchecked((int)0x10000);
@@ -139,4 +140,5 @@ namespace Unix.Terminal {
return 0 + n * 256;
}
}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
diff --git a/Terminal.Gui/MonoCurses/handles.cs b/Terminal.Gui/MonoCurses/handles.cs
index 85a1b6ac2..e81528ade 100644
--- a/Terminal.Gui/MonoCurses/handles.cs
+++ b/Terminal.Gui/MonoCurses/handles.cs
@@ -31,6 +31,7 @@ using System.Runtime.InteropServices;
namespace Unix.Terminal {
public partial class Curses {
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public class Window {
public readonly IntPtr Handle;
static Window curscr;
@@ -167,7 +168,8 @@ namespace Unix.Terminal {
Handle = handle;
}
}
-
+
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
}
diff --git a/Terminal.Gui/MonoCurses/mainloop.cs b/Terminal.Gui/MonoCurses/mainloop.cs
index 21bd1571a..5a9c49360 100644
--- a/Terminal.Gui/MonoCurses/mainloop.cs
+++ b/Terminal.Gui/MonoCurses/mainloop.cs
@@ -53,6 +53,10 @@ namespace Mono.Terminal {
/// true, if there were pending events, false otherwise.
/// If set to true wait until an event is available, otherwise return immediately.
bool EventsPending (bool wait);
+
+ ///
+ /// The interation function.
+ ///
void MainIteration ();
}
diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs
index 39788ea78..8fd4e2a2c 100644
--- a/Terminal.Gui/Views/Button.cs
+++ b/Terminal.Gui/Views/Button.cs
@@ -153,6 +153,7 @@ namespace Terminal.Gui {
Text = text;
}
+ ///
public override void Redraw (Rect region)
{
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
@@ -166,6 +167,7 @@ namespace Terminal.Gui {
}
}
+ ///
public override void PositionCursor ()
{
Move (hot_pos == -1 ? 1 : hot_pos, 0);
@@ -181,6 +183,7 @@ namespace Terminal.Gui {
return false;
}
+ ///
public override bool ProcessHotKey (KeyEvent kb)
{
if (kb.IsAlt)
@@ -189,6 +192,7 @@ namespace Terminal.Gui {
return false;
}
+ ///
public override bool ProcessColdKey (KeyEvent kb)
{
if (IsDefault && kb.KeyValue == '\n') {
@@ -199,6 +203,7 @@ namespace Terminal.Gui {
return CheckKey (kb);
}
+ ///
public override bool ProcessKey (KeyEvent kb)
{
var c = kb.KeyValue;
@@ -210,6 +215,7 @@ namespace Terminal.Gui {
return base.ProcessKey (kb);
}
+ ///
public override bool MouseEvent(MouseEvent me)
{
if (me.Flags == MouseFlags.Button1Clicked) {
diff --git a/Terminal.Gui/Views/Checkbox.cs b/Terminal.Gui/Views/Checkbox.cs
index 5ae8bb428..06cb26ab3 100644
--- a/Terminal.Gui/Views/Checkbox.cs
+++ b/Terminal.Gui/Views/Checkbox.cs
@@ -99,6 +99,7 @@ namespace Terminal.Gui {
}
}
+ ///
public override void Redraw (Rect region)
{
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
@@ -113,11 +114,13 @@ namespace Terminal.Gui {
}
}
+ ///
public override void PositionCursor ()
{
Move (1, 0);
}
+ ///
public override bool ProcessKey (KeyEvent kb)
{
if (kb.KeyValue == ' ') {
@@ -132,6 +135,7 @@ namespace Terminal.Gui {
return base.ProcessKey (kb);
}
+ ///
public override bool MouseEvent (MouseEvent me)
{
if (!me.Flags.HasFlag (MouseFlags.Button1Clicked))
diff --git a/Terminal.Gui/Views/Clipboard.cs b/Terminal.Gui/Views/Clipboard.cs
index eb1860f10..e0615da01 100644
--- a/Terminal.Gui/Views/Clipboard.cs
+++ b/Terminal.Gui/Views/Clipboard.cs
@@ -2,7 +2,13 @@
using NStack;
namespace Terminal.Gui {
+ ///
+ ///
+ ///
public static class Clipboard {
+ ///
+ ///
+ ///
public static ustring Contents { get; set; }
}
}
diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs
index 1f1915a10..0c82ea499 100644
--- a/Terminal.Gui/Views/DateField.cs
+++ b/Terminal.Gui/Views/DateField.cs
@@ -41,7 +41,7 @@ namespace Terminal.Gui {
{
CultureInfo cultureInfo = CultureInfo.CurrentCulture;
sepChar = cultureInfo.DateTimeFormat.DateSeparator;
- longFormat = $" {cultureInfo.DateTimeFormat.ShortDatePattern}";
+ longFormat = GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern);
shortFormat = GetShortFormat(longFormat);
this.isShort = isShort;
CursorPosition = 1;
@@ -55,7 +55,21 @@ namespace Terminal.Gui {
Text = e;
}
- string GetShortFormat(string lf)
+ string GetLongFormat (string lf)
+ {
+ ustring [] frm = ustring.Make (lf).Split (ustring.Make (sepChar));
+ for (int i = 0; i < frm.Length; i++) {
+ if (frm [i].Contains ("M") && frm [i].Length < 2)
+ lf = lf.Replace ("M", "MM");
+ if (frm [i].Contains ("d") && frm [i].Length < 2)
+ lf = lf.Replace ("d", "dd");
+ if (frm [i].Contains ("y") && frm [i].Length < 4)
+ lf = lf.Replace ("yy", "yyyy");
+ }
+ return $" {lf}";
+ }
+
+ string GetShortFormat (string lf)
{
return lf.Replace("yyyy", "yy");
}
diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs
index 313179268..63aea9470 100644
--- a/Terminal.Gui/Views/HexView.cs
+++ b/Terminal.Gui/Views/HexView.cs
@@ -98,6 +98,7 @@ namespace Terminal.Gui {
const int bsize = 4;
int bytesPerLine;
+ ///
public override Rect Frame {
get => base.Frame;
set {
@@ -128,6 +129,7 @@ namespace Terminal.Gui {
return buffer [offset];
}
+ ///
public override void Redraw (Rect region)
{
Attribute currentAttribute;
@@ -280,6 +282,7 @@ namespace Terminal.Gui {
RedisplayLine (position);
}
+ ///
public override bool ProcessKey (KeyEvent keyEvent)
{
switch (keyEvent.Key) {
diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs
index f87d941ee..b265fccda 100644
--- a/Terminal.Gui/Views/Label.cs
+++ b/Terminal.Gui/Views/Label.cs
@@ -124,7 +124,7 @@ namespace Terminal.Gui {
for (int i = 0; i < spaces; i++)
s.Append (' ');
if (extras > 0) {
- s.Append ('_');
+ //s.Append ('_');
extras--;
}
}
@@ -160,6 +160,7 @@ namespace Terminal.Gui {
lineResult.Add(ClipAndJustify(textStr[lp, textLen], width, talign));
}
+ ///
public override void Redraw (Rect region)
{
if (recalcPending)
@@ -178,8 +179,11 @@ namespace Terminal.Gui {
int x;
switch (textAlignment) {
case TextAlignment.Left:
+ x = Frame.Left;
+ break;
case TextAlignment.Justified:
- x = 0;
+ Recalc ();
+ x = Frame.Left;
break;
case TextAlignment.Right:
x = Frame.Right - str.Length;
diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs
index 02deb08ad..309c408e0 100644
--- a/Terminal.Gui/Views/ListView.cs
+++ b/Terminal.Gui/Views/ListView.cs
@@ -294,6 +294,11 @@ namespace Terminal.Gui {
///
public event Action SelectedChanged;
+ ///
+ /// This event is raised on Enter key or Double Click to open the selected item.
+ ///
+ public event EventHandler OpenSelectedItem;
+
///
/// Handles cursor movement for this view, passes all other events.
///
@@ -325,10 +330,19 @@ namespace Terminal.Gui {
return true;
else
break;
+
+ case Key.Enter:
+ OpenSelectedItem?.Invoke (this, new EventArgs ());
+ break;
+
}
return base.ProcessKey (kb);
}
+ ///
+ ///
+ ///
+ ///
public virtual bool AllowsAll ()
{
if (!allowsMarking)
@@ -344,6 +358,10 @@ namespace Terminal.Gui {
return true;
}
+ ///
+ ///
+ ///
+ ///
public virtual bool MarkUnmarkRow(){
if (AllowsAll ()) {
Source.SetMark(SelectedItem, !Source.IsMarked(SelectedItem));
@@ -354,6 +372,10 @@ namespace Terminal.Gui {
return false;
}
+ ///
+ ///
+ ///
+ ///
public virtual bool MovePageUp(){
int n = (selected - Frame.Height);
if (n < 0)
@@ -369,6 +391,10 @@ namespace Terminal.Gui {
return true;
}
+ ///
+ ///
+ ///
+ ///
public virtual bool MovePageDown(){
var n = (selected + Frame.Height);
if (n > source.Count)
@@ -387,6 +413,10 @@ namespace Terminal.Gui {
return true;
}
+ ///
+ ///
+ ///
+ ///
public virtual bool MoveDown(){
if (selected + 1 < source.Count){
selected++;
@@ -400,6 +430,10 @@ namespace Terminal.Gui {
return true;
}
+ ///
+ ///
+ ///
+ ///
public virtual bool MoveUp(){
if (selected > 0){
selected--;
@@ -424,9 +458,10 @@ namespace Terminal.Gui {
Move (0, selected - top);
}
+ ///
public override bool MouseEvent(MouseEvent me)
{
- if (!me.Flags.HasFlag (MouseFlags.Button1Clicked))
+ if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
return false;
if (!HasFocus)
@@ -444,9 +479,10 @@ namespace Terminal.Gui {
SetNeedsDisplay ();
return true;
}
- if (SelectedChanged != null)
- SelectedChanged();
+ SelectedChanged?.Invoke ();
SetNeedsDisplay ();
+ if (me.Flags == MouseFlags.Button1DoubleClicked)
+ OpenSelectedItem?.Invoke (this, new EventArgs ());
return true;
}
}
@@ -460,6 +496,10 @@ namespace Terminal.Gui {
BitArray marks;
int count;
+ ///
+ /// constructor
+ ///
+ ///
public ListWrapper (IList source)
{
count = source.Count;
@@ -467,6 +507,9 @@ namespace Terminal.Gui {
this.src = source;
}
+ ///
+ /// Count of items.
+ ///
public int Count => src.Count;
void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width)
@@ -487,6 +530,16 @@ namespace Terminal.Gui {
}
}
+ ///
+ /// Renders an item in the the list.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public void Render (ListView container, ConsoleDriver driver, bool marked, int item, int col, int line, int width)
{
container.Move (col, line);
@@ -499,6 +552,11 @@ namespace Terminal.Gui {
RenderUstr (driver, t.ToString (), col, line, width);
}
+ ///
+ /// Returns true of the item is marked. false if not.
+ ///
+ ///
+ ///
public bool IsMarked (int item)
{
if (item >= 0 && item < count)
@@ -506,6 +564,11 @@ namespace Terminal.Gui {
return false;
}
+ ///
+ /// Sets the marked state of an item.
+ ///
+ ///
+ ///
public void SetMark (int item, bool value)
{
if (item >= 0 && item < count)
diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs
index 0e40bd391..16b7c0b87 100644
--- a/Terminal.Gui/Views/Menu.cs
+++ b/Terminal.Gui/Views/Menu.cs
@@ -21,6 +21,9 @@ namespace Terminal.Gui {
///
public class MenuItem {
+ ///
+ /// constructor
+ ///
public MenuItem ()
{
Title = "";
@@ -207,10 +210,10 @@ namespace Terminal.Gui {
return len;
}
- ///
- /// Gets or sets the title to display.
- ///
- /// The title.
+ /////
+ ///// Gets or sets the title to display.
+ /////
+ ///// The title.
//public ustring Title { get; set; }
///
@@ -357,7 +360,7 @@ namespace Terminal.Gui {
public override bool ProcessHotKey (KeyEvent keyEvent)
{
// To ncurses simulate a AltMask key pressing Alt+Space because
- // it can´t detect an alone special key down was pressed.
+ // it can�t detect an alone special key down was pressed.
if (keyEvent.IsAlt && keyEvent.Key == Key.AltMask) {
OnKeyDown (keyEvent);
return true;
@@ -455,7 +458,7 @@ namespace Terminal.Gui {
}
host.handled = false;
bool disabled;
- if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) {
+ if (me.Flags == MouseFlags.Button1Clicked) {
disabled = false;
if (me.Y < 1)
return true;
@@ -559,6 +562,7 @@ namespace Terminal.Gui {
}
bool openedByAltKey;
+ ///
public override bool OnKeyDown (KeyEvent keyEvent)
{
if (keyEvent.IsAlt) {
@@ -569,12 +573,7 @@ namespace Terminal.Gui {
return false;
}
- ///
- /// Track Alt key-up events. On Windows, when a user releases Alt (without another key), the menu gets focus but doesn't open.
- /// We mimic that behavior here.
- ///
- ///
- ///
+ ///
public override bool OnKeyUp (KeyEvent keyEvent)
{
if (keyEvent.IsAlt) {
@@ -615,6 +614,7 @@ namespace Terminal.Gui {
return false;
}
+ ///
public override void Redraw (Rect region)
{
Move (0, 0);
@@ -645,6 +645,7 @@ namespace Terminal.Gui {
PositionCursor ();
}
+ ///
public override void PositionCursor ()
{
int pos = 0;
@@ -672,8 +673,16 @@ namespace Terminal.Gui {
action = item.Action;
}
+ ///
+ /// Raised as a menu is opened.
+ ///
public event EventHandler OnOpenMenu;
+
+ ///
+ /// Raised when a menu is closing.
+ ///
public event EventHandler OnCloseMenu;
+
internal Menu openMenu;
Menu openCurrentMenu;
internal List