using System;
using Terminal.Gui.Graphs;
using static Terminal.Gui.Dim;
namespace Terminal.Gui {
public class SplitContainer : View {
private LineView splitterLine = new LineView ();
private bool panel1Collapsed;
private bool panel2Collapsed;
private Pos splitterDistance = Pos.Percent (50);
private Orientation orientation = Orientation.Vertical;
public SplitContainer ()
{
// Default to a border of 1 so that View looks nice
Border = new Border ();
this.Add (splitterLine);
this.Add (Panel1);
this.Add (Panel2);
Setup ();
CanFocus = false;
// TODO: Actually respect collapsed statuses
}
private void Setup ()
{
// TODO: Enforce minimum sizes
splitterLine.Orientation = Orientation;
if(panel1Collapsed || panel2Collapsed) {
SetupForCollapsedPanel ();
}
else {
SetupForNormal ();
}
}
private void SetupForNormal ()
{
// Ensure all our component views are here
// (e.g. if we are transitioning from a collapsed state)
if (!this.Subviews.Contains (splitterLine)) {
this.Add (splitterLine);
}
if (!this.Subviews.Contains (Panel1)) {
this.Add (Panel1);
}
if (!this.Subviews.Contains (Panel2)) {
this.Add (Panel2);
}
switch (Orientation) {
case Orientation.Horizontal:
splitterLine.X = 0;
splitterLine.Y = splitterDistance;
splitterLine.Width = Dim.Fill ();
splitterLine.Height = 1;
splitterLine.LineRune = Driver.HLine;
this.Panel1.X = 0;
this.Panel1.Y = 0;
this.Panel1.Width = Dim.Fill ();
this.Panel1.Height = new DimFunc (() =>
splitterDistance.Anchor (Bounds.Height) - 1);
this.Panel2.Y = Pos.Bottom (splitterLine) + 1;
this.Panel2.X = 0;
this.Panel2.Width = Dim.Fill ();
this.Panel2.Height = Dim.Fill ();
break;
case Orientation.Vertical:
splitterLine.X = splitterDistance;
splitterLine.Y = 0;
splitterLine.Width = 1;
splitterLine.Height = Dim.Fill ();
splitterLine.LineRune = Driver.VLine;
this.Panel1.X = 0;
this.Panel1.Y = 0;
this.Panel1.Height = Dim.Fill ();
this.Panel1.Width = new DimFunc (() =>
splitterDistance.Anchor (Bounds.Width) - 1);
this.Panel2.X = Pos.Right (splitterLine) + 1;
this.Panel2.Y = 0;
this.Panel2.Width = Dim.Fill ();
this.Panel2.Height = Dim.Fill ();
break;
default: throw new ArgumentOutOfRangeException (nameof (orientation));
};
}
private void SetupForCollapsedPanel ()
{
View toRemove = panel1Collapsed ? Panel1 : Panel2;
View toFullSize = panel1Collapsed ? Panel2 : Panel1;
if (this.Subviews.Contains (splitterLine)) {
this.Subviews.Remove (splitterLine);
}
if (this.Subviews.Contains(toRemove)) {
this.Subviews.Remove (toRemove);
}
if(!this.Subviews.Contains(toFullSize)) {
this.Add (toFullSize);
}
toFullSize.X = 0;
toFullSize.Y = 0;
toFullSize.Width = Dim.Fill ();
toFullSize.Height = Dim.Fill ();
}
///
/// The left or top panel of the
/// (depending on ). Add panel contents
/// to this using .
///
public View Panel1 { get; } = new View ();
///
/// TODO: not implemented yet
///
public int Panel1MinSize { get; set; }
///
/// This determines if is collapsed.
///
public bool Panel1Collapsed {
get { return panel1Collapsed; }
set {
panel1Collapsed = value;
if (value && panel2Collapsed) {
panel2Collapsed = false;
}
Setup ();
}
}
///
/// The right or bottom panel of the
/// (depending on ). Add panel contents
/// to this using
///
public View Panel2 { get; } = new View ();
///
/// TODO: not implemented yet
///
public int Panel2MinSize { get; set; }
///
/// This determines if is collapsed.
///
public bool Panel2Collapsed {
get { return panel2Collapsed; }
set {
panel2Collapsed = value;
if (value && panel1Collapsed) {
panel1Collapsed = false;
}
Setup ();
}
}
public Orientation Orientation {
get { return orientation; }
set {
orientation = value;
Setup ();
}
}
public Pos SplitterDistance {
get { return splitterDistance; }
set {
splitterDistance = value;
Setup ();
}
}
}
}