Explorar o código

Complete the Windows driver

Miguel de Icaza %!s(int64=7) %!d(string=hai) anos
pai
achega
95db6a83b4

+ 4 - 5
Terminal.Gui/Core.cs

@@ -1264,14 +1264,13 @@ namespace Terminal.Gui {
 				if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows)
 					UseSystemConsole = true;
 			}
-			if (UseSystemConsole){
-				Console.WriteLine ("WARNING: This version currently does not support data input yet, working on it");
-				Console.ReadLine ();
+			UseSystemConsole = true;
+			if (UseSystemConsole)
 				Driver = new NetDriver ();
-			} else
+			else
 				Driver = new CursesDriver ();
 			Driver.Init (TerminalResized);
-			MainLoop = new Mono.Terminal.MainLoop ();
+			MainLoop = new Mono.Terminal.MainLoop (Driver is CursesDriver);
 			SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
 			Top = Toplevel.Create ();
 			Current = Top;

+ 46 - 22
Terminal.Gui/Driver.cs

@@ -834,21 +834,40 @@ namespace Terminal.Gui {
 			UpdateOffscreen ();
 		}
 
+		bool needMove;
 		// Current row, and current col, tracked by Move/AddCh only
 		int ccol, crow;
 		public override void Move (int col, int row)
 		{
 			ccol = col;
 			crow = row;
+
+			if (Clip.Contains (col, row)) {
+				Console.CursorTop = row;
+				Console.CursorLeft = col;
+				needMove = false;
+			} else {
+				Console.CursorTop = Clip.Y;
+				Console.CursorLeft = Clip.X;
+				needMove = true;
+			}
+
 		}
 
 		public override void AddRune (Rune rune)
 		{
 			if (Clip.Contains (ccol, crow)) {
-				contents [crow, ccol, 0] = (int) (uint) rune;
+				if (needMove) {
+					Console.CursorLeft = ccol;
+					Console.CursorTop = crow;
+					needMove = false;
+				}
+				contents [crow, ccol, 0] = (int)(uint)rune;
 				contents [crow, ccol, 1] = currentAttribute;
 				contents [crow, ccol, 2] = 1;
-			}
+				dirtyLine [crow] = true;
+			} else
+				needMove = true;
 			ccol++;
 			if (ccol == Cols) {
 				ccol = 0;
@@ -956,6 +975,8 @@ namespace Terminal.Gui {
 			int rows = Rows;
 			int cols = Cols;
 
+			var savedRow = Console.CursorTop;
+			var savedCol = Console.CursorLeft;
 			for (int row = 0; row < rows; row++) {
 				if (!dirtyLine [row])
 					continue;
@@ -976,6 +997,8 @@ namespace Terminal.Gui {
 					}
 				}
 			}
+			Console.CursorTop = savedRow;
+			Console.CursorLeft = savedCol;
 		}
 
 		public override void StartReportingMouseMoves()
