using System;
namespace Terminal.Gui {
///
///
///
///
///
/// The subviews that are added to this scrollview are offset by the
/// ContentOffset property. The view itself is a window into the
/// space represented by the ContentSize.
///
///
///
///
///
public class ScrollView : View {
View contentView;
public ScrollView (Rect frame) : base (frame)
{
contentView = new View (frame);
base.Add (contentView);
}
Size contentSize;
Point contentOffset;
bool showHorizontalScrollIndicator;
bool showVerticalScrollIndicator;
///
/// Represents the contents of the data shown inside the scrolview
///
/// The size of the content.
public Size ContentSize {
get {
return contentSize;
}
set {
contentSize = value;
contentView.Frame = new Rect (contentOffset, value);
}
}
///
/// Represents the top left corner coordinate that is displayed by the scrollview
///
/// The content offset.
public Point ContentOffset {
get {
return contentOffset;
}
set {
contentOffset = new Point (-value.X, -value.Y);
contentView.Frame = new Rect (contentOffset, contentSize);
}
}
///
/// Adds the view to the scrollview.
///
/// The view to add to the scrollview.
public override void Add (View view)
{
contentView.Add (view);
}
///
/// Gets or sets the visibility for the horizontal scroll indicator.
///
/// true if show vertical scroll indicator; otherwise, false.
public bool ShowHorizontalScrollIndicator {
get => showHorizontalScrollIndicator;
set {
showHorizontalScrollIndicator = value;
SetNeedsDisplay ();
}
}
///
/// /// Gets or sets the visibility for the vertical scroll indicator.
///
/// true if show vertical scroll indicator; otherwise, false.
public bool ShowVerticalScrollIndicator {
get => showVerticalScrollIndicator;
set {
showVerticalScrollIndicator = value;
SetNeedsDisplay ();
}
}
///
/// This event is raised when the contents have scrolled
///
public event Action Scrolled;
public override void Redraw(Rect region)
{
var oldClip = ClipToBounds ();
base.Redraw(region);
Attribute last = ColorScheme.Normal;
Driver.SetAttribute (last);
void SetColor (Attribute a)
{
if (a != last)
Driver.SetAttribute (a);
last = a;
}
Driver.Clip = oldClip;
if (true || ShowVerticalScrollIndicator) {
var bh = Bounds.Height;
var by1 = -contentOffset.Y * bh/ contentSize.Height;
var by2 = (-contentOffset.Y+bh) * bh/ contentSize.Height;
for (int y = 0; y < bh; y++) {
Move (Bounds.Width - 1, y);
SpecialChar special;
if (y < by1 || y > by2)
special = SpecialChar.Stipple;
else {
if (by2 - by1 == 0)
special = SpecialChar.Diamond;
else {
if (y == by1)
special = SpecialChar.TopTee;
else if (y == by2)
special = SpecialChar.BottomTee;
else
special = SpecialChar.VLine;
}
}
Driver.AddSpecial (special);
}
}
if (true || ShowHorizontalScrollIndicator){
var bw = Bounds.Width;
var bx1 = -contentOffset.X * bw / contentSize.Width;
var bx2 = (-contentOffset.X + bw) * bw / contentSize.Width;
Move (0, Bounds.Height - 1);
for (int x = 0; x < bw; x++) {
SpecialChar special;
if (x < bx1 || x > bx2){
special = SpecialChar.Stipple;
} else {
if (bx2 - bx1 == 0)
special = SpecialChar.Diamond;
else {
if (x == bx1)
special = SpecialChar.LeftTee;
else if (x == bx2)
special = SpecialChar.RightTee;
else
special = SpecialChar.HLine;
}
}
Driver.AddSpecial (special);
}
}
}
}
}