diff --git a/Terminal.Gui/View/View.Content.cs b/Terminal.Gui/View/View.Content.cs
index 719427d70..3f3790ddd 100644
--- a/Terminal.Gui/View/View.Content.cs
+++ b/Terminal.Gui/View/View.Content.cs
@@ -348,6 +348,14 @@ public partial class View
}
}
+ if (!ViewportSettings.HasFlag (ViewportSettings.AllowNegativeXWhenWidthGreaterThanContentWidth))
+ {
+ if (Viewport.Width > GetContentSize ().Width)
+ {
+ newViewport.X = 0;
+ }
+ }
+
if (!ViewportSettings.HasFlag (ViewportSettings.AllowYGreaterThanContentHeight))
{
if (newViewport.Y >= GetContentSize ().Height)
@@ -356,6 +364,14 @@ public partial class View
}
}
+ if (!ViewportSettings.HasFlag (ViewportSettings.AllowNegativeYWhenHeightGreaterThanContentHeight))
+ {
+ if (Viewport.Height > GetContentSize ().Height)
+ {
+ newViewport.Y = 0;
+ }
+ }
+
// IMPORTANT: Check for negative location AFTER checking for location greater than content width
if (!ViewportSettings.HasFlag (ViewportSettings.AllowNegativeY))
{
diff --git a/Terminal.Gui/View/ViewportSettings.cs b/Terminal.Gui/View/ViewportSettings.cs
index a84899394..32b734067 100644
--- a/Terminal.Gui/View/ViewportSettings.cs
+++ b/Terminal.Gui/View/ViewportSettings.cs
@@ -76,7 +76,7 @@ public enum ViewportSettings
AllowYGreaterThanContentHeight = 8,
///
- /// If set, .Size can be set values greater than
+ /// If set, .Location can be set values greater than
/// enabling scrolling beyond the bottom-right
/// of the content area.
///
@@ -87,11 +87,42 @@ public enum ViewportSettings
///
AllowLocationGreaterThanContentSize = AllowXGreaterThanContentWidth | AllowYGreaterThanContentHeight,
+ ///
+ /// If set and .Width is greater than
+ /// .Width .X can be negative.
+ ///
+ /// When not set, .X will be constrained to non-negative values, preventing
+ /// scrolling beyond the left of the Viewport.
+ ///
+ ///
+ /// This can be useful in infinite scrolling scenarios.
+ ///
+ ///
+ AllowNegativeXWhenWidthGreaterThanContentWidth = 16,
+
+ ///
+ /// If set and .Height is greater than
+ /// .Height .Y can be negative.
+ ///
+ /// When not set, .Y will be constrained to non-negative values, preventing
+ /// scrolling above the top of the Viewport.
+ ///
+ ///
+ /// This can be useful in infinite scrolling scenarios.
+ ///
+ ///
+ AllowNegativeYWhenHeightGreaterThanContentHeight = 32,
+
+ ///
+ /// The combination of and .
+ ///
+ AllowNegativeLocationWhenSizeGreaterThanContentSize = AllowNegativeXWhenWidthGreaterThanContentWidth | AllowNegativeYWhenHeightGreaterThanContentHeight,
+
///
/// By default, clipping is applied to the . Setting this flag will cause clipping to be
/// applied to the visible content area.
///
- ClipContentOnly = 16,
+ ClipContentOnly = 64,
///
/// If set will clear only the portion of the content
@@ -100,5 +131,5 @@ public enum ViewportSettings
/// must be set for this setting to work (clipping beyond the visible area must be
/// disabled).
///
- ClearContentOnly = 32,
+ ClearContentOnly = 128,
}
diff --git a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs
index bc1892c8b..10df243a1 100644
--- a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs
+++ b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs
@@ -17,7 +17,8 @@ namespace Terminal.Gui;
/// See the Scrolling Deep Dive.
///
///
-/// By default, the built-in View scrollbars (/) have both and set to
+/// By default, the built-in View scrollbars (/
+/// ) have both and set to
/// .
/// To enable them, either set set to or explicitly set
///
@@ -184,7 +185,8 @@ public class ScrollBar : View, IOrientation, IDesignable
#endregion
///
- /// Gets or sets the amount each mouse wheel event, or click on the increment/decrement buttons, will incremenet/decrement the .
+ /// Gets or sets the amount each mouse wheel event, or click on the increment/decrement buttons, will
+ /// incremenet/decrement the .
///
///
/// The default is 1.
diff --git a/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs b/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs
index 19159b8cf..899ee56e0 100644
--- a/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs
+++ b/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs
@@ -1,8 +1,6 @@
#nullable enable
using System.ComponentModel;
-using System.Diagnostics;
-using System.Drawing;
namespace Terminal.Gui;
@@ -13,11 +11,6 @@ namespace Terminal.Gui;
///
///
///
-/// If is set, it will be displayed centered within the slider. Set
-/// to automatically have the Text
-/// be show what percent the slider is to the Superview's Viewport size.
-///
-///
/// Used to represent the proportion of the visible content to the Viewport in a .
///
///
@@ -105,7 +98,7 @@ public class ScrollSlider : View, IOrientation, IDesignable
///
/// Gets or sets the size of the ScrollSlider. This is a helper that gets or sets Width or Height depending
/// on . The size will be clamped between 1 and the dimension of
- /// the 's Viewport.
+ /// the 's Viewport.
///
///
///
diff --git a/UICatalog/Scenarios/CharacterMap/CharMap.cs b/UICatalog/Scenarios/CharacterMap/CharMap.cs
index 62ab02f46..6f4093a36 100644
--- a/UICatalog/Scenarios/CharacterMap/CharMap.cs
+++ b/UICatalog/Scenarios/CharacterMap/CharMap.cs
@@ -134,7 +134,6 @@ public class CharMap : View, IDesignable
KeyBindings.Add (Key.End, Command.End);
MouseClick += Handle_MouseClick;
- MouseEvent += Handle_MouseEvent;
SetContentSize (new (COLUMN_WIDTH * 16 + RowLabelWidth, MAX_CODE_POINT / 16 * _rowHeight + HEADER_HEIGHT));
@@ -468,39 +467,36 @@ public class CharMap : View, IDesignable
// TODO: Use this to demonstrate using a popover to show glyph info on hover
public event EventHandler? Hover;
- private void Handle_MouseEvent (object? sender, MouseEventArgs e)
+ ///
+ protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
{
- if (e.Flags == MouseFlags.WheeledDown)
+ if (mouseEvent.Flags == MouseFlags.WheeledDown)
{
ScrollVertical (1);
- e.Handled = true;
-
- return;
+ return mouseEvent.Handled = true;
}
- if (e.Flags == MouseFlags.WheeledUp)
+ if (mouseEvent.Flags == MouseFlags.WheeledUp)
{
ScrollVertical (-1);
- e.Handled = true;
-
- return;
+ return mouseEvent.Handled = true;
}
- if (e.Flags == MouseFlags.WheeledRight)
+ if (mouseEvent.Flags == MouseFlags.WheeledRight)
{
ScrollHorizontal (1);
- e.Handled = true;
-
- return;
+ return mouseEvent.Handled = true;
}
- if (e.Flags == MouseFlags.WheeledLeft)
+ if (mouseEvent.Flags == MouseFlags.WheeledLeft)
{
ScrollHorizontal (-1);
- e.Handled = true;
+ return mouseEvent.Handled = true;
}
- }
+ return false;
+ }
+
private void Handle_MouseClick (object? sender, MouseEventArgs me)
{
if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked)
diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs
index 78eb9355a..1ff83a96b 100644
--- a/UICatalog/Scenarios/Scrolling.cs
+++ b/UICatalog/Scenarios/Scrolling.cs
@@ -29,7 +29,6 @@ public class Scrolling : Scenario
Width = 60,
Height = 20
};
- demoView.SetContentSize (new (80, 25));
label.Text =
$"{demoView}\nContentSize: {demoView.GetContentSize ()}\nViewport.Location: {demoView.Viewport.Location}";
@@ -149,6 +148,8 @@ public class DemoView : View
private void OnInitialized (object sender, EventArgs e)
{
+ SetContentSize (new (80, 25));
+
var rulerView = new View
{
Height = Dim.Fill (),
@@ -161,6 +162,16 @@ public class DemoView : View
Add (rulerView);
+ var centeredLabel = new Label ()
+ {
+ X = Pos.Center (),
+ Y = Pos.Center (),
+ TextAlignment = Alignment.Center,
+ VerticalTextAlignment = Alignment.Center,
+ Text = $"This label is centred.\nContentSize is {GetContentSize ()}"
+ };
+ Add (centeredLabel);
+
var pressMeButton = new Button
{
X = 1,
@@ -209,7 +220,7 @@ public class DemoView : View
Y = 40,
Width = 50,
ColorScheme = Colors.ColorSchemes ["Error"],
- Text = "Last line"
+ Text = "Last line - Beyond content area @ Y = 40"
}
);
@@ -229,4 +240,33 @@ public class DemoView : View
};
Add (anchorButton);
}
+
+ protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
+ {
+ if (mouseEvent.Flags == MouseFlags.WheeledDown)
+ {
+ ScrollVertical (1);
+ return mouseEvent.Handled = true;
+ }
+
+ if (mouseEvent.Flags == MouseFlags.WheeledUp)
+ {
+ ScrollVertical (-1);
+ return mouseEvent.Handled = true;
+ }
+
+ if (mouseEvent.Flags == MouseFlags.WheeledRight)
+ {
+ ScrollHorizontal (1);
+ return mouseEvent.Handled = true;
+ }
+
+ if (mouseEvent.Flags == MouseFlags.WheeledLeft)
+ {
+ ScrollHorizontal (-1);
+ return mouseEvent.Handled = true;
+ }
+
+ return false;
+ }
}