@@ -998,27 +1021,9 @@ namespace Terminal.Gui {
 
 		Key MapKey (ConsoleKeyInfo keyInfo)
 		{
-			var key = keyInfo.Key;
-			if (key >= ConsoleKey.A && key <= ConsoleKey.Z){
-				var delta = key - ConsoleKey.A;
-				if (keyInfo.Modifiers == ConsoleModifiers.Control)
-					return (Key)((uint)Key.ControlA + delta);
-				if (keyInfo.Modifiers == ConsoleModifiers.Alt)
-					return (Key) (((uint)Key.AltMask) | ((uint)'A' + delta));
-				if (keyInfo.Modifiers == ConsoleModifiers.Shift)
-					return (Key)((uint)'A' + delta);
-				else
-					return (Key)((uint)'a' + delta);
-			}
-			if (key >= ConsoleKey.F1 && key <= ConsoleKey.F10) {
-				var delta = key - ConsoleKey.F1;
-
-				return (Key)(ConsoleKey.F1 + delta);
-			}
-
-			switch (keyInfo.Key){
+			switch (keyInfo.Key) {
 			case ConsoleKey.Tab:
-				return Key.ControlT;
+				return Key.Tab;
 			case ConsoleKey.Escape:
 				return Key.Esc;
 			case ConsoleKey.Home:
@@ -1046,6 +1051,25 @@ namespace Terminal.Gui {
 			case ConsoleKey.Delete:
 				return Key.Delete;
 			}
+
+			var key = keyInfo.Key;
+			if (key >= ConsoleKey.A && key <= ConsoleKey.Z){
+				var delta = key - ConsoleKey.A;
+				if (keyInfo.Modifiers == ConsoleModifiers.Control)
+					return (Key)((uint)Key.ControlA + delta);
+				if (keyInfo.Modifiers == ConsoleModifiers.Alt)
+					return (Key) (((uint)Key.AltMask) | ((uint)'A' + delta));
+				if (keyInfo.Modifiers == ConsoleModifiers.Shift)
+					return (Key)((uint)'A' + delta);
+				else
+					return (Key)((uint)'a' + delta);
+			}
+			if (key >= ConsoleKey.F1 && key <= ConsoleKey.F10) {
+				var delta = key - ConsoleKey.F1;
+
+				return (Key)(ConsoleKey.F1 + delta);
+			}
+
 			return (Key)(0xffffffff);
 		}
 

+ 43 - 15
Terminal.Gui/MonoCurses/mainloop.cs

@@ -36,8 +36,12 @@ namespace Mono.Terminal {
 	///   Simple main loop implementation that can be used to monitor
 	///   file descriptor, run timers and idle handlers.
 	/// </summary>
+	/// <remarks>
+	///   Monitoring of file descriptors is only available on Unix, there
+	///   does not seem to be a way of supporting this on Windows.
+	/// </remarks>
 	public class MainLoop {
-		static bool useUnix = true;
+		bool useUnix = true;
 
 		/// <summary>
 		///   Condition on which to wake up from file descriptor activity.  These match the Linux/BSD poll definitions.
@@ -82,7 +86,7 @@ namespace Mono.Terminal {
 		}
 
 		Dictionary <int, Watch> descriptorWatchers = new Dictionary<int,Watch>();
-		SortedList <double, Timeout> timeouts = new SortedList<double,Timeout> ();
+		SortedList <long, Timeout> timeouts = new SortedList<long,Timeout> ();
 		List<Func<bool>> idleHandlers = new List<Func<bool>> ();
 
 		[StructLayout(LayoutKind.Sequential)]
@@ -107,17 +111,27 @@ namespace Mono.Terminal {
 		bool poll_dirty = true;
 		int [] wakeupPipes = new int [2];
 		static IntPtr ignore = Marshal.AllocHGlobal (1);
-		
+
 		/// <summary>
 		///  Default constructor
 		/// </summary>
-		public MainLoop ()
+		public MainLoop () : this (useUnix: true)
 		{
-			pipe (wakeupPipes);
-			AddWatch (wakeupPipes [0], Condition.PollIn, ml => {
-					read (wakeupPipes [0], ignore, (IntPtr) 1);
-				return true;
-			});
+		}
+
+		public MainLoop (bool useUnix)
+		{
+			this.useUnix = useUnix;
+			if (useUnix) {
+				pipe (wakeupPipes);
+				AddWatch (wakeupPipes [0], Condition.PollIn, ml => {
+					read (wakeupPipes [0], ignore, (IntPtr)1);
+					return true;
+				});
+			} else {
+				Thread readThread = new Thread (WindowsKeyReader);
+				readThread.Start ();
+			}
 		}
 
 		void Wakeup ()
@@ -260,7 +274,7 @@ namespace Mono.Terminal {
 		{
 			long now = DateTime.UtcNow.Ticks;
 			var copy = timeouts;
-			timeouts = new SortedList<double,Timeout> ();
+			timeouts = new SortedList<long,Timeout> ();
 			foreach (var k in copy.Keys){
 				var timeout = copy [k];
 				if (k < now) {
@@ -304,7 +318,7 @@ namespace Mono.Terminal {
 		{
 			while (true) {
 				waitForProbe.WaitOne ();
-				var result = Console.ReadKey ();
+				windowsKeyResult = Console.ReadKey ();
 				keyReady.Set ();
 			}
 		}
@@ -322,9 +336,12 @@ namespace Mono.Terminal {
 			long now = DateTime.UtcNow.Ticks;
 			if (useUnix) {
 				int pollTimeout, n;
-				if (timeouts.Count > 0)
+				if (timeouts.Count > 0){
 					pollTimeout = (int)((timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
-				else
+					if (pollTimeout < 0)
+						return true;
+
+				} else
 					pollTimeout = -1;
 
 				if (!wait)
@@ -338,10 +355,21 @@ namespace Mono.Terminal {
 					ic = idleHandlers.Count;
 				return n > 0 || timeouts.Count > 0 && ((timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
 			} else {
+				int waitTimeout;
+				if (timeouts.Count > 0){
+					waitTimeout = (int)((timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
+					if (waitTimeout < 0)
+						return true;
+				} else
+					waitTimeout = -1;
+
+				if (!wait)
+					waitTimeout = 0;
+				
 				windowsKeyResult = null;
 				waitForProbe.Set ();
-				keyReady.WaitOne ();
-				return false;
+				keyReady.WaitOne (waitTimeout);
+				return windowsKeyResult.HasValue;
 			}
 		}
 

+ 1 - 2
Terminal.Gui/Views/ListView.cs

@@ -282,7 +282,6 @@ namespace Terminal.Gui {
 						Driver.AddRune (' ');
 				else
 					Source.Render (isSelected, item, 0, row, f.Width);
-
 			}
 		}
 
@@ -361,7 +360,7 @@ namespace Terminal.Gui {
 		/// </summary>
 		public override void PositionCursor()
 		{
-			Driver.Move (0, selected);
+			Move (0, selected-top);
 		}
 
 		public override bool MouseEvent(MouseEvent me)

+ 2 - 0
Terminal.Gui/Views/ScrollView.cs

@@ -270,6 +270,7 @@ namespace Terminal.Gui {
 				contentView.Frame = new Rect (contentOffset, value);
 				vertical.Size = contentSize.Height;
 				horizontal.Size = contentSize.Width;
+				SetNeedsDisplay ();
 			}
 		}
 
@@ -286,6 +287,7 @@ namespace Terminal.Gui {
 				contentView.Frame = new Rect (contentOffset, contentSize);
 				vertical.Position = Math.Max (0, -contentOffset.Y);
 				horizontal.Position = Math.Max (0, -contentOffset.X);
+				SetNeedsDisplay ();
 			}
 		}