diff --git a/Terminal.Gui/View/View.ScrollBars.cs b/Terminal.Gui/View/View.ScrollBars.cs index cbea93ee4..d3e56344f 100644 --- a/Terminal.Gui/View/View.ScrollBars.cs +++ b/Terminal.Gui/View/View.ScrollBars.cs @@ -43,10 +43,15 @@ public partial class View Bottom = scrollBar.Visible ? Padding.Thickness.Bottom + 1 : 0 }; - scrollBar.SliderPositionChanged += (_, args) => - { - Viewport = Viewport with { X = args.CurrentValue }; - }; + scrollBar.ContentPositionChanged += (_, args) => + { + Viewport = Viewport with + { + X = Math.Min ( + args.CurrentValue, + GetContentSize ().Width - (Viewport.Width)) + }; + }; scrollBar.VisibleChanged += (_, _) => { @@ -96,18 +101,23 @@ public partial class View Right = scrollBar.Visible ? Padding.Thickness.Right + 1 : 0 }; - scrollBar.SliderPositionChanged += (_, args) => - { - Viewport = Viewport with { Y = args.CurrentValue }; - }; + scrollBar.ContentPositionChanged += (_, args) => + { + Viewport = Viewport with + { + Y = Math.Min ( + args.CurrentValue, + GetContentSize ().Height - (Viewport.Height)) + }; + }; scrollBar.VisibleChanged += (_, _) => { Padding.Thickness = Padding.Thickness with { Right = scrollBar.Visible - ? Padding.Thickness.Right + 1 - : Padding.Thickness.Right - 1 + ? Padding.Thickness.Right + 1 + : Padding.Thickness.Right - 1 }; }; } @@ -120,12 +130,12 @@ public partial class View { if (_verticalScrollBar.IsValueCreated) { - _verticalScrollBar.Value.SliderPosition = Viewport.Y; + _verticalScrollBar.Value.ContentPosition = Viewport.Y; } if (_horizontalScrollBar.IsValueCreated) { - _horizontalScrollBar.Value.SliderPosition = Viewport.X; + _horizontalScrollBar.Value.ContentPosition = Viewport.X; } }; diff --git a/Terminal.Gui/Views/Scroll/Scroll.cs b/Terminal.Gui/Views/Scroll/Scroll.cs index e240d5cdb..02ef59356 100644 --- a/Terminal.Gui/Views/Scroll/Scroll.cs +++ b/Terminal.Gui/Views/Scroll/Scroll.cs @@ -159,7 +159,7 @@ public class Scroll : View, IOrientation, IDesignable { int currentSliderPosition = CalculateSliderPosition (_contentPosition); - if (newSliderPosition > Size - ViewportDimension || currentSliderPosition == newSliderPosition) + if (/*newSliderPosition > Size - ViewportDimension ||*/ currentSliderPosition == newSliderPosition) { return; } diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index 1c5775541..dd65f84a7 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -125,7 +125,7 @@ public class ContentScrolling : Scenario app.Add (view); // Add Scroll Setting UI to Padding - view.Padding.Thickness = view.Padding.Thickness with { Top = view.Padding.Thickness.Top + 4 }; + view.Padding.Thickness = view.Padding.Thickness with { Top = view.Padding.Thickness.Top + 6 }; view.Padding.CanFocus = true; Label frameLabel = new () diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs index 8d7cdac00..a87ea4fae 100644 --- a/UICatalog/Scenarios/Scrolling.cs +++ b/UICatalog/Scenarios/Scrolling.cs @@ -3,35 +3,25 @@ using Terminal.Gui; namespace UICatalog.Scenarios; -[ScenarioMetadata ("Scrolling", "Demonstrates scrolling etc...")] +[ScenarioMetadata ("Scrolling", "Content scrolling, IScrollBars, etc...")] [ScenarioCategory ("Controls")] [ScenarioCategory ("Scrolling")] [ScenarioCategory ("Tests")] public class Scrolling : Scenario { - private ViewDiagnosticFlags _diagnosticFlags; - public override void Main () { Application.Init (); - _diagnosticFlags = View.Diagnostics; - View.Diagnostics = ViewDiagnosticFlags.Ruler; var app = new Window { Title = GetQuitKeyAndName (), - - // Offset to stress clipping - X = 3, - Y = 3, - Width = Dim.Fill (3), - Height = Dim.Fill (3) }; var label = new Label { X = 0, Y = 0 }; app.Add (label); - var scrollView = new ScrollView + var scrollView = new IScrollView { Id = "scrollView", X = 2, @@ -39,53 +29,48 @@ public class Scrolling : Scenario Width = 60, Height = 20, ColorScheme = Colors.ColorSchemes ["TopLevel"], - - //ContentOffset = Point.Empty, - ShowVerticalScrollIndicator = true, - ShowHorizontalScrollIndicator = true + CanFocus = true, + BorderStyle = LineStyle.Heavy, + Arrangement = ViewArrangement.Resizable }; - // BUGBUG: set_ContentSize is supposed to be `protected`. - scrollView.SetContentSize (new (120, 40)); - scrollView.Padding.Thickness = new (1); + scrollView.SetContentSize (new (80, 25)); + //scrollView.Padding.Thickness = new (1); + //scrollView.Padding.Diagnostics = ViewDiagnosticFlags.Ruler; - label.Text = $"{scrollView}\nContentSize: {scrollView.GetContentSize ()}\nContentOffset: {scrollView.ContentOffset}"; - - const string rule = "0123456789"; - - var horizontalRuler = new Label + View rulerView = new View () { - X = 0, - Y = 0, - - Width = Dim.Fill (), - Height = 2, - ColorScheme = Colors.ColorSchemes ["Error"] - }; - scrollView.Add (horizontalRuler); - - const string vrule = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n"; - - var verticalRuler = new Label - { - X = 0, - Y = 0, - - Width = 1, Height = Dim.Fill (), - ColorScheme = Colors.ColorSchemes ["Error"] + Width = Dim.Fill (), }; - scrollView.Add (verticalRuler); + rulerView.Border.Thickness = new (1); + rulerView.Border.LineStyle = LineStyle.None; + rulerView.Border.Diagnostics = ViewDiagnosticFlags.Ruler; + rulerView.Border.ColorScheme = Colors.ColorSchemes ["Error"]; - var pressMeButton = new Button { X = 3, Y = 3, Text = "Press me!" }; + scrollView.Add (rulerView); + label.Text = + $"{scrollView}\nContentSize: {scrollView.GetContentSize ()}\nViewport.Location: {scrollView.Viewport.Location}"; + + scrollView.ViewportChanged += (_, _) => + { + label.Text = + $"{scrollView}\nContentSize: {scrollView.GetContentSize ()}\nViewport.Location: {scrollView.Viewport.Location}"; + }; + + var pressMeButton = new Button + { + X = 1, + Y = 1, + Text = "Press me!" + }; pressMeButton.Accepting += (s, e) => MessageBox.Query (20, 7, "MessageBox", "Neat?", "Yes", "No"); scrollView.Add (pressMeButton); var aLongButton = new Button { - X = 3, - Y = 4, + X = Pos.Right (pressMeButton), + Y = Pos.Bottom (pressMeButton), - Width = Dim.Fill (3), Text = "A very long button. Should be wide enough to demo clipping!" }; aLongButton.Accepting += (s, e) => MessageBox.Query (20, 7, "MessageBox", "Neat?", "Yes", "No"); @@ -94,8 +79,8 @@ public class Scrolling : Scenario scrollView.Add ( new TextField { - X = 3, - Y = 5, + X = Pos.Left (pressMeButton), + Y = Pos.Bottom (aLongButton) + 1, Width = 50, ColorScheme = Colors.ColorSchemes ["Dialog"], Text = "This is a test of..." @@ -105,8 +90,8 @@ public class Scrolling : Scenario scrollView.Add ( new TextField { - X = 3, - Y = 10, + X = Pos.Left (pressMeButton), + Y = Pos.Bottom (aLongButton) + 3, Width = 50, ColorScheme = Colors.ColorSchemes ["Dialog"], Text = "... the emergency broadcast system." @@ -116,19 +101,21 @@ public class Scrolling : Scenario scrollView.Add ( new TextField { - X = 3, - Y = 99, + X = Pos.Left (pressMeButton), + Y = 40, Width = 50, - ColorScheme = Colors.ColorSchemes ["Dialog"], + ColorScheme = Colors.ColorSchemes ["Error"], Text = "Last line" } ); // Demonstrate AnchorEnd - Button is anchored to bottom/right - var anchorButton = new Button { Y = Pos.AnchorEnd (0) - 1, Text = "Bottom Right" }; - - // TODO: Use Pos.Width instead of (Right-Left) when implemented (#502) - anchorButton.X = Pos.AnchorEnd (0) - (Pos.Right (anchorButton) - Pos.Left (anchorButton)); + var anchorButton = new Button + { + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), + Text = "Bottom Right" + }; anchorButton.Accepting += (s, e) => { @@ -141,74 +128,51 @@ public class Scrolling : Scenario app.Add (scrollView); + scrollView.HorizontalScrollBar.Visible = true; var hCheckBox = new CheckBox { X = Pos.X (scrollView), Y = Pos.Bottom (scrollView), Text = "Horizontal Scrollbar", - CheckedState = scrollView.ShowHorizontalScrollIndicator ? CheckState.Checked : CheckState.UnChecked + CheckedState = scrollView.HorizontalScrollBar.Visible ? CheckState.Checked : CheckState.UnChecked }; app.Add (hCheckBox); + hCheckBox.CheckedStateChanged += (sender, args) => + { + scrollView.HorizontalScrollBar.Visible = args.CurrentValue == CheckState.Checked; + }; + scrollView.VerticalScrollBar.Visible = true; var vCheckBox = new CheckBox { X = Pos.Right (hCheckBox) + 3, Y = Pos.Bottom (scrollView), Text = "Vertical Scrollbar", - CheckedState = scrollView.ShowVerticalScrollIndicator ? CheckState.Checked : CheckState.UnChecked + CheckedState = scrollView.VerticalScrollBar.Visible ? CheckState.Checked : CheckState.UnChecked }; app.Add (vCheckBox); + vCheckBox.CheckedStateChanged += (sender, args) => + { + scrollView.VerticalScrollBar.Visible = args.CurrentValue == CheckState.Checked; + }; var t = "Auto Hide Scrollbars"; var ahCheckBox = new CheckBox { - X = Pos.Left (scrollView), Y = Pos.Bottom (hCheckBox), Text = t, CheckedState = scrollView.AutoHideScrollBars ? CheckState.Checked : CheckState.UnChecked + X = Pos.Left (scrollView), Y = Pos.Bottom (hCheckBox), Text = t, + CheckedState = scrollView.HorizontalScrollBar.AutoHide ? CheckState.Checked : CheckState.UnChecked }; - var k = "Keep Content Always In Viewport"; - - var keepCheckBox = new CheckBox - { - X = Pos.Left (scrollView), Y = Pos.Bottom (ahCheckBox), Text = k, CheckedState = scrollView.AutoHideScrollBars ? CheckState.Checked : CheckState.UnChecked - }; - - hCheckBox.CheckedStateChanging += (s, e) => - { - if (ahCheckBox.CheckedState == CheckState.UnChecked) - { - scrollView.ShowHorizontalScrollIndicator = e.NewValue == CheckState.Checked; - } - else - { - hCheckBox.CheckedState = CheckState.Checked; - MessageBox.Query ("Message", "Disable Auto Hide Scrollbars first.", "Ok"); - } - }; - - vCheckBox.CheckedStateChanging += (s, e) => - { - if (ahCheckBox.CheckedState == CheckState.UnChecked) - { - scrollView.ShowVerticalScrollIndicator = e.NewValue == CheckState.Checked; - } - else - { - vCheckBox.CheckedState = CheckState.Checked; - MessageBox.Query ("Message", "Disable Auto Hide Scrollbars first.", "Ok"); - } - }; ahCheckBox.CheckedStateChanging += (s, e) => { - scrollView.AutoHideScrollBars = e.NewValue == CheckState.Checked; + scrollView.HorizontalScrollBar.AutoHide = e.NewValue == CheckState.Checked; + scrollView.VerticalScrollBar.AutoHide = e.NewValue == CheckState.Checked; hCheckBox.CheckedState = CheckState.Checked; vCheckBox.CheckedState = CheckState.Checked; }; app.Add (ahCheckBox); - keepCheckBox.CheckedStateChanging += (s, e) => scrollView.KeepContentAlwaysInViewport = e.NewValue == CheckState.Checked; - app.Add (keepCheckBox); - var count = 0; var mousePos = new Label @@ -238,38 +202,24 @@ public class Scrolling : Scenario Application.AddTimeout (TimeSpan.FromMilliseconds (300), timer); - app.Loaded += App_Loaded; app.Unloaded += app_Unloaded; + Application.Run (app); - app.Loaded -= App_Loaded; app.Unloaded -= app_Unloaded; app.Dispose (); Application.Shutdown (); return; - // Local functions - void App_Loaded (object sender, EventArgs args) - { - horizontalRuler.Text = - rule.Repeat ((int)Math.Ceiling (horizontalRuler.Viewport.Width / (double)rule.Length)) [ - ..horizontalRuler.Viewport.Width] - + "\n" - + "| ".Repeat ( - (int)Math.Ceiling (horizontalRuler.Viewport.Width / (double)rule.Length) - ) [ - ..horizontalRuler.Viewport.Width]; - - verticalRuler.Text = - vrule.Repeat ((int)Math.Ceiling (verticalRuler.Viewport.Height * 2 / (double)rule.Length)) - [..(verticalRuler.Viewport.Height * 2)]; - } - void app_Unloaded (object sender, EventArgs args) { - View.Diagnostics = _diagnosticFlags; pulsing = false; } } } + +public class IScrollView : View +{ + +}