mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 07:47:54 +01:00
Scrollviews, some rendering bug fixes, some scrollview event handling
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
19
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;
|
||||
|
||||
Reference in New Issue
Block a user