Explorar el Código

Fixed ScrollViwe

Tig hace 1 año
padre
commit
17efda9926

+ 0 - 3
Terminal.Gui/View/ViewDrawing.cs

@@ -442,9 +442,6 @@ public partial class View
 
             // This should NOT clear 
             // TODO: If the output is not in the Viewport, do nothing
-            if (Viewport.Y != 0)
-            { }
-
             var drawRect = new Rectangle (ContentToScreen (Point.Empty), ContentSize);
 
             TextFormatter?.Draw (

+ 27 - 1
Terminal.Gui/View/ViewScrolling.cs

@@ -44,9 +44,35 @@ public partial class View
     public Size ContentSize
     {
         get => _contentSize == Size.Empty ? Viewport.Size : _contentSize;
-        set => _contentSize = value;
+        set
+        {
+            _contentSize = value;
+            OnContentSizeChanged (new (_contentSize));
+        }
     }
 
+    /// <summary>
+    /// Called when the <see cref="ContentSize"/> changes. Invokes the <see cref="ContentSizeChanged"/> event.
+    /// </summary>
+    /// <param name="e"></param>
+    /// <returns></returns>
+    protected bool? OnContentSizeChanged (SizeChangedEventArgs e)
+    {
+        ContentSizeChanged?.Invoke (this, e);
+
+        if (e.Cancel != true)
+        {
+            SetNeedsDisplay ();
+        }
+
+        return e.Cancel == true;
+    }
+
+    /// <summary>
+    ///    Event that is raised when the <see cref="ContentSize"/> changes.
+    /// </summary>
+    public event EventHandler<SizeChangedEventArgs> ContentSizeChanged;
+
     /// <summary>
     ///     Converts a content-relative location to a screen-relative location.
     /// </summary>

+ 5 - 9
Terminal.Gui/Views/ScrollBarView.cs

@@ -275,7 +275,7 @@ public class ScrollBarView : View
     public event EventHandler ChangedPosition;
 
     /// <inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent mouseEvent)
+    protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
         if (mouseEvent.Flags != MouseFlags.Button1Pressed
             && mouseEvent.Flags != MouseFlags.Button1DoubleClicked
@@ -524,8 +524,7 @@ public class ScrollBarView : View
                     by1 = Math.Max (by1 - 1, 0);
                 }
 
-                Move (col, 0);
-                Driver.AddRune (Glyphs.UpArrow);
+                AddRune (col, 0, Glyphs.UpArrow);
 
                 var hasTopTee = false;
                 var hasDiamond = false;
@@ -533,7 +532,6 @@ public class ScrollBarView : View
 
                 for (var y = 0; y < bh; y++)
                 {
-                    Move (col, y + 1);
 
                     if ((y < by1 || y > by2) && ((_position > 0 && !hasTopTee) || (hasTopTee && hasBottomTee)))
                     {
@@ -567,17 +565,15 @@ public class ScrollBarView : View
                         }
                     }
 
-                    Driver.AddRune (special);
+                    AddRune (col, y + 1, special);
                 }
 
                 if (!hasTopTee)
                 {
-                    Move (col, Viewport.Height - 2);
-                    Driver.AddRune (Glyphs.TopTee);
+                    AddRune (col, Viewport.Height - 2, Glyphs.TopTee);
                 }
 
-                Move (col, Viewport.Height - 1);
-                Driver.AddRune (Glyphs.DownArrow);
+                AddRune (col, Viewport.Height - 1, Glyphs.DownArrow);
             }
         }
         else

+ 43 - 40
Terminal.Gui/Views/ScrollView.cs

@@ -33,7 +33,6 @@ public class ScrollView : View
     private bool _autoHideScrollBars = true;
     private View _contentBottomRightCorner;
     private Point _contentOffset;
-    private Size _contentSize;
     private bool _keepContentAlwaysInViewport = true;
     private bool _showHorizontalScrollIndicator;
     private bool _showVerticalScrollIndicator;
@@ -89,10 +88,10 @@ public class ScrollView : View
         AddCommand (Command.PageDown, () => ScrollDown (Viewport.Height));
         AddCommand (Command.PageLeft, () => ScrollLeft (Viewport.Width));
         AddCommand (Command.PageRight, () => ScrollRight (Viewport.Width));
