瀏覽代碼

Scrollviews, some rendering bug fixes, some scrollview event handling

Miguel de Icaza 7 年之前
父節點
當前提交
4de3083bba
共有 5 個文件被更改,包括 150 次插入12 次删除
  1. 40 2
      Terminal.Gui/Core.cs
  2. 1 1
      Terminal.Gui/Driver.cs
  3. 21 0
      Terminal.Gui/Views/FrameView.cs
  4. 73 5
      Terminal.Gui/Views/ScrollView.cs
  5. 15 4
      demo.cs

+ 40 - 2
Terminal.Gui/Core.cs

@@ -257,7 +257,7 @@ namespace Terminal.Gui {
 		/// </summary>
 		public void SetNeedsDisplay ()
 		{
-			SetNeedsDisplay (Frame);
+			SetNeedsDisplay (Bounds);
 		}
 
 		/// <summary>
@@ -281,7 +281,10 @@ namespace Terminal.Gui {
 				return;
 			foreach (var view in subviews)
 				if (view.Frame.IntersectsWith (region)) {
-					view.SetNeedsDisplay (Rect.Intersect (view.Frame, region));
+					var childRegion = Rect.Intersect (view.Frame, region);
+					childRegion.X -= view.Frame.X;
+					childRegion.Y -= view.Frame.Y;
+					view.SetNeedsDisplay (childRegion);
 				}
 		}
 
@@ -387,6 +390,20 @@ namespace Terminal.Gui {
 			}
 		}
 
+		/// <summary>
+		///   Clears the specfied rectangular region with the current color
+		/// </summary>
+		public void Clear (Rect r)
+		{
+			var h = r.Height;
+			var w = r.Width;
+			for (int line = 0; line < h; line++) {
+				Move (0, line);
+				for (int col = 0; col < w; col++)
+					Driver.AddRune (' ');
+			}
+		}
+
 		/// <summary>
 		/// Converts the (col,row) position from the view into a screen (col,row).  The values are clamped to (0..ScreenDim-1)
 		/// </summary>
@@ -1012,6 +1029,27 @@ namespace Terminal.Gui {
 		public override void Add (View view)
 		{
 			contentView.Add (view);
+			if (view.CanFocus)
+				CanFocus = true;
+		}
+
+
+		/// <summary>
+		///   Removes a widget from this container.
+		/// </summary>
+		/// <remarks>
+		/// </remarks>
+		public virtual void Remove (View view)
+		{
+			if (view == null)
+				return;
+
+			SetNeedsDisplay ();
+			var touched = view.Frame;
+			contentView.Remove (view);
+
+			if (contentView.Subviews.Count < 1)
+				this.CanFocus = false;
 		}
 
 		public override void Redraw (Rect bounds)

+ 1 - 1
Terminal.Gui/Driver.cs

@@ -332,7 +332,7 @@ namespace Terminal.Gui {
 			}
 		}
 
