diff --git a/Terminal.Gui/Core.cs b/Terminal.Gui/Core.cs index c06e122b2..2edfac654 100644 --- a/Terminal.Gui/Core.cs +++ b/Terminal.Gui/Core.cs @@ -257,7 +257,7 @@ namespace Terminal.Gui { /// public void SetNeedsDisplay () { - SetNeedsDisplay (Frame); + SetNeedsDisplay (Bounds); } /// @@ -281,7 +281,10 @@ namespace Terminal.Gui { return; foreach (var view in subviews) if (view.Frame.IntersectsWith (region)) { - view.SetNeedsDisplay (Rect.Intersect (view.Frame, region)); + var childRegion = Rect.Intersect (view.Frame, region); + childRegion.X -= view.Frame.X; + childRegion.Y -= view.Frame.Y; + view.SetNeedsDisplay (childRegion); } } @@ -387,6 +390,20 @@ namespace Terminal.Gui { } } + /// + /// Clears the specfied rectangular region with the current color + /// + public void Clear (Rect r) + { + var h = r.Height; + var w = r.Width; + for (int line = 0; line < h; line++) { + Move (0, line); + for (int col = 0; col < w; col++) + Driver.AddRune (' '); + } + } + /// /// Converts the (col,row) position from the view into a screen (col,row). The values are clamped to (0..ScreenDim-1) /// @@ -1012,6 +1029,27 @@ namespace Terminal.Gui { public override void Add (View view) { contentView.Add (view); + if (view.CanFocus) + CanFocus = true; + } + + + /// + /// Removes a widget from this container. + /// + /// + /// + public virtual void Remove (View view) + { + if (view == null) + return; + + SetNeedsDisplay (); + var touched = view.Frame; + contentView.Remove (view); + + if (contentView.Subviews.Count < 1) + this.CanFocus = false; } public override void Redraw (Rect bounds) diff --git a/Terminal.Gui/Driver.cs b/Terminal.Gui/Driver.cs index 372683794..eb3753f00 100644 --- a/Terminal.Gui/Driver.cs +++ b/Terminal.Gui/Driver.cs @@ -332,7 +332,7 @@ namespace Terminal.Gui { } } - static bool sync = true; + static bool sync = false; public override void AddRune (Rune rune) { if (Clip.Contains (ccol, crow)) { diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index f2d15077a..5a0979a05 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -59,6 +59,27 @@ namespace Terminal.Gui { public override void Add (View view) { contentView.Add (view); + if (view.CanFocus) + CanFocus = true; + } + + + /// + /// Removes a widget from this container. + /// + /// + /// + public virtual void Remove (View view) + { + if (view == null) + return; + + SetNeedsDisplay (); + var touched = view.Frame; + contentView.Remove (view); + + if (contentView.Subviews.Count < 1) + this.CanFocus = false; } public override void Redraw (Rect bounds) diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 68a4caafb..411032bf5 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -11,14 +11,22 @@ // - keyboard handling in scrollview to scroll // - focus handling in scrollview to auto scroll to focused view // - Raise events +// - Perhaps allow an option to not display the scrollbar arrow indicators? + using System; namespace Terminal.Gui { /// /// ScrollBarViews are views that display a 1-character scrollbar, either horizontal or vertical /// /// - /// The scrollbar is drawn to be a representation of the Size, assuming that the - /// scroll position is set at Position. + /// + /// The scrollbar is drawn to be a representation of the Size, assuming that the + /// scroll position is set at Position. + /// + /// + /// If the region to display the scrollbar is larger than three characters, + /// arrow indicators are drawn. + /// /// public class ScrollBarView : View { bool vertical; @@ -36,6 +44,11 @@ namespace Terminal.Gui { } } + /// + /// This event is raised when the position on the scrollbar has changed. + /// + public event Action ChangedPosition; + /// /// The position to show the scrollbar at. /// @@ -48,6 +61,12 @@ namespace Terminal.Gui { } } + void SetPosition (int newPos) + { + Position = newPos; + ChangedPosition?.Invoke (); + } + /// /// Initializes a new instance of the class. /// @@ -78,7 +97,7 @@ namespace Terminal.Gui { var bh = Bounds.Height; SpecialChar special; - if (bh < 3) { + if (bh < 4) { var by1 = position * bh / Size; var by2 = (position + bh) * bh / Size; @@ -126,7 +145,20 @@ namespace Terminal.Gui { var row = Bounds.Height - 1; var bw = Bounds.Width; - if (bw < 3) { + SpecialChar special; + + if (bw < 4) { + var bx1 = position * bw / Size; + var bx2 = (position + bw) * bw / Size; + + for (int x = 0; x < bw; x++) { + Move (0, x); + if (x < bx1 || x > bx2) + special = SpecialChar.Stipple; + else + special = SpecialChar.Diamond; + Driver.AddSpecial (special); + } } else { bw -= 2; var bx1 = position * bw / Size; @@ -136,7 +168,6 @@ namespace Terminal.Gui { Driver.AddRune ('<'); for (int x = 0; x < bw; x++) { - SpecialChar special; if (x < bx1 || x > bx2) { special = SpecialChar.Stipple; @@ -158,6 +189,35 @@ namespace Terminal.Gui { } } } + + public override bool MouseEvent(MouseEvent me) + { + if (me.Flags != MouseFlags.Button1Clicked) + return false; + + int location = vertical ? me.Y : me.X; + int barsize = vertical ? Bounds.Height : Bounds.Width; + + if (barsize < 4) { + // Handle scrollbars with no buttons + Console.WriteLine ("TODO at ScrollBarView2"); + } else { + barsize -= 2; + // Handle scrollbars with arrow buttons + var pos = Position; + if (location == 0) { + if (pos > 0) + SetPosition (pos - 1); + } else if (location == Bounds.Width - 1){ + if (pos + 1 + barsize < Size) + SetPosition (pos + 1); + } else { + Console.WriteLine ("TODO at ScrollBarView"); + } + } + + return true; + } } /// @@ -181,7 +241,13 @@ namespace Terminal.Gui { { contentView = new View (frame); vertical = new ScrollBarView (new Rect (frame.Width - 1, 0, 1, frame.Height), frame.Height, 0, isVertical: true); + vertical.ChangedPosition += delegate { + ContentOffset = new Point (ContentOffset.X, vertical.Position); + }; horizontal = new ScrollBarView (new Rect (0, frame.Height-1, frame.Width-1, 1), frame.Width-1, 0, isVertical: false); + horizontal.ChangedPosition += delegate { + ContentOffset = new Point (horizontal.Position, ContentOffset.Y); + }; base.Add (contentView); CanFocus = true; } @@ -279,6 +345,8 @@ namespace Terminal.Gui { public override void Redraw(Rect region) { var oldClip = ClipToBounds (); + Driver.SetAttribute (ColorScheme.Normal); + Clear (); base.Redraw(region); Driver.Clip = oldClip; Driver.SetAttribute (ColorScheme.Normal); diff --git a/demo.cs b/demo.cs index ef4f4b331..6106e72bf 100644 --- a/demo.cs +++ b/demo.cs @@ -67,14 +67,23 @@ class Demo { { var scrollView = new ScrollView (new Rect (50, 10, 20, 8)) { ContentSize = new Size (100, 100), - ContentOffset = new Point (5, -2), + //ContentOffset = new Point (5, -2), ShowVerticalScrollIndicator = true, ShowHorizontalScrollIndicator = true }; - //scrollView.Add (new Box10x (0, 0)); - scrollView.Add (new Filler (new Rect (0, 0, 40, 40))); + scrollView.Add (new Box10x (0, 0)); + //scrollView.Add (new Filler (new Rect (0, 0, 40, 40))); + // This is just to debug the visuals of the scrollview when small + var scrollView2 = new ScrollView (new Rect (72, 10, 3, 3)) { + ContentSize = new Size (100, 100), + ShowVerticalScrollIndicator = true, + ShowHorizontalScrollIndicator = true + }; + scrollView2.Add (new Box10x (0, 0)); + + // Add some content container.Add ( new Label (3, 6, "Login: "), new TextField (14, 6, 40, ""), @@ -84,11 +93,13 @@ class Demo { new CheckBox (1, 0, "Remember me"), new RadioGroup (1, 2, new [] { "_Personal", "_Company" }), }, - scrollView, + //scrollView, + //scrollView2, new Button (3, 19, "Ok"), new Button (10, 19, "Cancel"), new Label (3, 22, "Press ESC and 9 to activate the menubar") ); + } public static Label ml2;