-        AddCommand (Command.TopHome, () => ScrollUp (_contentSize.Height));
-        AddCommand (Command.BottomEnd, () => ScrollDown (_contentSize.Height));
-        AddCommand (Command.LeftHome, () => ScrollLeft (_contentSize.Width));
-        AddCommand (Command.RightEnd, () => ScrollRight (_contentSize.Width));
+        AddCommand (Command.TopHome, () => ScrollUp (ContentSize.Height));
+        AddCommand (Command.BottomEnd, () => ScrollDown (ContentSize.Height));
+        AddCommand (Command.LeftHome, () => ScrollLeft (ContentSize.Width));
+        AddCommand (Command.RightEnd, () => ScrollRight (ContentSize.Width));
 
         // Default keybindings for this view
         KeyBindings.Add (Key.CursorUp, Command.ScrollUp);
@@ -134,6 +133,14 @@ public class ScrollView : View
                            _vertical.ChangedPosition += delegate { ContentOffset = new Point (ContentOffset.X, _vertical.Position); };
                            _horizontal.ChangedPosition += delegate { ContentOffset = new Point (_horizontal.Position, ContentOffset.Y); };
                        };
+        ContentSizeChanged += ScrollViewContentSizeChanged;
+    }
+
+    private void ScrollViewContentSizeChanged (object sender, SizeChangedEventArgs e)
+    {
+        _contentView.Frame = new Rectangle (ContentOffset, e.Size with {Width = e.Size.Width-1, Height = e.Size.Height-1});
+        _vertical.Size = e.Size.Height;
+        _horizontal.Size = e.Size.Width;
     }
 
     private void Application_UnGrabbedMouse (object sender, ViewEventArgs e)
@@ -202,23 +209,23 @@ public class ScrollView : View
         }
     }
 
-    /// <summary>Represents the contents of the data shown inside the scrollview</summary>
-    /// <value>The size of the content.</value>
-    public new Size ContentSize
-    {
-        get => _contentSize;
-        set
-        {
-            if (_contentSize != value)
-            {
-                _contentSize = value;
-                _contentView.Frame = new Rectangle (_contentOffset, value);
-                _vertical.Size = _contentSize.Height;
-                _horizontal.Size = _contentSize.Width;
-                SetNeedsDisplay ();
-            }
-        }
-    }
+    ///// <summary>Represents the contents of the data shown inside the scrollview</summary>
+    ///// <value>The size of the content.</value>
+    //public new Size ContentSize
+    //{
+    //    get => ContentSize;
+    //    set
+    //    {
+    //        if (ContentSize != value)
+    //        {
+    //            ContentSize = value;
+    //            _contentView.Frame = new Rectangle (_contentOffset, value);
+    //            _vertical.Size = ContentSize.Height;
+    //            _horizontal.Size = ContentSize.Width;
+    //            SetNeedsDisplay ();
+    //        }
+    //    }
+    //}
 
     /// <summary>Get or sets if the view-port is kept always visible in the area of this <see cref="ScrollView"/></summary>
     public bool KeepContentAlwaysInViewport
@@ -233,26 +240,26 @@ public class ScrollView : View
                 _horizontal.OtherScrollBarView.KeepContentAlwaysInViewport = value;
                 Point p = default;
 
-                if (value && -_contentOffset.X + Viewport.Width > _contentSize.Width)
+                if (value && -_contentOffset.X + Viewport.Width > ContentSize.Width)
                 {
                     p = new Point (
-                                   _contentSize.Width - Viewport.Width + (_showVerticalScrollIndicator ? 1 : 0),
+                                   ContentSize.Width - Viewport.Width + (_showVerticalScrollIndicator ? 1 : 0),
                                    -_contentOffset.Y
                                   );
                 }
 
-                if (value && -_contentOffset.Y + Viewport.Height > _contentSize.Height)
+                if (value && -_contentOffset.Y + Viewport.Height > ContentSize.Height)
                 {
                     if (p == default (Point))
                     {
                         p = new Point (
                                        -_contentOffset.X,
-                                       _contentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0)
+                                       ContentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0)
                                       );
                     }
                     else
                     {
-                        p.Y = _contentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0);
+                        p.Y = ContentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0);
                     }
                 }
 
@@ -362,10 +369,8 @@ public class ScrollView : View
     {
         SetViewsNeedsDisplay ();
 
-        Rectangle savedClip = ClipToViewport ();
-
         // TODO: It's bad practice for views to always clear a view. It negates clipping.
-        Clear ();
+        ClearVisibleContent();
 
         if (!string.IsNullOrEmpty (_contentView.Text) || _contentView.Subviews.Count > 0)
         {
@@ -373,8 +378,6 @@ public class ScrollView : View
         }
 
         DrawScrollBars ();
-
-        Driver.Clip = savedClip;
     }
 
     /// <inheritdoc/>
