mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fixed ScrollViwe
This commit is contained in:
@@ -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 (
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user