diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs
index a0c6cc703..192ecf0d0 100644
--- a/Terminal.Gui/View/ViewDrawing.cs
+++ b/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 (
diff --git a/Terminal.Gui/View/ViewScrolling.cs b/Terminal.Gui/View/ViewScrolling.cs
index 2879d84f5..b07f968b0 100644
--- a/Terminal.Gui/View/ViewScrolling.cs
+++ b/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));
+ }
}
+ ///
+ /// Called when the changes. Invokes the event.
+ ///
+ ///
+ ///
+ protected bool? OnContentSizeChanged (SizeChangedEventArgs e)
+ {
+ ContentSizeChanged?.Invoke (this, e);
+
+ if (e.Cancel != true)
+ {
+ SetNeedsDisplay ();
+ }
+
+ return e.Cancel == true;
+ }
+
+ ///
+ /// Event that is raised when the changes.
+ ///
+ public event EventHandler ContentSizeChanged;
+
///
/// Converts a content-relative location to a screen-relative location.
///
diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs
index a85fdb21c..e56e4d2c5 100644
--- a/Terminal.Gui/Views/ScrollBarView.cs
+++ b/Terminal.Gui/Views/ScrollBarView.cs
@@ -275,7 +275,7 @@ public class ScrollBarView : View
public event EventHandler ChangedPosition;
///
- 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
diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs
index 22161404a..e35c8d874 100644
--- a/Terminal.Gui/Views/ScrollView.cs
+++ b/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
}
}
- /// Represents the contents of the data shown inside the scrollview
- /// The size of the content.
- 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 ();
- }
- }
- }
+ ///// Represents the contents of the data shown inside the scrollview
+ ///// The size of the content.
+ //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 ();
+ // }
+ // }
+ //}
/// Get or sets if the view-port is kept always visible in the area of this
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;
}
///
@@ -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 ();
}
}
diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs
index b747dc048..47fdd9be7 100644
--- a/Terminal.Gui/Views/Toplevel.cs
+++ b/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 ();
}
}
diff --git a/UICatalog/Scenarios/VirtualContentScrolling.cs b/UICatalog/Scenarios/VirtualContentScrolling.cs
index 096dcc6bb..e55ac36c6 100644
--- a/UICatalog/Scenarios/VirtualContentScrolling.cs
+++ b/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) };
diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs
index a11be9d09..61fc5530e 100644
--- a/UnitTests/Views/ScrollViewTests.cs
+++ b/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);
}