Move panel splitting logic (SplitLeft/SplitRight) to main SplitContainer class

This commit is contained in:
tznind
2023-01-15 08:54:58 +00:00
parent ce6ffe324c
commit 8497dd7829
2 changed files with 108 additions and 39 deletions

View File

@@ -245,6 +245,81 @@ namespace Terminal.Gui {
}
}
/// <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.
/// </summary>
/// <remarks>After successful splitting, the returned container's <see cref="Panel1"/>
/// will contain the original content (if any) while <see cref="Panel2"/> will be empty and available
/// 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>
/// <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)
{
return TrySplit (
() => this.Panel1,
(n) => this.Panel1 = n,
out result);
}
/// <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.
/// </summary>
/// <remarks>After successful splitting, the returned container's <see cref="Panel1"/>
/// will contain the original content (if any) while <see cref="Panel2"/> will be empty and available
/// 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>
/// <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)
{
return TrySplit (
() => this.Panel2,
(n) => this.Panel2 = n,
out result);
}
private bool TrySplit(
Func<View> getter,
Action<SplitContainer> newSplitContainerSetter,
out SplitContainer result)
{
// Get the current panel contents (Panel1 or Panel2)
var toMove = getter();
if (toMove is SplitContainer existing) {
result = existing;
return false;
}
var newContainer = new SplitContainer {
Width = Dim.Fill (),
Height = Dim.Fill (),
};
// Replace current child contents
Remove (toMove);
Add (newContainer);
// Set Panel (1 or 2) to the new container
newSplitContainerSetter(newContainer);
// Set the original content into the first panel of the new container
newContainer.Add (toMove);
newContainer.Panel1 = toMove;
result = newContainer;
return true;
}
private List<SplitContainerLineView> GetAllChildSplitContainerLineViewRecursively (View v)
{
var lines = new List<SplitContainerLineView>();
@@ -372,6 +447,11 @@ namespace Terminal.Gui {
var availableSpace = Orientation == Orientation.Horizontal ? this.Bounds.Height : this.Bounds.Width;
// we probably haven't finished layout even if IsInitialized is true :(
if(availableSpace <= 0) {
return pos;
}
var idealPosition = pos.Anchor (availableSpace);
// bad position because not enough space for Panel1

View File

@@ -97,7 +97,7 @@ namespace UICatalog.Scenarios {
var root = CreateSplitContainer (1,startHorizontal ?
Terminal.Gui.Graphs.Orientation.Horizontal :
Terminal.Gui.Graphs.Orientation.Vertical, false);
Terminal.Gui.Graphs.Orientation.Vertical);
root.Panel1.Add (CreateTextView (1));
root.Panel2.Add (CreateTextView (2));
@@ -142,11 +142,11 @@ namespace UICatalog.Scenarios {
}
if (!(to.Panel1 is SplitContainer)) {
SplitLeft (to);
Split(to,true);
}
if (!(to.Panel2 is SplitContainer)) {
SplitRight (to);
Split(to,false);
}
if (to.Panel1 is SplitContainer && to.Panel2 is SplitContainer) {
@@ -156,47 +156,42 @@ namespace UICatalog.Scenarios {
}
}
private void SplitLeft(SplitContainer to)
private void Split(SplitContainer to, bool left)
{
if (panelsCreated == panelsToCreate) {
return;
}
SplitContainer newContainer;
if (left) {
to.TrySplitPanel1 (out newContainer);
}
else {
to.TrySplitPanel2 (out newContainer);
}
panelsCreated++;
// we can split Panel1
var tv = (TextView)to.Panel1.Subviews.Single ();
SetPanelTitles (newContainer, panelsCreated);
panelsCreated++;
var newContainer = CreateSplitContainer (panelsCreated, to.Orientation, true);
to.Remove (to.Panel1);
to.Add (newContainer);
to.Panel1 = newContainer;
newContainer.Panel1.Add (tv);
// Flip orientation
newContainer.Orientation = newContainer.Orientation == Orientation.Vertical ?
Orientation.Horizontal :
Orientation.Vertical;
newContainer.Panel2.Add (CreateTextView (panelsCreated));
}
private void SplitRight(SplitContainer to)
private void SetPanelTitles (SplitContainer container, int containerNumber)
{
if (panelsCreated == panelsToCreate) {
return;
}
// we can split Panel2
var tv = (TextView)to.Panel2.Subviews.Single ();
panelsCreated++;
var newContainer = CreateSplitContainer (panelsCreated, to.Orientation, true);
to.Remove (to.Panel2);
to.Add (newContainer);
to.Panel2 = newContainer;
newContainer.Panel2.Add (tv);
newContainer.Panel1.Add (CreateTextView (panelsCreated));
container.Panel1Title = cbTitles.Checked ? $"Panel {containerNumber}" : string.Empty;
container.Panel2Title = cbTitles.Checked ? $"Panel {containerNumber + 1}" : string.Empty;
}
private SplitContainer CreateSplitContainer (int titleNumber, Orientation orientation, bool flip)
private SplitContainer CreateSplitContainer (int titleNumber, Orientation orientation)
{
var toReturn = new SplitContainer {
Width = Dim.Fill (),
@@ -205,13 +200,7 @@ namespace UICatalog.Scenarios {
Orientation = orientation
};
if (flip) {
toReturn.Orientation = toReturn.Orientation == Orientation.Vertical ?
Orientation.Horizontal :
Orientation.Vertical;
}
toReturn.Panel1Title = cbTitles.Checked ? $"Panel {titleNumber}" : string.Empty;
toReturn.Panel2Title = cbTitles.Checked ? $"Panel {titleNumber+1}" : string.Empty;
SetPanelTitles (toReturn, titleNumber);
return toReturn;
}