@@ -606,7 +609,7 @@ public class ScrollView : View
     {
         // INTENT: Unclear intent. How about a call to Offset?
         _contentOffset = new Point (-Math.Abs (offset.X), -Math.Abs (offset.Y));
-        _contentView.Frame = new Rectangle (_contentOffset, _contentSize);
+        _contentView.Frame = new Rectangle (_contentOffset, ContentSize);
         int p = Math.Max (0, -_contentOffset.Y);
 
         if (_vertical.Position != p)
@@ -637,7 +640,7 @@ public class ScrollView : View
         bool v = false, h = false;
         var p = false;
 
-        if (Viewport.Height == 0 || Viewport.Height > _contentSize.Height)
+        if (Viewport.Height == 0 || Viewport.Height > ContentSize.Height)
         {
             if (ShowVerticalScrollIndicator)
             {
@@ -646,7 +649,7 @@ public class ScrollView : View
 
             v = false;
         }
-        else if (Viewport.Height > 0 && Viewport.Height == _contentSize.Height)
+        else if (Viewport.Height > 0 && Viewport.Height == ContentSize.Height)
         {
             p = true;
         }
@@ -660,7 +663,7 @@ public class ScrollView : View
             v = true;
         }
 
-        if (Viewport.Width == 0 || Viewport.Width > _contentSize.Width)
+        if (Viewport.Width == 0 || Viewport.Width > ContentSize.Width)
         {
             if (ShowHorizontalScrollIndicator)
             {
@@ -669,7 +672,7 @@ public class ScrollView : View
 
             h = false;
         }
-        else if (Viewport.Width > 0 && Viewport.Width == _contentSize.Width && p)
+        else if (Viewport.Width > 0 && Viewport.Width == ContentSize.Width && p)
         {
             if (ShowHorizontalScrollIndicator)
             {
@@ -721,13 +724,13 @@ public class ScrollView : View
 
         if (v)
         {
-            _vertical.SetRelativeLayout (ContentSize);
+            _vertical.SetRelativeLayout (Viewport.Size);
             _vertical.Draw ();
         }
 
         if (h)
         {
-            _horizontal.SetRelativeLayout (ContentSize);
+            _horizontal.SetRelativeLayout (Viewport.Size);
             _horizontal.Draw ();
         }
 
@@ -735,7 +738,7 @@ public class ScrollView : View
 
         if (v && h)
         {
-            _contentBottomRightCorner.SetRelativeLayout (ContentSize);
+            _contentBottomRightCorner.SetRelativeLayout (Viewport.Size);
             _contentBottomRightCorner.Draw ();
         }
     }

+ 1 - 1
Terminal.Gui/Views/Toplevel.cs

@@ -287,7 +287,7 @@ public partial class Toplevel : View
                 if (view.Frame.IntersectsWith (Viewport) && !OutsideTopFrame (this))
                 {
                     //view.SetNeedsLayout ();
-                    view.SetNeedsDisplay (view.Viewport);
+                    view.SetNeedsDisplay ();
                     view.SetSubViewNeedsDisplay ();
                 }
             }

+ 1 - 1
UICatalog/Scenarios/VirtualContentScrolling.cs

@@ -100,7 +100,7 @@ public class VirtualScrolling : Scenario
     {
         Application.Init ();
 
-        var view = new VirtualDemoView { Title = "Virtual Demo View" };
+        var view = new VirtualDemoView { Title = "Virtual Scrolling" };
 
         var tf1 = new TextField { X = 20, Y = 7, Width = 10, Text = "TextField" };
         var color = new ColorPicker { Title = "BG", BoxHeight = 1, BoxWidth = 1, X = Pos.AnchorEnd (11) };

+ 1 - 1
UnitTests/Views/ScrollViewTests.cs

@@ -354,7 +354,7 @@ public class ScrollViewTests
         Assert.True (sv.CanFocus);
         Assert.Equal (new Rectangle (1, 2, 20, 10), sv.Frame);
         Assert.Equal (Point.Empty, sv.ContentOffset);
-        Assert.Equal (Size.Empty, sv.ContentSize);
+        Assert.Equal (sv.Viewport.Size, sv.ContentSize);
         Assert.True (sv.AutoHideScrollBars);
         Assert.True (sv.KeepContentAlwaysInViewport);
     }