diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 808d829b0..c9f6b73cc 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -890,7 +890,15 @@ namespace Terminal.Gui { if (view.layoutNeeded) view.LayoutSubviews (); Application.CurrentView = view; - view.Redraw (view.Bounds); + + // Ensure we don't make the Driver's clip rect any bigger + if (Driver.Clip.IsEmpty || Driver.Clip.Contains(RectToScreen (view.Bounds))) { + var savedClip = ClipToBounds (); + view.Redraw (view.Bounds); + Driver.Clip = savedClip; + } else { + view.Redraw (view.Bounds); + } } view.NeedDisplay = Rect.Empty; view.childNeedsDisplay = false; diff --git a/Terminal.Gui/Core/Window.cs b/Terminal.Gui/Core/Window.cs index 548acf3ed..285c26bcb 100644 --- a/Terminal.Gui/Core/Window.cs +++ b/Terminal.Gui/Core/Window.cs @@ -153,16 +153,24 @@ namespace Terminal.Gui { /// public override void Redraw (Rect bounds) { + //var padding = 0; Application.CurrentView = this; var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height)); - var savedClip = Driver.Clip; - Driver.Clip = ScreenClip (RectToScreen (Bounds)); if (NeedDisplay != null && !NeedDisplay.IsEmpty) { Driver.SetAttribute (ColorScheme.Normal); Driver.DrawFrame (scrRect, padding, true); } - contentView.Redraw (contentView.Bounds); + + + if (Driver.Clip.IsEmpty || Driver.Clip.Contains (RectToScreen (contentView.Bounds))) { + var savedClip = Driver.Clip; + Driver.Clip = ClipToBounds(); + contentView.Redraw (contentView.Bounds); + Driver.Clip = savedClip; + } else { + contentView.Redraw (contentView.Bounds); + } ClearNeedsDisplay (); Driver.SetAttribute (ColorScheme.Normal); Driver.DrawFrame (scrRect, padding, false); @@ -170,7 +178,6 @@ namespace Terminal.Gui { if (HasFocus) Driver.SetAttribute (ColorScheme.HotNormal); Driver.DrawWindowTitle (scrRect, Title, padding, padding, padding, padding); - Driver.Clip = savedClip; Driver.SetAttribute (ColorScheme.Normal); } diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index 93fecf4b5..a0aba70a2 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -137,14 +137,20 @@ namespace Terminal.Gui { var padding = 0; Application.CurrentView = this; var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height)); - var savedClip = Driver.Clip; - Driver.Clip = ScreenClip (RectToScreen (Bounds)); if (NeedDisplay != null && !NeedDisplay.IsEmpty) { Driver.SetAttribute (ColorScheme.Normal); Driver.DrawFrame (scrRect, padding, true); } - contentView.Redraw (contentView.Bounds); + + if (Driver.Clip.IsEmpty || Driver.Clip.Contains (contentView.RectToScreen (contentView.Bounds))) { + var savedClip = Driver.Clip; + Driver.Clip = ScreenClip (RectToScreen (Bounds)); + contentView.Redraw (contentView.Bounds); + Driver.Clip = savedClip; + } else { + contentView.Redraw (contentView.Bounds); + } ClearNeedsDisplay (); Driver.SetAttribute (ColorScheme.Normal); Driver.DrawFrame (scrRect, padding, false); @@ -152,7 +158,6 @@ namespace Terminal.Gui { if (HasFocus) Driver.SetAttribute (ColorScheme.HotNormal); Driver.DrawWindowTitle (scrRect, Title, padding, padding, padding, padding); - Driver.Clip = savedClip; Driver.SetAttribute (ColorScheme.Normal); } } diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 64689a437..30fc61da1 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -401,11 +401,21 @@ namespace Terminal.Gui { public override void Redraw(Rect region) { SetViewsNeedsDisplay (); - var oldClip = ClipToBounds (); Driver.SetAttribute (ColorScheme.Normal); Clear (); - base.Redraw(region); - Driver.Clip = oldClip; + + //if (Driver.Clip.IsEmpty || Driver.Clip.Contains (RectToScreen (Bounds)) || Driver.Clip.Contains (contentView.RectToScreen (contentView.Bounds))) { + var savedClip = Driver.Clip; + Driver.Clip = ClipToBounds (); + //vertical.Redraw (vertical.Bounds); + //horizontal.Redraw (vertical.Bounds); + contentView.Redraw (contentView.Bounds); + Driver.Clip = savedClip; + //} else { + // vertical.Redraw (vertical.Bounds); + // horizontal.Redraw (vertical.Bounds); + // contentView.Redraw (contentView.Bounds); + //} Driver.SetAttribute (ColorScheme.Normal); } diff --git a/UICatalog/Properties/launchSettings.json b/UICatalog/Properties/launchSettings.json index 68c82f53f..19b9ce46a 100644 --- a/UICatalog/Properties/launchSettings.json +++ b/UICatalog/Properties/launchSettings.json @@ -1,7 +1,8 @@ { "profiles": { "UICatalog": { - "commandName": "Project" + "commandName": "Project", + "commandLineArgs": "Scrolling" } } } \ No newline at end of file diff --git a/UICatalog/Scenarios/MessageBoxes.cs b/UICatalog/Scenarios/MessageBoxes.cs index e21720e66..d36b00f1f 100644 --- a/UICatalog/Scenarios/MessageBoxes.cs +++ b/UICatalog/Scenarios/MessageBoxes.cs @@ -110,7 +110,7 @@ namespace UICatalog { var styleRadioGroup = new RadioGroup (new [] { "_Query", "_Error" } ) { X = Pos.Right (label) + 1, Y = Pos.Top (label), - Width = 5, // BUGBUG: This should cause clipping! + Width = 5, // BUGBUG: This should cause clipping! #399 }; frame.Add (styleRadioGroup); diff --git a/UICatalog/Scenarios/Progress.cs b/UICatalog/Scenarios/Progress.cs index 6351de13c..ee26167e8 100644 --- a/UICatalog/Scenarios/Progress.cs +++ b/UICatalog/Scenarios/Progress.cs @@ -41,7 +41,7 @@ namespace UICatalog { LeftFrame = new FrameView ("Settings") { X = 0, Y = 0, - Height = Dim.Percent (100) + 1, // BUGBUG: This +1 should not be needed + Height = Dim.Percent (100), // BUGBUG: This +1 should not be needed Width = Dim.Percent (25) }; var lbl = new Label (1, 1, "Tick every (ms):"); @@ -223,14 +223,13 @@ namespace UICatalog { var startBoth = new Button ("Start Both") { X = Pos.Center (), - Y = Pos.AnchorEnd () - 1, + Y = Pos.Bottom(mainLoopTimeoutDemo) + 1, }; startBoth.Clicked = () => { systemTimerDemo.Start (); mainLoopTimeoutDemo.Start (); }; Win.Add (startBoth); - } protected override void Dispose (bool disposing) diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs new file mode 100644 index 000000000..30d3f000d --- /dev/null +++ b/UICatalog/Scenarios/Scrolling.cs @@ -0,0 +1,96 @@ +using System; +using Terminal.Gui; + +namespace UICatalog { + [ScenarioMetadata (Name: "Scrolling", Description: "Demonstrates ScrollView etc...")] + [ScenarioCategory ("Controls")] + [ScenarioCategory ("Bug Repro")] + + class Scrolling : Scenario { + public override void Setup () + { + var label = new Label ("ScrollView (new Rect (2, 2, 50, 20)) with a 100, 100 ContentSize...") { + X = 0, Y = 0, + ColorScheme = Colors.Dialog + }; + Win.Add (label); + + // BUGBUG: ScrollView only supports Absolute Positioning (#72) + var scrollView = new ScrollView (new Rect (2, 2, 50, 20)); + scrollView.ColorScheme = Colors.TopLevel; + scrollView.ContentSize = new Size (100, 100); + //ContentOffset = new Point (0, 0), + scrollView.ShowVerticalScrollIndicator = true; + scrollView.ShowHorizontalScrollIndicator = true; + + const string rule = "|123456789"; + var horizontalRuler = new Label ("") { + X = 0, + Y = 0, + Width = Dim.Fill (1), // BUGBUG: I don't think this should be needed; DimFill() should respect container's frame. X does. + ColorScheme = Colors.Error + }; + scrollView.Add (horizontalRuler); + const string vrule = "|\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.Error + }; + scrollView.Add (verticalRuler); + + Application.Resized += (sender, a) => { + horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)]; + verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height * 2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height * 2)]; + }; + + scrollView.Add (new Button ("Press me!") { + X = 3, + Y = 3, + Clicked = () => MessageBox.Query (20, 7, "MessageBox", "Neat?", "Yes", "No") + }); + + scrollView.Add (new TextField ("This is a test of...") { + X = 3, + Y = 5, + Width = 50, + ColorScheme = Colors.Dialog + }); + + scrollView.Add (new TextField ("... the emergency broadcast sytem.") { + X = 3, + Y = 10, + Width = 50, + ColorScheme = Colors.Dialog + }); + + scrollView.Add (new TextField ("Last line") { + X = 3, + Y = 99, + Width = 50, + ColorScheme = Colors.Dialog + }); + + // Demonstrate AnchorEnd - Button is anchored to bottom/right + var anchorButton = new Button ("Bottom Right") { + Y = Pos.AnchorEnd () - 1, + }; + // TODO: Use Pos.Width instead of (Right-Left) when implemented (#502) + anchorButton.X = Pos.AnchorEnd () - (Pos.Right (anchorButton) - Pos.Left (anchorButton)); + anchorButton.Clicked = () => { + // Ths demonstrates how to have a dynamically sized button + // Each time the button is clicked the button's text gets longer + // The call to Win.LayoutSubviews causes the Computed layout to + // get updated. + anchorButton.Text += "!"; + Win.LayoutSubviews (); + }; + scrollView.Add (anchorButton); + + Win.Add (scrollView); + } + } +} \ No newline at end of file diff --git a/UICatalog/Scenarios/WindowsAndFrameViews.cs b/UICatalog/Scenarios/WindowsAndFrameViews.cs index 5d575e06b..714c1bd9f 100644 --- a/UICatalog/Scenarios/WindowsAndFrameViews.cs +++ b/UICatalog/Scenarios/WindowsAndFrameViews.cs @@ -104,11 +104,11 @@ namespace UICatalog { Height = height, }; frame.ColorScheme = Colors.Dialog; - frame.Add (new Button ("Press me! (Y = 0)") { + frame.Add (new Label ("This is a Label! (Y = 0)") { X = Pos.Center (), Y = 0, ColorScheme = Colors.Error, - Clicked = () => MessageBox.ErrorQuery (30, 10, frame.Title.ToString (), "Neat?", "Yes", "No") + //Clicked = () => MessageBox.ErrorQuery (30, 10, frame.Title.ToString (), "Neat?", "Yes", "No") }); var subWinofFV = new Window ("this is a Sub-Window") { X = Pos.Percent (0),