Rename SplitContainer to SplitView

This commit is contained in:
tznind
2023-01-16 19:56:32 +00:00
parent 62b98dcceb
commit 8487422f25
4 changed files with 241 additions and 240 deletions

View File

@@ -8,19 +8,20 @@ namespace Terminal.Gui {
/// <summary>
/// A <see cref="View"/> consisting of a moveable bar that divides
/// the display area into 2 resizeable panels.
/// the display area into 2 resizeable views.
/// </summary>
public class SplitContainer : View {
public class SplitView : View
{
private SplitContainerLineView splitterLine;
SplitContainer parentSplitPanel;
SplitView parentSplitView;
/// TODO: Might be able to make Border virtual and override here
/// To make this more API friendly
/// <summary>
/// Use this field instead of Border to create an integrated
/// Border in which lines connect with subpanels and splitters
/// Border in which lines connect with subviews and splitters
/// seamlessly
/// </summary>
public BorderStyle IntegratedBorder {get;set;}
@@ -29,25 +30,25 @@ namespace Terminal.Gui {
/// The <see cref="View"/> showing in the left hand pane of a
/// <see cref="Orientation.Vertical"/> or top of an
/// <see cref="Orientation.Horizontal"/> pane. May be another
/// <see cref="SplitContainer"/> if further splitter subdivisions are
/// <see cref="SplitView"/> if further splitter subdivisions are
/// desired (e.g. to create a resizeable grid.
/// </summary>
public View Panel1 { get; private set; }
public View View1 { get; private set; }
public int Panel1MinSize { get; set; } = 1;
public ustring Panel1Title { get; set; } = string.Empty;
public int View1MinSize { get; set; } = 1;
public ustring View1Title { get; set; } = string.Empty;
/// <summary>
/// The <see cref="View"/> showing in the right hand pane of a
/// <see cref="Orientation.Vertical"/> or bottom of an
/// <see cref="Orientation.Horizontal"/> pane. May be another
/// <see cref="SplitContainer"/> if further splitter subdivisions are
/// <see cref="SplitView"/> if further splitter subdivisions are
/// desired (e.g. to create a resizeable grid.
/// </summary>
public View Panel2 { get; private set; }
public View View2 { get; private set; }
public int Panel2MinSize { get; set; } = 1;
public ustring Panel2Title { get; set; } = string.Empty;
public int View2MinSize { get; set; } = 1;
public ustring View2Title { get; set; } = string.Empty;
private Pos splitterDistance = Pos.Percent (50);
private Orientation orientation = Orientation.Vertical;
@@ -55,15 +56,15 @@ namespace Terminal.Gui {
/// <summary>
/// Creates a new instance of the SplitContainer class.
/// </summary>
public SplitContainer ()
public SplitView ()
{
splitterLine = new SplitContainerLineView (this);
Panel1 = new View () { Width = Dim.Fill (), Height = Dim.Fill() };
Panel2 = new View () { Width = Dim.Fill (), Height = Dim.Fill () };
View1 = new View () { Width = Dim.Fill (), Height = Dim.Fill() };
View2 = new View () { Width = Dim.Fill (), Height = Dim.Fill () };
this.Add (Panel1);
this.Add (View1);
this.Add (splitterLine);
this.Add (Panel2);
this.Add (View2);
CanFocus = true;
}
@@ -123,7 +124,7 @@ namespace Terminal.Gui {
/// <summary>
/// <para>Distance Horizontally or Vertically to the splitter line when
/// neither panel is collapsed.
/// neither view is collapsed.
/// </para>
/// <para>Only absolute values (e.g. 10) and percent values (i.e. <see cref="Pos.Percent(float)"/>)
/// are supported for this property.</para>
@@ -215,9 +216,9 @@ namespace Terminal.Gui {
// Draw Titles over Border
var screen = ViewToScreen (new Rect(0,0,bounds.Width,1));
if (Panel1.Visible && Panel1Title.Length > 0) {
Driver.SetAttribute (Panel1.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, Panel1.Frame.Width, 0), Panel1Title, 0, 0, 0, 0);
if (View1.Visible && View1Title.Length > 0) {
Driver.SetAttribute (View1.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, View1.Frame.Width, 0), View1Title, 0, 0, 0, 0);
}
if (splitterLine.Visible) {
@@ -229,47 +230,47 @@ namespace Terminal.Gui {
}
if (Orientation == Orientation.Horizontal) {
if (Panel2.Visible && Panel2Title?.Length > 0) {
if (View2.Visible && View2Title?.Length > 0) {
Driver.SetAttribute (Panel2.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, Panel2.Bounds.Width, 1), Panel2Title, 0, 0, 0, 0);
Driver.SetAttribute (View2.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, View2.Bounds.Width, 1), View2Title, 0, 0, 0, 0);
}
} else {
if (Panel2.Visible && Panel2Title?.Length > 0) {
Driver.SetAttribute (Panel2.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, Panel2.Bounds.Width, 1), Panel2Title, 0, 0, 0, 0);
if (View2.Visible && View2Title?.Length > 0) {
Driver.SetAttribute (View2.HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal);
Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, View2.Bounds.Width, 1), View2Title, 0, 0, 0, 0);
}
}
}
/// <summary>
/// Converts <see cref="Panel1"/> from a regular <see cref="View"/>
/// container to a new nested <see cref="SplitContainer"/>. If <see cref="Panel1"/>
/// is already a <see cref="SplitContainer"/> then returns false.
/// Converts <see cref="View1"/> from a regular <see cref="View"/>
/// container to a new nested <see cref="SplitView"/>. If <see cref="View1"/>
/// is already a <see cref="SplitView"/> then returns false.
/// </summary>
/// <remarks>After successful splitting, the returned container's <see cref="Panel1"/>
/// will contain the original content and <see cref="Panel1Title"/> (if any) while
/// <see cref="Panel2"/> will be empty and available for adding to.
/// <remarks>After successful splitting, the returned container's <see cref="View1"/>
/// will contain the original content and <see cref="View1Title"/> (if any) while
/// <see cref="View2"/> will be empty and available for adding to.
/// for adding to.</remarks>
/// <param name="result">The new <see cref="SplitContainer"/> now showing in
/// <see cref="Panel1"/> or the existing one if it was already been converted before.</param>
/// <param name="result">The new <see cref="SplitView"/> now showing in
/// <see cref="View1"/> or the existing one if it was already been converted before.</param>
/// <returns><see langword="true"/> if a <see cref="View"/> was converted to a new nested
/// <see cref="SplitContainer"/>. <see langword="false"/> if it was already a nested
/// <see cref="SplitContainer"/></returns>
public bool TrySplitPanel1(out SplitContainer result)
/// <see cref="SplitView"/>. <see langword="false"/> if it was already a nested
/// <see cref="SplitView"/></returns>
public bool TrySplitView1(out SplitView result)
{
// when splitting a panel into 2 sub panels we will need to migrate
// when splitting a view into 2 sub views we will need to migrate
// the title too
var title = Panel1Title;
var title = View1Title;
bool returnValue = TrySplit (
this.Panel1,
this.View1,
(newSplitContainer) => {
this.Panel1 = newSplitContainer;
this.View1 = newSplitContainer;
// Move title to new container
Panel1Title = string.Empty;
newSplitContainer.Panel1Title = title;
View1Title = string.Empty;
newSplitContainer.View1Title = title;
},
out result);
@@ -277,36 +278,36 @@ namespace Terminal.Gui {
}
/// <summary>
/// Converts <see cref="Panel2"/> from a regular <see cref="View"/>
/// container to a new nested <see cref="SplitContainer"/>. If <see cref="Panel2"/>
/// is already a <see cref="SplitContainer"/> then returns false.
/// Converts <see cref="View2"/> from a regular <see cref="View"/>
/// container to a new nested <see cref="SplitView"/>. If <see cref="View2"/>
/// is already a <see cref="SplitView"/> then returns false.
/// </summary>
/// <remarks>After successful splitting, the returned container's <see cref="Panel1"/>
/// will contain the original content and <see cref="Panel2Title"/> (if any) while
/// <see cref="Panel2"/> will be empty and available for adding to.
/// <remarks>After successful splitting, the returned container's <see cref="View1"/>
/// will contain the original content and <see cref="View2Title"/> (if any) while
/// <see cref="View2"/> will be empty and available for adding to.
/// for adding to.</remarks>
/// <param name="result">The new <see cref="SplitContainer"/> now showing in
/// <see cref="Panel2"/> or the existing one if it was already been converted before.</param>
/// <param name="result">The new <see cref="SplitView"/> now showing in
/// <see cref="View2"/> or the existing one if it was already been converted before.</param>
/// <returns><see langword="true"/> if a <see cref="View"/> was converted to a new nested
/// <see cref="SplitContainer"/>. <see langword="false"/> if it was already a nested
/// <see cref="SplitContainer"/></returns>
public bool TrySplitPanel2 (out SplitContainer result)
/// <see cref="SplitView"/>. <see langword="false"/> if it was already a nested
/// <see cref="SplitView"/></returns>
public bool TrySplitView2 (out SplitView result)
{
// when splitting a panel into 2 sub panels we will need to migrate
// when splitting a view into 2 sub views we will need to migrate
// the title too
var title = Panel2Title;
var title = View2Title;
bool returnValue = TrySplit (
this.Panel2,
this.View2,
(newSplitContainer) => {
this.Panel2 = newSplitContainer;
this.View2 = newSplitContainer;
// Move title to new container
Panel2Title = string.Empty;
View2Title = string.Empty;
// Content always goes into Panel1 of the new container
// Content always goes into View1 of the new container
// so that is where the title goes too
newSplitContainer.Panel1Title = title;
newSplitContainer.View1Title = title;
},
out result);
@@ -314,32 +315,32 @@ namespace Terminal.Gui {
}
private bool TrySplit(
View toMove,
Action<SplitContainer> newSplitContainerSetter,
out SplitContainer result)
Action<SplitView> newSplitContainerSetter,
out SplitView result)
{
if (toMove is SplitContainer existing) {
if (toMove is SplitView existing) {
result = existing;
return false;
}
var newContainer = new SplitContainer {
var newContainer = new SplitView {
Width = Dim.Fill (),
Height = Dim.Fill (),
parentSplitPanel = this,
parentSplitView = this,
};
// Take everything out of the Panel we are moving
// Take everything out of the View we are moving
var childViews = toMove.Subviews.ToArray();
toMove.RemoveAll ();
// Remove the panel itself and replace it with the new SplitContainer
// Remove the view itself and replace it with the new SplitContainer
Remove (toMove);
Add (newContainer);
newSplitContainerSetter(newContainer);
// Add the original content into the first panel of the new container
// Add the original content into the first view of the new container
foreach(var childView in childViews) {
newContainer.Panel1.Add (childView);
newContainer.View1.Add (childView);
}
result = newContainer;
@@ -370,14 +371,14 @@ namespace Terminal.Gui {
private bool IsRootSplitContainer ()
{
// TODO: don't want to layout subviews since the parent recursively lays them all out
return parentSplitPanel == null;
return parentSplitView == null;
}
private SplitContainer GetRootSplitContainer ()
private SplitView GetRootSplitContainer ()
{
SplitContainer root = this;
SplitView root = this;
while (root.parentSplitPanel != null) {
root = root.parentSplitPanel;
while (root.parentSplitView != null) {
root = root.parentSplitView;
}
return root;
@@ -385,12 +386,12 @@ namespace Terminal.Gui {
private void Setup (Rect bounds)
{
splitterLine.Orientation = Orientation;
// splitterLine.Text = Panel2.Title;
// splitterLine.Text = View2.Title;
// TODO: Recursion
if (!Panel1.Visible || !Panel2.Visible) {
View toFullSize = !Panel1.Visible ? Panel2 : Panel1;
if (!View1.Visible || !View2.Visible) {
View toFullSize = !View1.Visible ? View2 : View1;
splitterLine.Visible = false;
@@ -403,8 +404,8 @@ namespace Terminal.Gui {
splitterDistance = BoundByMinimumSizes (splitterDistance);
Panel1.X = bounds.X;
Panel1.Y = bounds.Y;
View1.X = bounds.X;
View1.Y = bounds.Y;
switch (Orientation) {
case Orientation.Horizontal:
@@ -414,14 +415,14 @@ namespace Terminal.Gui {
splitterLine.Height = 1;
splitterLine.LineRune = Driver.HLine;
Panel1.Width = Dim.Fill (HasBorder()? 1:0);
Panel1.Height = new Dim.DimFunc (() =>
View1.Width = Dim.Fill (HasBorder()? 1:0);
View1.Height = new Dim.DimFunc (() =>
splitterDistance.Anchor (bounds.Height));
Panel2.Y = Pos.Bottom (splitterLine);
Panel2.X = bounds.X;
Panel2.Width = bounds.Width;
Panel2.Height = Dim.Fill(HasBorder () ? 1 : 0);
View2.Y = Pos.Bottom (splitterLine);
View2.X = bounds.X;
View2.Width = bounds.Width;
View2.Height = Dim.Fill(HasBorder () ? 1 : 0);
break;
case Orientation.Vertical:
@@ -431,14 +432,14 @@ namespace Terminal.Gui {
splitterLine.Height = Dim.Fill ();
splitterLine.LineRune = Driver.VLine;
Panel1.Height = Dim.Fill();
Panel1.Width = new Dim.DimFunc (() =>
View1.Height = Dim.Fill();
View1.Width = new Dim.DimFunc (() =>
splitterDistance.Anchor (bounds.Width));
Panel2.X = Pos.Right (splitterLine);
Panel2.Y = bounds.Y;
Panel2.Height = bounds.Height;
Panel2.Width = Dim.Fill(HasBorder()? 1:0);
View2.X = Pos.Right (splitterLine);
View2.Y = bounds.Y;
View2.Height = bounds.Height;
View2.Width = Dim.Fill(HasBorder()? 1:0);
break;
default: throw new ArgumentOutOfRangeException (nameof (orientation));
@@ -449,7 +450,7 @@ namespace Terminal.Gui {
/// <summary>
/// Considers <paramref name="pos"/> as a candidate for <see cref="splitterDistance"/>
/// then either returns (if valid) or returns adjusted if invalid with respect to the
/// <see cref="SplitterPanel.MinSize"/> of the panels.
/// <see cref="SplitterView.MinSize"/> of the views.
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
@@ -457,21 +458,21 @@ namespace Terminal.Gui {
{
// if we are not yet initialized then we don't know
// how big we are and therefore cannot sensibly calculate
// how big the panels will be with a given SplitterDistance
// how big the views will be with a given SplitterDistance
if (!IsInitialized) {
return pos;
}
var panel1MinSize = Panel1MinSize;
var panel2MinSize = Panel2MinSize;
var view1MinSize = View1MinSize;
var view2MinSize = View2MinSize;
// if there is a border then there is less space
// for the panels so we need to make size restrictions
// for the views so we need to make size restrictions
// tighter.
if(HasBorder()) {
panel1MinSize++;
panel2MinSize++;
view1MinSize++;
view2MinSize++;
}
var availableSpace = Orientation == Orientation.Horizontal ? this.Bounds.Height : this.Bounds.Width;
@@ -483,33 +484,33 @@ namespace Terminal.Gui {
var idealPosition = pos.Anchor (availableSpace);
// bad position because not enough space for Panel1
if (idealPosition < panel1MinSize) {
// bad position because not enough space for View1
if (idealPosition < view1MinSize) {
// TODO: we should preserve Absolute/Percent status here not just force it to absolute
return (Pos)Math.Min (panel1MinSize, availableSpace);
return (Pos)Math.Min (view1MinSize, availableSpace);
}
// bad position because not enough space for Panel2
if (availableSpace - idealPosition <= panel2MinSize) {
// bad position because not enough space for View2
if (availableSpace - idealPosition <= view2MinSize) {
// TODO: we should preserve Absolute/Percent status here not just force it to absolute
// +1 is to allow space for the splitter
return (Pos)Math.Max (availableSpace - (panel2MinSize + 1), 0);
return (Pos)Math.Max (availableSpace - (view2MinSize + 1), 0);
}
// this splitter position is fine, there is enough space for everyone
return pos;
}
private class SplitContainerLineView : LineView {
public SplitContainer Parent { get; private set; }
public SplitView Parent { get; private set; }
Point? dragPosition;
Pos dragOrignalPos;
public Point? moveRuneRenderLocation;
public SplitContainerLineView (SplitContainer parent)
public SplitContainerLineView (SplitView parent)
{
CanFocus = true;
TabStop = true;
@@ -681,7 +682,7 @@ namespace Terminal.Gui {
/// <summary>
/// <para>
/// Moves <see cref="parent"/> <see cref="SplitContainer.SplitterDistance"/> to
/// Moves <see cref="parent"/> <see cref="SplitView.SplitterDistance"/> to
/// <see cref="Pos"/> <paramref name="newValue"/> preserving <see cref="Pos"/> format
/// (absolute / relative) that <paramref name="oldValue"/> had.
/// </para>
@@ -729,7 +730,7 @@ namespace Terminal.Gui {
}
private bool HasAnyTitles()
{
return Panel1Title.Length > 0 || Panel2Title.Length > 0;
return View1Title.Length > 0 || View2Title.Length > 0;
}
@@ -747,7 +748,7 @@ namespace Terminal.Gui {
{
var screenRect = currentLine.ViewToScreen (
new Rect(0,0,currentLine.Frame.Width,currentLine.Frame.Height));
Driver.DrawWindowTitle (screenRect, currentLine.Parent.Panel2Title, 0, 0, 0, 0);
Driver.DrawWindowTitle (screenRect, currentLine.Parent.View2Title, 0, 0, 0, 0);
}
}
}
@@ -763,21 +764,21 @@ namespace Terminal.Gui {
/// </summary>
/// <param name="splitContainer"></param>
/// <param name="splitterDistance"></param>
public SplitterEventArgs (SplitContainer splitContainer, Pos splitterDistance)
public SplitterEventArgs (SplitView splitContainer, Pos splitterDistance)
{
SplitterDistance = splitterDistance;
SplitContainer = splitContainer;
}
/// <summary>
/// New position of the <see cref="SplitContainer.SplitterDistance"/>
/// New position of the <see cref="SplitView.SplitterDistance"/>
/// </summary>
public Pos SplitterDistance { get; }
/// <summary>
/// Container (sender) of the event.
/// </summary>
public SplitContainer SplitContainer { get; }
public SplitView SplitContainer { get; }
}
/// <summary>

View File

@@ -3,10 +3,10 @@ using Terminal.Gui;
using Terminal.Gui.Graphs;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Split Container Nesting", Description: "Nest SplitContainers")]
[ScenarioMetadata (Name: "Split View Nesting", Description: "Nest SplitViews")]
[ScenarioCategory ("Controls")]
[ScenarioCategory ("LineView")]
public class SplitContainerNesting : Scenario {
public class SplitViewNesting : Scenario {
private View workArea;
private TextField textField;
@@ -16,8 +16,8 @@ namespace UICatalog.Scenarios {
private CheckBox cbUseLabels;
bool loaded = false;
int panelsCreated;
int panelsToCreate;
int viewsCreated;
int viewsToCreate;
/// <summary>
/// Setup the scenario.
@@ -28,35 +28,35 @@ namespace UICatalog.Scenarios {
Win.Title = this.GetName ();
Win.Y = 1;
var lblPanels = new Label ("Number Of Panels:");
var lblViews = new Label ("Number Of Views:");
textField = new TextField {
X = Pos.Right (lblPanels),
X = Pos.Right (lblViews),
Width = 10,
Text = "2",
};
textField.TextChanged += (s) => SetupSplitContainer ();
textField.TextChanged += (s) => SetupSplitView ();
cbHorizontal = new CheckBox ("Horizontal") {
X = Pos.Right (textField) + 1
};
cbHorizontal.Toggled += (s) => SetupSplitContainer ();
cbHorizontal.Toggled += (s) => SetupSplitView ();
cbBorder = new CheckBox ("Border") {
X = Pos.Right (cbHorizontal) + 1
};
cbBorder.Toggled += (s) => SetupSplitContainer ();
cbBorder.Toggled += (s) => SetupSplitView ();
cbTitles = new CheckBox ("Titles") {
X = Pos.Right (cbBorder) + 1
};
cbTitles.Toggled += (s) => SetupSplitContainer ();
cbTitles.Toggled += (s) => SetupSplitView ();
cbUseLabels = new CheckBox ("Use Labels") {
X = Pos.Right (cbTitles) + 1
};
cbUseLabels.Toggled += (s) => SetupSplitContainer ();
cbUseLabels.Toggled += (s) => SetupSplitView ();
workArea = new View {
X = 0,
@@ -70,7 +70,7 @@ namespace UICatalog.Scenarios {
new MenuItem ("_Quit", "", () => Quit()),
}) });
Win.Add (lblPanels);
Win.Add (lblViews);
Win.Add (textField);
Win.Add (cbHorizontal);
Win.Add (cbBorder);
@@ -78,16 +78,16 @@ namespace UICatalog.Scenarios {
Win.Add (cbUseLabels);
Win.Add (workArea);
SetupSplitContainer ();
SetupSplitView ();
Application.Top.Add (menu);
Win.Loaded += () => loaded = true;
}
private void SetupSplitContainer ()
private void SetupSplitView ()
{
int numberOfPanels = GetNumberOfPanels ();
int numberOfViews = GetNumberOfViews ();
bool titles = cbTitles.Checked;
bool border = cbBorder.Checked;
@@ -95,16 +95,16 @@ namespace UICatalog.Scenarios {
workArea.RemoveAll ();
if (numberOfPanels <= 0) {
if (numberOfViews <= 0) {
return;
}
var root = CreateSplitContainer (1,startHorizontal ?
var root = CreateSplitView (1,startHorizontal ?
Terminal.Gui.Graphs.Orientation.Horizontal :
Terminal.Gui.Graphs.Orientation.Vertical);
root.Panel1.Add (CreateContentControl (1));
root.Panel2.Add (CreateContentControl (2));
root.View1.Add (CreateContentControl (1));
root.View2.Add (CreateContentControl (2));
root.IntegratedBorder = border ? BorderStyle.Rounded : BorderStyle.None;
@@ -112,15 +112,15 @@ namespace UICatalog.Scenarios {
workArea.Add (root);
if (numberOfPanels == 1) {
root.Panel2.Visible = false;
if (numberOfViews == 1) {
root.View2.Visible = false;
}
if (numberOfPanels > 2) {
if (numberOfViews > 2) {
panelsCreated = 2;
panelsToCreate = numberOfPanels;
AddMorePanels (root);
viewsCreated = 2;
viewsToCreate = numberOfViews;
AddMoreViews (root);
}
if (loaded) {
@@ -152,81 +152,81 @@ namespace UICatalog.Scenarios {
Height = Dim.Fill(),
Text = number.ToString ().Repeat (1000),
AllowsTab = false,
//WordWrap = true, // TODO: This is very slow (like 10s to render with 45 panels)
//WordWrap = true, // TODO: This is very slow (like 10s to render with 45 views)
};
}
private void AddMorePanels (SplitContainer to)
private void AddMoreViews (SplitView to)
{
if (panelsCreated == panelsToCreate) {
if (viewsCreated == viewsToCreate) {
return;
}
if (!(to.Panel1 is SplitContainer)) {
if (!(to.View1 is SplitView)) {
Split(to,true);
}
if (!(to.Panel2 is SplitContainer)) {
if (!(to.View2 is SplitView)) {
Split(to,false);
}
if (to.Panel1 is SplitContainer && to.Panel2 is SplitContainer) {
if (to.View1 is SplitView && to.View2 is SplitView) {
AddMorePanels ((SplitContainer)to.Panel1);
AddMorePanels ((SplitContainer)to.Panel2);
AddMoreViews ((SplitView)to.View1);
AddMoreViews ((SplitView)to.View2);
}
}
private void Split(SplitContainer to, bool left)
private void Split(SplitView to, bool left)
{
if (panelsCreated == panelsToCreate) {
if (viewsCreated == viewsToCreate) {
return;
}
SplitContainer newContainer;
SplitView newView;
if (left) {
to.TrySplitPanel1 (out newContainer);
to.TrySplitView1 (out newView);
}
else {
to.TrySplitPanel2 (out newContainer);
to.TrySplitView2 (out newView);
}
panelsCreated++;
viewsCreated++;
// During splitting the old Title will have been migrated to Panel1 so we only need
// to set the Title on Panel2 (the one that gets our new TextView)
newContainer.Panel2Title = cbTitles.Checked ? $"Panel {panelsCreated}" : string.Empty;
// During splitting the old Title will have been migrated to View1 so we only need
// to set the Title on View2 (the one that gets our new TextView)
newView.View2Title = cbTitles.Checked ? $"View {viewsCreated}" : string.Empty;
// Flip orientation
newContainer.Orientation = to.Orientation == Orientation.Vertical ?
newView.Orientation = to.Orientation == Orientation.Vertical ?
Orientation.Horizontal :
Orientation.Vertical;
newContainer.Panel2.Add (CreateContentControl(panelsCreated));
newView.View2.Add (CreateContentControl(viewsCreated));
}
private SplitContainer CreateSplitContainer (int titleNumber, Orientation orientation)
private SplitView CreateSplitView (int titleNumber, Orientation orientation)
{
var toReturn = new SplitContainer {
var toReturn = new SplitView {
Width = Dim.Fill (),
Height = Dim.Fill (),
// flip the orientation
Orientation = orientation
};
toReturn.Panel1Title = cbTitles.Checked ? $"Panel {titleNumber}" : string.Empty;
toReturn.Panel2Title = cbTitles.Checked ? $"Panel {titleNumber + 1}" : string.Empty;
toReturn.View1Title = cbTitles.Checked ? $"View {titleNumber}" : string.Empty;
toReturn.View2Title = cbTitles.Checked ? $"View {titleNumber + 1}" : string.Empty;
return toReturn;
}
private int GetNumberOfPanels ()
private int GetNumberOfViews ()
{
if (int.TryParse (textField.Text.ToString (), out var panels) && panels >= 0) {
if (int.TryParse (textField.Text.ToString (), out var views) && views >= 0) {
return panels;
return views;
} else {
return 0;
}

View File

@@ -151,7 +151,7 @@ namespace UICatalog {
public MenuItem miIsMouseDisabled;
public MenuItem miHeightAsBuffer;
public SplitContainer ContentPane;
public SplitView ContentPane;
public ListView CategoryListView;
public ListView ScenarioListView;
@@ -207,7 +207,7 @@ namespace UICatalog {
OS
};
ContentPane = new SplitContainer () {
ContentPane = new SplitView () {
X = 0,
Y = 1, // for menu
Width = Dim.Fill (),
@@ -232,8 +232,8 @@ namespace UICatalog {
};
CategoryListView.SelectedItemChanged += CategoryListView_SelectedChanged;
ContentPane.Panel1Title = "Categories";
ContentPane.Panel1.Add (CategoryListView);
ContentPane.View1Title = "Categories";
ContentPane.View1.Add (CategoryListView);
ScenarioListView = new ListView () {
X = 0,
@@ -246,8 +246,8 @@ namespace UICatalog {
ScenarioListView.OpenSelectedItem += ScenarioListView_OpenSelectedItem;
ContentPane.Panel2Title = "Scenarios";
ContentPane.Panel2.Add (ScenarioListView);
ContentPane.View2Title = "Scenarios";
ContentPane.View2.Add (ScenarioListView);
KeyDown += KeyDownHandler;
Add (MenuBar);

View File

@@ -5,20 +5,20 @@ using Xunit;
using Xunit.Abstractions;
namespace UnitTests {
public class SplitContainerTests {
public class SplitViewTests {
readonly ITestOutputHelper output;
public SplitContainerTests (ITestOutputHelper output)
public SplitViewTests (ITestOutputHelper output)
{
this.output = output;
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical ()
public void TestSplitView_Vertical ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
splitContainer.Redraw (splitContainer.Bounds);
string looksLike =
@@ -36,9 +36,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_WithBorder ()
public void TestSplitView_Vertical_WithBorder ()
{
var splitContainer = Get11By3SplitContainer (out var line, true);
var splitContainer = Get11By3SplitView (out var line, true);
splitContainer.Redraw (splitContainer.Bounds);
string looksLike =
@@ -56,9 +56,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Focused ()
public void TestSplitView_Vertical_Focused ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
SetInputFocusLine (splitContainer);
splitContainer.Redraw (splitContainer.Bounds);
@@ -96,9 +96,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Focused_WithBorder ()
public void TestSplitView_Vertical_Focused_WithBorder ()
{
var splitContainer = Get11By3SplitContainer (out var line, true);
var splitContainer = Get11By3SplitView (out var line, true);
SetInputFocusLine (splitContainer);
splitContainer.Redraw (splitContainer.Bounds);
@@ -137,9 +137,9 @@ namespace UnitTests {
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Focused_50PercentSplit ()
public void TestSplitView_Vertical_Focused_50PercentSplit ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
SetInputFocusLine (splitContainer);
splitContainer.SplitterDistance = Pos.Percent (50);
Assert.IsType<Pos.PosFactor> (splitContainer.SplitterDistance);
@@ -183,9 +183,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Horizontal ()
public void TestSplitView_Horizontal ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
splitContainer.Redraw (splitContainer.Bounds);
@@ -205,11 +205,11 @@ namespace UnitTests {
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Panel1MinSize_Absolute ()
public void TestSplitView_Vertical_View1MinSize_Absolute ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
SetInputFocusLine (splitContainer);
splitContainer.Panel1MinSize = 6;
splitContainer.View1MinSize = 6;
// distance is too small (below 6)
splitContainer.SplitterDistance = 2;
@@ -250,11 +250,11 @@ namespace UnitTests {
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Panel1MinSize_Absolute_WithBorder ()
public void TestSplitView_Vertical_View1MinSize_Absolute_WithBorder ()
{
var splitContainer = Get11By3SplitContainer (out var line,true);
var splitContainer = Get11By3SplitView (out var line,true);
SetInputFocusLine (splitContainer);
splitContainer.Panel1MinSize = 5;
splitContainer.View1MinSize = 5;
// distance is too small (below 5)
splitContainer.SplitterDistance = 2;
@@ -294,13 +294,13 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Panel2MinSize_Absolute ()
public void TestSplitView_Vertical_View2MinSize_Absolute ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
SetInputFocusLine (splitContainer);
splitContainer.Panel2MinSize = 6;
splitContainer.View2MinSize = 6;
// distance leaves too little space for panel2 (less than 6 would remain)
// distance leaves too little space for view2 (less than 6 would remain)
splitContainer.SplitterDistance = 8;
// Should bound the value to the minimum distance
@@ -338,13 +338,13 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Vertical_Panel2MinSize_Absolute_WithBorder ()
public void TestSplitView_Vertical_View2MinSize_Absolute_WithBorder ()
{
var splitContainer = Get11By3SplitContainer (out var line, true);
var splitContainer = Get11By3SplitView (out var line, true);
SetInputFocusLine (splitContainer);
splitContainer.Panel2MinSize = 5;
splitContainer.View2MinSize = 5;
// distance leaves too little space for panel2 (less than 5 would remain)
// distance leaves too little space for view2 (less than 5 would remain)
splitContainer.SplitterDistance = 8;
// Should bound the value to the minimum distance
@@ -382,9 +382,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_Horizontal_Focused ()
public void TestSplitView_Horizontal_Focused ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
SetInputFocusLine (splitContainer);
@@ -422,15 +422,15 @@ namespace UnitTests {
[Fact, AutoInitShutdown]
public void TestSplitContainer_Horizontal_Panel1MinSize_Absolute ()
public void TestSplitView_Horizontal_View1MinSize_Absolute ()
{
var splitContainer = Get11By3SplitContainer (out var line);
var splitContainer = Get11By3SplitView (out var line);
splitContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
SetInputFocusLine (splitContainer);
splitContainer.Panel1MinSize = 1;
splitContainer.View1MinSize = 1;
// 0 should not be allowed because it brings us below minimum size of Panel1
// 0 should not be allowed because it brings us below minimum size of View1
splitContainer.SplitterDistance = 0;
Assert.Equal ((Pos)1, splitContainer.SplitterDistance);
@@ -453,7 +453,7 @@ namespace UnitTests {
";
TestHelpers.AssertDriverContentsAre (looksLike, output);
// And up 2 (only 1 is allowed because of minimum size of 1 on panel1)
// And up 2 (only 1 is allowed because of minimum size of 1 on view1)
line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
splitContainer.Redraw (splitContainer.Bounds);
@@ -466,9 +466,9 @@ namespace UnitTests {
}
[Fact, AutoInitShutdown]
public void TestSplitContainer_CannotSetSplitterPosToFuncEtc ()
public void TestSplitView_CannotSetSplitterPosToFuncEtc ()
{
var splitContainer = Get11By3SplitContainer ();
var splitContainer = Get11By3SplitView ();
var ex = Assert.Throws<ArgumentException> (() => splitContainer.SplitterDistance = Pos.Right (splitContainer));
Assert.Equal ("Only Percent and Absolute values are supported for SplitterDistance property. Passed value was PosCombine", ex.Message);
@@ -488,26 +488,26 @@ namespace UnitTests {
var splitContainer = GetNestedContainer2Left1Right (false);
Assert.Equal (20,splitContainer.Frame.Width);
Assert.Equal (10, splitContainer.Panel1.Frame.Width);
Assert.Equal (9, splitContainer.Panel2.Frame.Width);
Assert.Equal (10, splitContainer.View1.Frame.Width);
Assert.Equal (9, splitContainer.View2.Frame.Width);
Assert.IsType<SplitContainer> (splitContainer.Panel1);
var left = (SplitContainer)splitContainer.Panel1;
Assert.IsType<SplitView> (splitContainer.View1);
var left = (SplitView)splitContainer.View1;
Assert.Same (left.SuperView, splitContainer);
Assert.Equal (10, left.Panel1.Frame.Width);
Assert.Equal (5, left.Panel1.Frame.Height);
Assert.Equal (10, left.Panel2.Frame.Width);
Assert.Equal (4, left.Panel2.Frame.Height);
Assert.Equal (10, left.View1.Frame.Width);
Assert.Equal (5, left.View1.Frame.Height);
Assert.Equal (10, left.View2.Frame.Width);
Assert.Equal (4, left.View2.Frame.Height);
Assert.Equal(2, left.Panel1.Subviews.Count);
Assert.IsType<Label> (left.Panel1.Subviews [0]);
Assert.IsType<Label> (left.Panel1.Subviews [1]);
var onesTop = (Label)left.Panel1.Subviews [0];
var onesBottom = (Label)left.Panel1.Subviews [1];
Assert.Equal(2, left.View1.Subviews.Count);
Assert.IsType<Label> (left.View1.Subviews [0]);
Assert.IsType<Label> (left.View1.Subviews [1]);
var onesTop = (Label)left.View1.Subviews [0];
var onesBottom = (Label)left.View1.Subviews [1];
Assert.Same (left.Panel1, onesTop.SuperView);
Assert.Same (left.Panel1, onesBottom.SuperView);
Assert.Same (left.View1, onesTop.SuperView);
Assert.Same (left.View1, onesBottom.SuperView);
Assert.Equal (10, onesTop.Frame.Width);
Assert.Equal (10, onesBottom.Frame.Width);
@@ -538,10 +538,10 @@ namespace UnitTests {
/// </summary>
/// <param name="withBorder"></param>
/// <returns></returns>
private SplitContainer GetNestedContainer2Left1Right(bool withBorder)
private SplitView GetNestedContainer2Left1Right(bool withBorder)
{
var container = GetSplitContainer (20, 10,withBorder);
Assert.True (container.TrySplitPanel1 (out var newContainer));
var container = GetSplitView (20, 10,withBorder);
Assert.True (container.TrySplitView1 (out var newContainer));
newContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
newContainer.ColorScheme = new ColorScheme ();
@@ -551,45 +551,45 @@ namespace UnitTests {
return container;
}
private LineView GetLine (SplitContainer splitContainer)
private LineView GetLine (SplitView splitContainer)
{
return splitContainer.Subviews.OfType<LineView> ().Single ();
}
private void SetInputFocusLine (SplitContainer splitContainer)
private void SetInputFocusLine (SplitView splitContainer)
{
var line = GetLine (splitContainer);
line.SetFocus ();
Assert.True (line.HasFocus);
}
private SplitContainer Get11By3SplitContainer(out LineView line, bool withBorder = false)
private SplitView Get11By3SplitView(out LineView line, bool withBorder = false)
{
var split = Get11By3SplitContainer (withBorder);
var split = Get11By3SplitView (withBorder);
line = GetLine (split);
return split;
}
private SplitContainer Get11By3SplitContainer (bool withBorder = false)
private SplitView Get11By3SplitView (bool withBorder = false)
{
return GetSplitContainer (11, 3, withBorder);
return GetSplitView (11, 3, withBorder);
}
private SplitContainer GetSplitContainer (int width, int height, bool withBorder = false)
private SplitView GetSplitView (int width, int height, bool withBorder = false)
{
var container = new SplitContainer () {
var container = new SplitView () {
Width = width,
Height = height,
};
container.IntegratedBorder = withBorder ? BorderStyle.Single : BorderStyle.None;
container.Panel1.Add (new Label (new string ('1', 100)) { Width = Dim.Fill(), Height = 1, AutoSize = false});
container.Panel1.Add (new Label (new string ('1', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
container.Panel2.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false });
container.Panel2.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
container.View1.Add (new Label (new string ('1', 100)) { Width = Dim.Fill(), Height = 1, AutoSize = false});
container.View1.Add (new Label (new string ('1', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
container.View2.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false });
container.View2.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
container.Panel1MinSize = 0;
container.Panel2MinSize = 0;
container.View1MinSize = 0;
container.View2MinSize = 0;
Application.Top.Add (container);
container.ColorScheme = new ColorScheme ();