Scrollviews, some rendering bug fixes, some scrollview event handling

This commit is contained in:
Miguel de Icaza
2018-01-27 22:51:48 -05:00
parent 85692036ec
commit 4de3083bba
5 changed files with 150 additions and 12 deletions

View File

@@ -257,7 +257,7 @@ namespace Terminal.Gui {
/// </summary>
public void SetNeedsDisplay ()
{
SetNeedsDisplay (Frame);
SetNeedsDisplay (Bounds);
}
/// <summary>
@@ -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 {
}
}
/// <summary>
/// Clears the specfied rectangular region with the current color
/// </summary>
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 (' ');
}
}
/// <summary>
/// Converts the (col,row) position from the view into a screen (col,row). The values are clamped to (0..ScreenDim-1)
/// </summary>
@@ -1012,6 +1029,27 @@ namespace Terminal.Gui {
public override void Add (View view)
{
contentView.Add (view);
if (view.CanFocus)
CanFocus = true;
}
/// <summary>
/// Removes a widget from this container.
/// </summary>
/// <remarks>
/// </remarks>
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)

View File

@@ -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)) {

View File

@@ -59,6 +59,27 @@ namespace Terminal.Gui {
public override void Add (View view)
{
contentView.Add (view);
if (view.CanFocus)
CanFocus = true;
}
/// <summary>
/// Removes a widget from this container.
/// </summary>
/// <remarks>
/// </remarks>
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)

View File

@@ -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 {
/// <summary>
/// ScrollBarViews are views that display a 1-character scrollbar, either horizontal or vertical
/// </summary>
/// <remarks>
/// The scrollbar is drawn to be a representation of the Size, assuming that the
/// scroll position is set at Position.
/// <para>
/// The scrollbar is drawn to be a representation of the Size, assuming that the
/// scroll position is set at Position.
/// </para>
/// <para>
/// If the region to display the scrollbar is larger than three characters,
/// arrow indicators are drawn.
/// </para>
/// </remarks>
public class ScrollBarView : View {
bool vertical;
@@ -36,6 +44,11 @@ namespace Terminal.Gui {
}
}
/// <summary>
/// This event is raised when the position on the scrollbar has changed.
/// </summary>
public event Action ChangedPosition;
/// <summary>
/// The position to show the scrollbar at.
/// </summary>
@@ -48,6 +61,12 @@ namespace Terminal.Gui {
}
}
void SetPosition (int newPos)
{
Position = newPos;
ChangedPosition?.Invoke ();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:Terminal.Gui.Gui.ScrollBarView"/> class.
/// </summary>
@@ -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;
}
}
/// <summary>
@@ -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);

19
demo.cs
View File

@@ -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;