-		static bool sync = true;
+		static bool sync = false;
 		public override void AddRune (Rune rune)
 		{
 			if (Clip.Contains (ccol, crow)) {

+ 21 - 0
Terminal.Gui/Views/FrameView.cs

@@ -59,6 +59,27 @@ namespace Terminal.Gui {
 		public override void Add (View view)
 		{
 			contentView.Add (view);
+			if (view.CanFocus)
+				CanFocus = true;
+		}
+
+
+		/// <summary>
+		///   Removes a widget from this container.
+		/// </summary>
+		/// <remarks>
+		/// </remarks>
+		public virtual void Remove (View view)
+		{
+			if (view == null)
+				return;
+
+			SetNeedsDisplay ();
+			var touched = view.Frame;
+			contentView.Remove (view);
+
+			if (contentView.Subviews.Count < 1)
+				this.CanFocus = false;
 		}
 
 		public override void Redraw (Rect bounds)

+ 73 - 5
Terminal.Gui/Views/ScrollView.cs

@@ -11,14 +11,22 @@
 // - keyboard handling in scrollview to scroll
 // - focus handling in scrollview to auto scroll to focused view
 // - Raise events
+// - Perhaps allow an option to not display the scrollbar arrow indicators?
+
 using System;
 namespace Terminal.Gui {
 	/// <summary>
 	/// ScrollBarViews are views that display a 1-character scrollbar, either horizontal or vertical
 	/// </summary>
 	/// <remarks>
-	/// The scrollbar is drawn to be a representation of the Size, assuming that the 
-	/// scroll position is set at Position.
+	/// <para>
+	///   The scrollbar is drawn to be a representation of the Size, assuming that the 
+	///   scroll position is set at Position.
+	/// </para>
+	/// <para>
+	///   If the region to display the scrollbar is larger than three characters, 
+	///   arrow indicators are drawn.
+	/// </para>
 	/// </remarks>
 	public class ScrollBarView : View {
 		bool vertical;
@@ -36,6 +44,11 @@ namespace Terminal.Gui {
 			}
 		}
 
+		/// <summary>
+		/// This event is raised when the position on the scrollbar has changed.
+		/// </summary>
+		public event Action ChangedPosition;
+
 		/// <summary>
 		/// The position to show the scrollbar at.
 		/// </summary>
@@ -48,6 +61,12 @@ namespace Terminal.Gui {
 			}
 		}
 
+		void SetPosition (int newPos)
+		{
+			Position = newPos;
+			ChangedPosition?.Invoke ();
+		}
+
 		/// <summary>
 		/// Initializes a new instance of the <see cref="T:Terminal.Gui.Gui.ScrollBarView"/> class.
 		/// </summary>
@@ -78,7 +97,7 @@ namespace Terminal.Gui {
 				var bh = Bounds.Height;
 				SpecialChar special;
 
-				if (bh < 3) {
+				if (bh < 4) {
 					var by1 = position * bh / Size;
 					var by2 = (position + bh) * bh / Size;
 
@@ -126,7 +145,20 @@ namespace Terminal.Gui {
 
 				var row = Bounds.Height - 1;
 				var bw = Bounds.Width;
-				if (bw < 3) {
+				SpecialChar special;
+
+				if (bw < 4) {
+					var bx1 = position * bw / Size;
+					var bx2 = (position + bw) * bw / Size;
+
+					for (int x = 0; x < bw; x++) {
+						Move (0, x);
+						if (x < bx1 || x > bx2)
+							special = SpecialChar.Stipple;
+						else
+							special = SpecialChar.Diamond;
+						Driver.AddSpecial (special);
+					}
 				} else {
 					bw -= 2;
 					var bx1 = position * bw / Size;
@@ -136,7 +168,6 @@ namespace Terminal.Gui {
 					Driver.AddRune ('<');
 
 					for (int x = 0; x < bw; x++) {
-						SpecialChar special;
 
 						if (x < bx1 || x > bx2) {
 							special = SpecialChar.Stipple;
@@ -158,6 +189,35 @@ namespace Terminal.Gui {
 				}
 			}
 		}
+
+		public override bool MouseEvent(MouseEvent me)
+		{
+			if (me.Flags != MouseFlags.Button1Clicked)
+				return false;
+
+			int location = vertical ? me.Y : me.X;
+			int barsize = vertical ? Bounds.Height : Bounds.Width;
+
+			if (barsize < 4) {
+				// Handle scrollbars with no buttons
+				Console.WriteLine ("TODO at ScrollBarView2");
+			} else {
+				barsize -= 2;
+				// Handle scrollbars with arrow buttons
+				var pos = Position;
+				if (location == 0) {
+					if (pos > 0)
+						SetPosition (pos - 1);
+				} else if (location == Bounds.Width - 1){
+					if (pos + 1 + barsize < Size)
+						SetPosition (pos + 1);
+				} else {
+					Console.WriteLine ("TODO at ScrollBarView");
+				}
+			}
+
+			return true;
+		}
 	}
 
 	/// <summary>
@@ -181,7 +241,13 @@ namespace Terminal.Gui {
 		{
 			contentView = new View (frame);
 			vertical = new ScrollBarView (new Rect (frame.Width - 1, 0, 1, frame.Height), frame.Height, 0, isVertical: true);
+			vertical.ChangedPosition += delegate {
+				ContentOffset = new Point (ContentOffset.X, vertical.Position);
+			};
 			horizontal = new ScrollBarView (new Rect (0, frame.Height-1, frame.Width-1, 1), frame.Width-1, 0, isVertical: false);
+			horizontal.ChangedPosition += delegate {
+				ContentOffset = new Point (horizontal.Position, ContentOffset.Y);
+			};
 			base.Add (contentView);
 			CanFocus = true;
 		}
@@ -279,6 +345,8 @@ namespace Terminal.Gui {
 		public override void Redraw(Rect region)
 		{
 			var oldClip = ClipToBounds ();
+			Driver.SetAttribute (ColorScheme.Normal);
+			Clear ();
 			base.Redraw(region);
 			Driver.Clip = oldClip;
 			Driver.SetAttribute (ColorScheme.Normal);

+ 15 - 4
demo.cs

@@ -67,14 +67,23 @@ class Demo {
 	{
 		var scrollView = new ScrollView (new Rect (50, 10, 20, 8)) {
 			ContentSize = new Size (100, 100),
-			ContentOffset = new Point (5, -2),
+			//ContentOffset = new Point (5, -2),
 			ShowVerticalScrollIndicator = true,
 			ShowHorizontalScrollIndicator = true
 		};
 
-		//scrollView.Add (new Box10x (0, 0));
-		scrollView.Add (new Filler (new Rect (0, 0, 40, 40)));
+		scrollView.Add (new Box10x (0, 0));
+		//scrollView.Add (new Filler (new Rect (0, 0, 40, 40)));
 
+		// This is just to debug the visuals of the scrollview when small
+		var scrollView2 = new ScrollView (new Rect (72, 10, 3, 3)) {
+			ContentSize = new Size (100, 100),
+			ShowVerticalScrollIndicator = true,
+			ShowHorizontalScrollIndicator = true
+		};
+		scrollView2.Add (new Box10x (0, 0));
+
+		// Add some content
 		container.Add (
 			new Label (3, 6, "Login: "),
 			new TextField (14, 6, 40, ""),
@@ -84,11 +93,13 @@ class Demo {
 				new CheckBox (1, 0, "Remember me"),
 				new RadioGroup (1, 2, new [] { "_Personal", "_Company" }),
 			},
-			scrollView,
+			//scrollView,
+			//scrollView2,
 			new Button (3, 19, "Ok"),
 			new Button (10, 19, "Cancel"),
 			new Label (3, 22, "Press ESC and 9 to activate the menubar")
 		);
+
 	}
 
 	public static Label ml2;