diff --git a/Examples/UICatalog/Scenarios/Notepad.cs b/Examples/UICatalog/Scenarios/Notepad.cs
index c827ca59f9..0d9dd5034e 100644
--- a/Examples/UICatalog/Scenarios/Notepad.cs
+++ b/Examples/UICatalog/Scenarios/Notepad.cs
@@ -59,12 +59,13 @@ public override void Main ()
_tabView.Style.ShowBorder = true;
_tabView.ApplyStyleChanges ();
- // Start with only a single view but support splitting to show side by side
- var split = new TileView (1) { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill (1) };
- split.Tiles.ElementAt (0).ContentView.Add (_tabView);
- split.LineStyle = LineStyle.None;
-
- top.Add (split);
+ // Simple container for the tabview
+ top.Add (_tabView);
+ _tabView.X = 0;
+ _tabView.Y = 1;
+ _tabView.Width = Dim.Fill ();
+ _tabView.Height = Dim.Fill (1);
+
LenShortcut = new (Key.Empty, "Len: ", null);
var statusBar = new StatusBar (new [] {
@@ -198,40 +199,6 @@ private void Close (TabView tv, Tab tabToClose)
tv.RemoveTab (tab);
tab.View.Dispose ();
_focusedTabView = tv;
-
- if (tv.Tabs.Count == 0)
- {
- var split = (TileView)tv.SuperView.SuperView;
-
- // if it is the last TabView on screen don't drop it or we will
- // be unable to open new docs!
- if (split.IsRootTileView () && split.Tiles.Count == 1)
- {
- return;
- }
-
- int tileIndex = split.IndexOf (tv);
- split.RemoveTile (tileIndex);
-
- if (split.Tiles.Count == 0)
- {
- TileView parent = split.GetParentTileView ();
-
- if (parent == null)
- {
- return;
- }
-
- int idx = parent.IndexOf (split);
-
- if (idx == -1)
- {
- return;
- }
-
- parent.RemoveTile (idx);
- }
- }
}
private TabView CreateNewTabView ()
@@ -286,36 +253,7 @@ private void Open (FileInfo fileInfo, string tabName)
private void Quit () { Application.RequestStop (); }
- private void Split (int offset, Orientation orientation, TabView sender, OpenedFile tab)
- {
- var split = (TileView)sender.SuperView.SuperView;
- int tileIndex = split.IndexOf (sender);
-
- if (tileIndex == -1)
- {
- return;
- }
-
- if (orientation != split.Orientation)
- {
- split.TrySplitTile (tileIndex, 1, out split);
- split.Orientation = orientation;
- tileIndex = 0;
- }
-
- Tile newTile = split.InsertTile (tileIndex + offset);
- TabView newTabView = CreateNewTabView ();
- tab.CloneTo (newTabView);
- newTile.ContentView.Add (newTabView);
-
- newTabView.FocusDeepest (NavigationDirection.Forward, null);
- newTabView.AdvanceFocus (NavigationDirection.Forward, null);
- }
-
- private void SplitDown (TabView sender, OpenedFile tab) { Split (1, Orientation.Horizontal, sender, tab); }
- private void SplitLeft (TabView sender, OpenedFile tab) { Split (0, Orientation.Vertical, sender, tab); }
- private void SplitRight (TabView sender, OpenedFile tab) { Split (1, Orientation.Vertical, sender, tab); }
- private void SplitUp (TabView sender, OpenedFile tab) { Split (0, Orientation.Horizontal, sender, tab); }
+ // Split functionality removed - TileView is deprecated in favor of View.Arrangement
private void TabView_SelectedTabChanged (object sender, TabChangedEventArgs e)
{
@@ -346,12 +284,8 @@ private void TabView_TabClicked (object sender, TabMouseEventArgs e)
items =
[
new MenuItemv2 ("Save", "", () => Save (_focusedTabView, e.Tab)),
- new MenuItemv2 ("Close", "", () => Close (tv, e.Tab)),
- new Line (),
- new MenuItemv2 ("Split Up", "", () => SplitUp (tv, t)),
- new MenuItemv2 ("Split Down", "", () => SplitDown (tv, t)),
- new MenuItemv2 ("Split Right", "", () => SplitRight (tv, t)),
- new MenuItemv2 ("Split Left", "", () => SplitLeft (tv, t))
+ new MenuItemv2 ("Close", "", () => Close (tv, e.Tab))
+ // Split menu items removed - TileView is deprecated in favor of View.Arrangement
];
PopoverMenu? contextMenu = new (items);
diff --git a/Examples/UICatalog/Scenarios/TileViewNesting.cs b/Examples/UICatalog/Scenarios/TileViewNesting.cs
deleted file mode 100644
index 2d262bf497..0000000000
--- a/Examples/UICatalog/Scenarios/TileViewNesting.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-using System.Linq;
-
-namespace UICatalog.Scenarios;
-
-[ScenarioMetadata ("Tile View Nesting", "Demonstrates recursive nesting of TileViews")]
-[ScenarioCategory ("Controls")]
-[ScenarioCategory ("LineView")]
-public class TileViewNesting : Scenario
-{
- private CheckBox _cbBorder;
- private CheckBox _cbHorizontal;
- private CheckBox _cbTitles;
- private CheckBox _cbUseLabels;
- private TextField _textField;
- private int _viewsCreated;
- private int _viewsToCreate;
- private View _workArea;
-
- /// Setup the scenario.
- public override void Main ()
- {
- Application.Init ();
- // Scenario Windows.
- var win = new Window
- {
- Title = GetName (),
- Y = 1
- };
-
- var lblViews = new Label { Text = "Number Of Views:" };
- _textField = new() { X = Pos.Right (lblViews), Width = 10, Text = "2" };
-
- _textField.TextChanged += (s, e) => SetupTileView ();
-
- _cbHorizontal = new() { X = Pos.Right (_textField) + 1, Text = "Horizontal" };
- _cbHorizontal.CheckedStateChanged += (s, e) => SetupTileView ();
-
- _cbBorder = new() { X = Pos.Right (_cbHorizontal) + 1, Text = "Border" };
- _cbBorder.CheckedStateChanged += (s, e) => SetupTileView ();
-
- _cbTitles = new() { X = Pos.Right (_cbBorder) + 1, Text = "Titles" };
- _cbTitles.CheckedStateChanged += (s, e) => SetupTileView ();
-
- _cbUseLabels = new() { X = Pos.Right (_cbTitles) + 1, Text = "Use Labels" };
- _cbUseLabels.CheckedStateChanged += (s, e) => SetupTileView ();
-
- _workArea = new() { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () };
-
- var menu = new MenuBar
- {
- Menus =
- [
- new ("_File", new MenuItem [] { new ("_Quit", "", () => Quit ()) })
- ]
- };
-
- win.Add (lblViews);
- win.Add (_textField);
- win.Add (_cbHorizontal);
- win.Add (_cbBorder);
- win.Add (_cbTitles);
- win.Add (_cbUseLabels);
- win.Add (_workArea);
-
- SetupTileView ();
-
- var top = new Toplevel ();
- top.Add (menu);
- top.Add (win);
-
- Application.Run (top);
- top.Dispose ();
- Application.Shutdown ();
- }
-
- private void AddMoreViews (TileView to)
- {
- if (_viewsCreated == _viewsToCreate)
- {
- return;
- }
-
- if (!(to.Tiles.ElementAt (0).ContentView is TileView))
- {
- Split (to, true);
- }
-
- if (!(to.Tiles.ElementAt (1).ContentView is TileView))
- {
- Split (to, false);
- }
-
- if (to.Tiles.ElementAt (0).ContentView is TileView && to.Tiles.ElementAt (1).ContentView is TileView)
- {
- AddMoreViews ((TileView)to.Tiles.ElementAt (0).ContentView);
- AddMoreViews ((TileView)to.Tiles.ElementAt (1).ContentView);
- }
- }
-
- private View CreateContentControl (int number) { return _cbUseLabels.CheckedState == CheckState.Checked ? CreateLabelView (number) : CreateTextView (number); }
-
- private View CreateLabelView (int number)
- {
- return new Label
- {
- Width = Dim.Fill (),
- Height = 1,
-
- Text = number.ToString ().Repeat (1000),
- CanFocus = true
- };
- }
-
- private View CreateTextView (int number)
- {
- return new TextView
- {
- Width = Dim.Fill (), Height = Dim.Fill (), Text = number.ToString ().Repeat (1000), AllowsTab = false
-
- //WordWrap = true, // TODO: This is very slow (like 10s to render with 45 views)
- };
- }
-
- private TileView CreateTileView (int titleNumber, Orientation orientation)
- {
- var toReturn = new TileView
- {
- Width = Dim.Fill (),
- Height = Dim.Fill (),
-
- // flip the orientation
- Orientation = orientation
- };
-
- toReturn.Tiles.ElementAt (0).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {titleNumber}" : string.Empty;
- toReturn.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {titleNumber + 1}" : string.Empty;
-
- return toReturn;
- }
-
- private int GetNumberOfViews ()
- {
- if (int.TryParse (_textField.Text, out int views) && views >= 0)
- {
- return views;
- }
-
- return 0;
- }
-
- private void Quit () { Application.RequestStop (); }
-
- private void SetupTileView ()
- {
- int numberOfViews = GetNumberOfViews ();
-
- CheckState titles = _cbTitles.CheckedState;
- CheckState border = _cbBorder.CheckedState;
- CheckState startHorizontal = _cbHorizontal.CheckedState;
-
- foreach (View sub in _workArea.SubViews)
- {
- sub.Dispose ();
- }
-
- _workArea.RemoveAll ();
-
- if (numberOfViews <= 0)
- {
- return;
- }
-
- TileView root = CreateTileView (1, startHorizontal == CheckState.Checked ? Orientation.Horizontal : Orientation.Vertical);
-
- root.Tiles.ElementAt (0).ContentView.Add (CreateContentControl (1));
- root.Tiles.ElementAt (0).Title = _cbTitles.CheckedState == CheckState.Checked ? "View 1" : string.Empty;
- root.Tiles.ElementAt (1).ContentView.Add (CreateContentControl (2));
- root.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? "View 2" : string.Empty;
-
- root.LineStyle = border == CheckState.Checked? LineStyle.Rounded : LineStyle.None;
-
- _workArea.Add (root);
-
- if (numberOfViews == 1)
- {
- root.Tiles.ElementAt (1).ContentView.Visible = false;
- }
-
- if (numberOfViews > 2)
- {
- _viewsCreated = 2;
- _viewsToCreate = numberOfViews;
- AddMoreViews (root);
- }
- }
-
- private void Split (TileView to, bool left)
- {
- if (_viewsCreated == _viewsToCreate)
- {
- return;
- }
-
- TileView newView;
-
- if (left)
- {
- to.TrySplitTile (0, 2, out newView);
- }
- else
- {
- to.TrySplitTile (1, 2, out newView);
- }
-
- _viewsCreated++;
-
- // 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.Tiles.ElementAt (1).Title = _cbTitles.CheckedState == CheckState.Checked ? $"View {_viewsCreated}" : string.Empty;
-
- // Flip orientation
- newView.Orientation = to.Orientation == Orientation.Vertical
- ? Orientation.Horizontal
- : Orientation.Vertical;
-
- newView.Tiles.ElementAt (1).ContentView.Add (CreateContentControl (_viewsCreated));
- }
-}
diff --git a/Terminal.Gui/ViewBase/View.Hierarchy.cs b/Terminal.Gui/ViewBase/View.Hierarchy.cs
index d7510c2b07..26d56b4811 100644
--- a/Terminal.Gui/ViewBase/View.Hierarchy.cs
+++ b/Terminal.Gui/ViewBase/View.Hierarchy.cs
@@ -111,7 +111,7 @@ protected virtual void OnSuperViewChanged (SuperViewChangedEventArgs e) { }
Logging.Warning ($"{view} has already been Added to {this}.");
}
- // TileView likes to add views that were previously added and have HasFocus = true. No bueno.
+ // Ensure views that were previously added don't have HasFocus = true when re-added
view.HasFocus = false;
// TODO: Make this thread safe
diff --git a/Terminal.Gui/Views/FileDialogs/FileDialog.cs b/Terminal.Gui/Views/FileDialogs/FileDialog.cs
index 344399b82b..1f0064d748 100644
--- a/Terminal.Gui/Views/FileDialogs/FileDialog.cs
+++ b/Terminal.Gui/Views/FileDialogs/FileDialog.cs
@@ -39,7 +39,8 @@ public class FileDialog : Dialog, IDesignable
private readonly IFileSystem _fileSystem;
private readonly FileDialogHistory _history;
private readonly SpinnerView _spinnerView;
- private readonly TileView _splitContainer;
+ private readonly View _leftPanel;
+ private readonly View _rightPanel;
private readonly TableView _tableView;
private readonly TextField _tbFind;
private readonly TextField _tbPath;
@@ -149,19 +150,29 @@ internal FileDialog (IFileSystem fileSystem)
_tbPath.Autocomplete = new AppendAutocomplete (_tbPath);
_tbPath.Autocomplete.SuggestionGenerator = new FilepathSuggestionGenerator ();
- _splitContainer = new ()
+ // Left panel for tree view
+ _leftPanel = new ()
{
+ Id = "leftPanel",
X = 0,
Y = Pos.Bottom (_btnBack),
- Width = Dim.Fill (),
- Height = Dim.Fill (Dim.Func (_ => IsInitialized ? _btnOk.Frame.Height : 1))
+ Width = 30,
+ Height = Dim.Fill (Dim.Func (_ => IsInitialized ? _btnOk.Frame.Height : 1)),
+ Visible = false,
+ CanFocus = true,
+ Arrangement = ViewArrangement.Resizable
};
- Initialized += (s, e) =>
- {
- _splitContainer.SetSplitterPos (0, 30);
- _splitContainer.Tiles.ElementAt (0).ContentView.Visible = false;
- };
+ // Right panel for table view
+ _rightPanel = new ()
+ {
+ Id = "rightPanel",
+ X = Pos.Right (_leftPanel),
+ Y = Pos.Bottom (_btnBack),
+ Width = Dim.Fill (),
+ Height = Dim.Fill (Dim.Func (_ => IsInitialized ? _btnOk.Frame.Height : 1)),
+ CanFocus = true
+ };
// this.splitContainer.Border.BorderStyle = BorderStyle.None;
@@ -202,8 +213,8 @@ internal FileDialog (IFileSystem fileSystem)
_treeView.SelectionChanged += TreeView_SelectionChanged;
- _splitContainer.Tiles.ElementAt (0).ContentView.Add (_treeView);
- _splitContainer.Tiles.ElementAt (1).ContentView.Add (_tableView);
+ _leftPanel.Add (_treeView);
+ _rightPanel.Add (_tableView);
_btnToggleSplitterCollapse = new ()
{
@@ -215,10 +226,9 @@ internal FileDialog (IFileSystem fileSystem)
{
// Required otherwise the Save button clicks itself
e.Handled = true;
- Tile tile = _splitContainer.Tiles.ElementAt (0);
- bool newState = !tile.ContentView.Visible;
- tile.ContentView.Visible = newState;
+ bool newState = !_leftPanel.Visible;
+ _leftPanel.Visible = newState;
_btnToggleSplitterCollapse.Text = GetToggleSplitterText (newState);
SetNeedsLayout ();
};
@@ -282,7 +292,8 @@ internal FileDialog (IFileSystem fileSystem)
Add (_btnUp);
Add (_btnBack);
Add (_btnForward);
- Add (_splitContainer);
+ Add (_leftPanel);
+ Add (_rightPanel);
Add (_btnToggleSplitterCollapse);
Add (_tbFind);
Add (_spinnerView);
diff --git a/Terminal.Gui/Views/SplitterEventArgs.cs b/Terminal.Gui/Views/SplitterEventArgs.cs
deleted file mode 100644
index 7354209e98..0000000000
--- a/Terminal.Gui/Views/SplitterEventArgs.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-
-namespace Terminal.Gui.Views;
-
-/// Provides data for events.
-public class SplitterEventArgs : EventArgs
-{
- /// Creates a new instance of the class.
- /// in which splitter is being moved.
- /// Index of the splitter being moved in .
- /// The new of the splitter line.
- public SplitterEventArgs (TileView tileView, int idx, Pos splitterDistance)
- {
- SplitterDistance = splitterDistance;
- TileView = tileView;
- Idx = idx;
- }
-
- ///
- /// Gets the index of the splitter that is being moved. This can be used to index
- ///
- ///
- public int Idx { get; }
-
- /// New position of the splitter line (see ).
- public Pos SplitterDistance { get; }
-
- /// Container (sender) of the event.
- public TileView TileView { get; }
-}
diff --git a/Terminal.Gui/Views/Tile.cs b/Terminal.Gui/Views/Tile.cs
deleted file mode 100644
index 45bcd259bb..0000000000
--- a/Terminal.Gui/Views/Tile.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-#nullable enable
-using System.ComponentModel;
-
-namespace Terminal.Gui.Views;
-
-///
-/// A single presented in a . To create new instances use
-/// or .
-///
-public class Tile
-{
- private string _title = string.Empty;
-
- /// Creates a new instance of the class.
- public Tile ()
- {
- ContentView = new View
- {
- Width = Dim.Fill (),
- Height = Dim.Fill (),
- CanFocus = true
- };
-#if DEBUG_IDISPOSABLE
- ContentView.Data = "Tile.ContentView";
-#endif
- Title = string.Empty;
- MinSize = 0;
- }
-
- ///
- /// The that is contained in this . Add new child views to this
- /// member for multiple s within the .
- ///
- public View? ContentView { get; internal set; }
-
- ///
- /// Gets or Sets the minimum size you to allow when splitter resizing along parent
- /// direction.
- ///
- public int MinSize { get; set; }
-
- ///
- /// The text that should be displayed above the . This will appear over the splitter line
- /// or border (above the view client area).
- ///
- /// Title are not rendered for root level tiles is .
- public string Title
- {
- get => _title;
- set
- {
- if (!OnTitleChanging (_title, value))
- {
- string old = _title;
- _title = value;
- OnTitleChanged (old, _title);
-
- return;
- }
-
- _title = value;
- }
- }
-
- /// Called when the has been changed. Invokes the event.
- /// The that is/has been replaced.
- /// The new to be replaced.
- public virtual void OnTitleChanged (string oldTitle, string newTitle)
- {
- var args = new EventArgs (in newTitle);
- TitleChanged?.Invoke (this, args);
- }
-
- ///
- /// Called before the changes. Invokes the event, which can be
- /// cancelled.
- ///
- /// The that is/has been replaced.
- /// The new to be replaced.
- /// true if an event handler cancelled the Title change.
- public virtual bool OnTitleChanging (string oldTitle, string newTitle)
- {
- var args = new CancelEventArgs (ref oldTitle, ref newTitle);
- TitleChanging?.Invoke (this, args);
-
- return args.Cancel;
- }
-
- /// Event fired after the has been changed.
- public event EventHandler? TitleChanged;
-
- ///
- /// Event fired when the is changing.
- /// can be set to true to cancel the change.
- ///
- public event EventHandler>? TitleChanging;
-}
diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs
deleted file mode 100644
index 0e929ac960..0000000000
--- a/Terminal.Gui/Views/TileView.cs
+++ /dev/null
@@ -1,1094 +0,0 @@
-#nullable enable
-
-namespace Terminal.Gui.Views;
-
-///
-/// A consisting of a moveable bar that divides the display area into resizeable
-/// .
-///
-public class TileView : View
-{
- private Orientation _orientation = Orientation.Vertical;
- private List? _splitterDistances;
- private List? _splitterLines;
- private List? _tiles;
- private TileView? _parentTileView;
-
- /// Creates a new instance of the class with 2 tiles (i.e. left and right).
- public TileView () : this (2) { }
-
- /// Creates a new instance of the class with number of tiles.
- ///
- public TileView (int tiles)
- {
- CanFocus = true;
- RebuildForTileCount (tiles);
-
- SubViewLayout += (_, _) =>
- {
- Rectangle viewport = Viewport;
-
- if (HasBorder ())
- {
- viewport = new (
- viewport.X + 1,
- viewport.Y + 1,
- Math.Max (0, viewport.Width - 2),
- Math.Max (0, viewport.Height - 2)
- );
- }
-
- Setup (viewport);
- };
- }
-
- /// The line style to use when drawing the splitter lines.
- public LineStyle LineStyle { get; set; } = LineStyle.None;
-
- /// Orientation of the dividing line (Horizontal or Vertical).
- public Orientation Orientation
- {
- get => _orientation;
- set
- {
- if (_orientation == value)
- {
- return;
- }
-
- _orientation = value;
-
- SetNeedsDraw ();
- SetNeedsLayout ();
-
- }
- }
-
- /// The splitter locations. Note that there will be N-1 splitters where N is the number of .
- public IReadOnlyCollection SplitterDistances => _splitterDistances!.AsReadOnly ();
-
- /// The sub sections hosted by the view
- public IReadOnlyCollection Tiles => _tiles!.AsReadOnly ();
-
- // TODO: Update to use Key instead of KeyCode
- ///
- /// The keyboard key that the user can press to toggle resizing of splitter lines. Mouse drag splitting is always
- /// enabled.
- ///
- public KeyCode ToggleResizable { get; set; } = KeyCode.CtrlMask | KeyCode.F10;
-
- ///
- /// Returns the immediate parent of this. Note that in case of deep nesting this might not
- /// be the root . Returns null if this instance is not a nested child (created with
- /// )
- ///
- /// Use to determine if the returned value is the root.
- ///
- public TileView? GetParentTileView () { return _parentTileView; }
-
- ///
- /// Returns the index of the first in which contains
- /// .
- ///
- public int IndexOf (View toFind, bool recursive = false)
- {
- for (var i = 0; i < _tiles!.Count; i++)
- {
- View v = _tiles [i].ContentView!;
-
- if (v == toFind)
- {
- return i;
- }
-
- if (v.SubViews.Contains (toFind))
- {
- return i;
- }
-
- if (recursive)
- {
- if (RecursiveContains (v.SubViews, toFind))
- {
- return i;
- }
- }
- }
-
- return -1;
- }
-
- ///
- /// Adds a new to the collection at . This will also add another splitter
- /// line
- ///
- ///
- public Tile? InsertTile (int idx)
- {
- Tile [] oldTiles = Tiles.ToArray ();
- RebuildForTileCount (oldTiles.Length + 1);
-
- Tile? toReturn = null;
-
- for (var i = 0; i < _tiles?.Count; i++)
- {
- if (i != idx)
- {
- Tile oldTile = oldTiles [i > idx ? i - 1 : i];
-
- // remove the new empty View
- Remove (_tiles [i].ContentView);
- _tiles [i].ContentView?.Dispose ();
- _tiles [i].ContentView = null;
-
- // restore old Tile and View
- _tiles [i] = oldTile;
- _tiles [i].ContentView!.TabStop = TabStop;
- Add (_tiles [i].ContentView);
- }
- else
- {
- toReturn = _tiles [i];
- }
- }
-
- SetNeedsDraw ();
- SetNeedsLayout ();
-
- return toReturn;
- }
-
- ///
- ///
- /// if is nested within a parent e.g. via
- /// the . if it is a root level .
- ///
- ///
- ///
- /// Note that manually adding one to another will not result in a parent/child relationship
- /// and both will still be considered 'root' containers. Always use
- /// if you want to subdivide a .
- ///
- ///
- public bool IsRootTileView () { return _parentTileView == null; }
-
- /// Overridden so no Frames get drawn
- ///
- protected override bool OnDrawingAdornments () { return true; }
-
- ///
- protected override bool OnRenderingLineCanvas () { return false; }
-
- ///
- protected override void OnDrawComplete (DrawContext? context)
- {
- SetAttributeForRole (Enabled ? VisualRole.Normal : VisualRole.Disabled);
-
- var lc = new LineCanvas ();
-
- List allLines = GetAllLineViewsRecursively (this);
- List allTitlesToRender = GetAllTitlesToRenderRecursively (this);
-
- if (IsRootTileView ())
- {
- if (HasBorder ())
- {
- lc.AddLine (Point.Empty, Viewport.Width, Orientation.Horizontal, LineStyle);
- lc.AddLine (Point.Empty, Viewport.Height, Orientation.Vertical, LineStyle);
-
- lc.AddLine (
- new (Viewport.Width - 1, Viewport.Height - 1),
- -Viewport.Width,
- Orientation.Horizontal,
- LineStyle
- );
-
- lc.AddLine (
- new (Viewport.Width - 1, Viewport.Height - 1),
- -Viewport.Height,
- Orientation.Vertical,
- LineStyle
- );
- }
-
- foreach (TileViewLineView line in allLines)
- {
- bool isRoot = _splitterLines!.Contains (line);
-
- Rectangle screen = line.ViewportToScreen (Rectangle.Empty);
- Point origin = ScreenToFrame (screen.Location);
- int length = line.Orientation == Orientation.Horizontal ? line.Frame.Width : line.Frame.Height;
-
- if (!isRoot)
- {
- if (line.Orientation == Orientation.Horizontal)
- {
- origin.X -= 1;
- }
- else
- {
- origin.Y -= 1;
- }
-
- length += 2;
- }
-
- lc.AddLine (origin, length, line.Orientation, LineStyle);
- }
- }
-
- SetAttributeForRole (Enabled ? VisualRole.Normal : VisualRole.Disabled);
-
- foreach (KeyValuePair p in lc.GetMap (Viewport))
- {
- AddRune (p.Key.X, p.Key.Y, p.Value);
- }
-
- // Redraw the lines so that focus/drag symbol renders
- foreach (TileViewLineView line in allLines)
- {
- line.DrawSplitterSymbol ();
- }
-
- // Draw Titles over Border
-
- foreach (TileTitleToRender titleToRender in allTitlesToRender)
- {
- Point renderAt = titleToRender.GetLocalCoordinateForTitle (this);
-
- if (renderAt.Y < 0)
- {
- // If we have no border then root level tiles
- // have nowhere to render their titles.
- continue;
- }
-
- // TODO: Render with focus color if focused
-
- string title = titleToRender.GetTrimmedTitle ();
-
- for (var i = 0; i < title.Length; i++)
- {
- AddRune (renderAt.X + i, renderAt.Y, (Rune)title [i]);
- }
- }
-
- return;
- }
-
- //// BUGBUG: Why is this not handled by a key binding???
- ///
- protected override bool OnKeyDownNotHandled (Key key)
- {
- var focusMoved = false;
-
- if (key.KeyCode == ToggleResizable)
- {
- foreach (TileViewLineView l in _splitterLines!)
- {
- bool iniBefore = l.IsInitialized;
- l.IsInitialized = false;
- l.CanFocus = !l.CanFocus;
- l.IsInitialized = iniBefore;
-
- if (l.CanFocus && !focusMoved)
- {
- l.SetFocus ();
- focusMoved = true;
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- ///
- /// Scraps all and creates new tiles in orientation
- ///
- ///
- ///
- public void RebuildForTileCount (int count)
- {
- _tiles = new ();
- _splitterDistances = new ();
-
- if (_splitterLines is { })
- {
- foreach (TileViewLineView sl in _splitterLines)
- {
- sl.Dispose ();
- }
- }
-
- _splitterLines = new ();
-
- RemoveAll ();
-
- foreach (Tile tile in _tiles)
- {
- tile.ContentView?.Dispose ();
- tile.ContentView = null;
- }
-
- _tiles.Clear ();
- _splitterDistances.Clear ();
-
- if (count == 0)
- {
- return;
- }
-
- for (var i = 0; i < count; i++)
- {
- if (i > 0)
- {
- Pos currentPos = Pos.Percent (100 / count * i);
- _splitterDistances.Add (currentPos);
- var line = new TileViewLineView (this, i - 1);
- Add (line);
- _splitterLines.Add (line);
- }
-
- var tile = new Tile ();
- _tiles.Add (tile);
- tile.ContentView!.Id = $"Tile.ContentView {i}";
- Add (tile.ContentView);
-
- // BUGBUG: This should not be needed:
- tile.TitleChanged += (s, e) => SetNeedsLayout ();
- }
-
- SetNeedsLayout ();
- }
-
- ///
- /// Removes a at the provided from the view. Returns the removed tile
- /// or null if already empty.
- ///
- ///
- ///
- public Tile? RemoveTile (int idx)
- {
- Tile [] oldTiles = Tiles.ToArray ();
-
- if (idx < 0 || idx >= oldTiles.Length)
- {
- return null;
- }
-
- Tile removed = Tiles.ElementAt (idx);
-
- RebuildForTileCount (oldTiles.Length - 1);
-
- for (var i = 0; i < _tiles?.Count; i++)
- {
- int oldIdx = i >= idx ? i + 1 : i;
- Tile oldTile = oldTiles [oldIdx];
-
- // remove the new empty View
- Remove (_tiles [i].ContentView);
- _tiles [i].ContentView?.Dispose ();
- _tiles [i].ContentView = null;
-
- // restore old Tile and View
- _tiles [i] = oldTile;
- Add (_tiles [i].ContentView);
- }
-
- return removed;
- }
-
- ///
- ///
- /// Attempts to update the of line at to the new
- /// . Returns false if the new position is not allowed because of
- /// , location of other splitters etc.
- ///
- ///
- /// Only absolute values (e.g. 10) and percent values (i.e. ) are supported for
- /// this property.
- ///
- ///
- public bool SetSplitterPos (int idx, Pos value)
- {
- if (!(value is PosAbsolute) && !(value is PosPercent))
- {
- throw new ArgumentException (
- $"Only Percent and Absolute values are supported. Passed value was {value.GetType ().Name}"
- );
- }
-
- int fullSpace = _orientation == Orientation.Vertical ? Viewport.Width : Viewport.Height;
-
- if (fullSpace != 0 && !IsValidNewSplitterPos (idx, value, fullSpace))
- {
- return false;
- }
-
- if (_splitterDistances is { })
- {
- _splitterDistances [idx] = value;
- }
-
- OnSplitterMoved (idx);
- SetNeedsDraw ();
- SetNeedsLayout ();
-
- return true;
- }
-
- /// Invoked when any of the is changed.
- public event SplitterEventHandler? SplitterMoved;
-
- ///
- /// Converts of element from a regular to a new
- /// nested the specified . Returns false if the element already
- /// contains a nested view.
- ///
- ///
- /// After successful splitting, the old contents will be moved to the
- /// 's first tile.
- ///
- /// The element of that is to be subdivided.
- /// The number of panels that the should be split into
- /// The new nested .
- ///
- /// if a was converted to a new nested .
- /// if it was already a nested
- ///
- public bool TrySplitTile (int idx, int numberOfPanels, out TileView result)
- {
- // when splitting a view into 2 sub views we will need to migrate
- // the title too
- Tile tile = _tiles! [idx];
-
- string title = tile.Title;
- View? toMove = tile.ContentView;
-
- if (toMove is TileView existing)
- {
- result = existing;
-
- return false;
- }
-
- var newContainer = new TileView (numberOfPanels)
- {
- Width = Dim.Fill (), Height = Dim.Fill (), _parentTileView = this
- };
-
- // Take everything out of the View we are moving
- View [] childViews = toMove!.SubViews.ToArray ();
- toMove.RemoveAll ();
-
- // Remove the view itself and replace it with the new TileView
- Remove (toMove);
- toMove.Dispose ();
- toMove = null;
-
- Add (newContainer);
-
- tile.ContentView = newContainer;
-
- View newTileView1 = newContainer!._tiles? [0].ContentView!;
-
- // Add the original content into the first view of the new container
- foreach (View childView in childViews)
- {
- newTileView1!.Add (childView);
- }
-
- // Move the title across too
- newContainer._tiles! [0].Title = title;
- tile.Title = string.Empty;
-
- result = newContainer;
-
- return true;
- }
-
- ///
- protected override void Dispose (bool disposing)
- {
- foreach (Tile tile in Tiles)
- {
- Remove (tile.ContentView);
- tile.ContentView?.Dispose ();
- }
-
- base.Dispose (disposing);
- }
-
- /// Raises the event
- protected virtual void OnSplitterMoved (int idx) { SplitterMoved?.Invoke (this, new (this, idx, _splitterDistances! [idx])); }
-
- private List GetAllLineViewsRecursively (View v)
- {
- List lines = new ();
-
- foreach (View sub in v.SubViews)
- {
- if (sub is TileViewLineView s)
- {
- if (s.Visible && s.Parent.GetRootTileView () == this)
- {
- lines.Add (s);
- }
- }
- else
- {
- if (sub.Visible)
- {
- lines.AddRange (GetAllLineViewsRecursively (sub));
- }
- }
- }
-
- return lines;
- }
-
- private List GetAllTitlesToRenderRecursively (TileView? v, int depth = 0)
- {
- List titles = new ();
-
- foreach (Tile sub in v!.Tiles)
- {
- // Don't render titles for invisible stuff!
- if (!sub.ContentView!.Visible)
- {
- continue;
- }
-
- if (sub.ContentView is TileView subTileView)
- {
- // Panels with sub split tiles in them can never
- // have their Titles rendered. Instead we dive in
- // and pull up their children as titles
- titles.AddRange (GetAllTitlesToRenderRecursively (subTileView, depth + 1));
- }
- else
- {
- if (sub.Title.Length > 0)
- {
- titles.Add (new (v, sub, depth));
- }
- }
- }
-
- return titles;
- }
-
- private TileView GetRootTileView ()
- {
- TileView root = this;
-
- while (root._parentTileView is { })
- {
- root = root._parentTileView;
- }
-
- return root;
- }
-
- private Dim GetTileWidthOrHeight (int i, int space, Tile? [] visibleTiles, TileViewLineView? [] visibleSplitterLines)
- {
- // last tile
- if (i + 1 >= visibleTiles.Length)
- {
- return Dim.Fill (HasBorder () ? 1 : 0)!;
- }
-
- TileViewLineView? nextSplitter = visibleSplitterLines [i];
- Pos? nextSplitterPos = Orientation == Orientation.Vertical ? nextSplitter!.X : nextSplitter!.Y;
- int nextSplitterDistance = nextSplitterPos.GetAnchor (space);
-
- TileViewLineView? lastSplitter = i >= 1 ? visibleSplitterLines [i - 1] : null;
- Pos? lastSplitterPos = Orientation == Orientation.Vertical ? lastSplitter?.X : lastSplitter?.Y;
- int lastSplitterDistance = lastSplitterPos?.GetAnchor (space) ?? 0;
-
- int distance = nextSplitterDistance - lastSplitterDistance;
-
- if (i > 0)
- {
- return distance - 1;
- }
-
- return distance - (HasBorder () ? 1 : 0);
- }
-
- private bool HasBorder () { return LineStyle != LineStyle.None; }
-
- private void HideSplittersBasedOnTileVisibility ()
- {
- if (_splitterLines is { Count: 0 })
- {
- return;
- }
-
- foreach (TileViewLineView line in _splitterLines!)
- {
- line.Visible = true;
- }
-
- for (var i = 0; i < _tiles!.Count; i++)
- {
- if (!_tiles [i].ContentView!.Visible)
- {
- // when a tile is not visible, prefer hiding
- // the splitter on it's left
- TileViewLineView candidate = _splitterLines [Math.Max (0, i - 1)];
-
- // unless that splitter is already hidden
- // e.g. when hiding panels 0 and 1 of a 3 panel
- // container
- if (candidate.Visible)
- {
- candidate.Visible = false;
- }
- else
- {
- _splitterLines [Math.Min (i, _splitterLines.Count - 1)].Visible = false;
- }
- }
- }
- }
-
- private bool IsValidNewSplitterPos (int idx, Pos value, int fullSpace)
- {
- int newSize = value.GetAnchor (fullSpace);
- bool isGettingBigger = newSize > _splitterDistances! [idx].GetAnchor (fullSpace);
- int lastSplitterOrBorder = HasBorder () ? 1 : 0;
- int nextSplitterOrBorder = HasBorder () ? fullSpace - 1 : fullSpace;
-
- // Cannot move off screen right
- if (newSize >= fullSpace - (HasBorder () ? 1 : 0))
- {
- if (isGettingBigger)
- {
- return false;
- }
- }
-
- // Cannot move off screen left
- if (newSize < (HasBorder () ? 1 : 0))
- {
- if (!isGettingBigger)
- {
- return false;
- }
- }
-
- // Do not allow splitter to move left of the one before
- if (idx > 0)
- {
- int posLeft = _splitterDistances [idx - 1].GetAnchor (fullSpace);
-
- if (newSize <= posLeft)
- {
- return false;
- }
-
- lastSplitterOrBorder = posLeft;
- }
-
- // Do not allow splitter to move right of the one after
- if (idx + 1 < _splitterDistances.Count)
- {
- int posRight = _splitterDistances [idx + 1].GetAnchor (fullSpace);
-
- if (newSize >= posRight)
- {
- return false;
- }
-
- nextSplitterOrBorder = posRight;
- }
-
- if (isGettingBigger)
- {
- int spaceForNext = nextSplitterOrBorder - newSize;
-
- // space required for the last line itself
- if (idx > 0)
- {
- spaceForNext--;
- }
-
- // don't grow if it would take us below min size of right panel
- if (spaceForNext < _tiles! [idx + 1].MinSize)
- {
- return false;
- }
- }
- else
- {
- int spaceForLast = newSize - lastSplitterOrBorder;
-
- // space required for the line itself
- if (idx > 0)
- {
- spaceForLast--;
- }
-
- // don't shrink if it would take us below min size of left panel
- if (spaceForLast < _tiles! [idx].MinSize)
- {
- return false;
- }
- }
-
- return true;
- }
-
- private bool RecursiveContains (IEnumerable haystack, View needle)
- {
- foreach (View v in haystack)
- {
- if (v == needle)
- {
- return true;
- }
-
- if (RecursiveContains (v.SubViews, needle))
- {
- return true;
- }
- }
-
- return false;
- }
-
- private void Setup (Rectangle viewport)
- {
- if (viewport.IsEmpty || viewport.Height <= 0 || viewport.Width <= 0)
- {
- return;
- }
-
- for (var i = 0; i < _splitterLines!.Count; i++)
- {
- TileViewLineView line = _splitterLines [i];
-
- line.Orientation = Orientation;
-
- line.Width = _orientation == Orientation.Vertical
- ? 1
- : Dim.Fill ();
-
- line.Height = _orientation == Orientation.Vertical
- ? Dim.Fill ()
- : 1;
- line.LineRune = _orientation == Orientation.Vertical ? Glyphs.VLine : Glyphs.HLine;
-
- if (_orientation == Orientation.Vertical)
- {
- line.X = _splitterDistances! [i];
- line.Y = 0;
- }
- else
- {
- line.Y = _splitterDistances! [i];
- line.X = 0;
- }
- }
-
- HideSplittersBasedOnTileVisibility ();
-
- Tile [] visibleTiles = _tiles!.Where (t => t.ContentView!.Visible).ToArray ();
- TileViewLineView [] visibleSplitterLines = _splitterLines.Where (l => l.Visible).ToArray ();
-
- for (var i = 0; i < visibleTiles.Length; i++)
- {
- Tile tile = visibleTiles [i];
-
- if (Orientation == Orientation.Vertical)
- {
- tile.ContentView!.X = i == 0 ? viewport.X : Pos.Right (visibleSplitterLines [i - 1]);
- tile.ContentView.Y = viewport.Y;
- tile.ContentView.Height = viewport.Height;
- tile.ContentView.Width = GetTileWidthOrHeight (i, Viewport.Width, visibleTiles, visibleSplitterLines);
- }
- else
- {
- tile.ContentView!.X = viewport.X;
- tile.ContentView.Y = i == 0 ? viewport.Y : Pos.Bottom (visibleSplitterLines [i - 1]);
- tile.ContentView.Width = viewport.Width;
- tile.ContentView.Height = GetTileWidthOrHeight (i, Viewport.Height, visibleTiles, visibleSplitterLines);
- }
-
- // BUGBUG: This should not be needed. If any of the pos/dim setters above actually changed values, NeedsDisplay should have already been set.
- tile.ContentView.SetNeedsDraw ();
- }
- }
-
- private class TileTitleToRender
- {
- public TileTitleToRender (TileView? parent, Tile tile, int depth)
- {
- Parent = parent;
- Tile = tile;
- Depth = depth;
- }
-
- public int Depth { get; }
- public TileView? Parent { get; }
- public Tile? Tile { get; }
-
- ///
- /// Translates the title location from its local coordinate space
- /// .
- ///
- public Point GetLocalCoordinateForTitle (TileView intoCoordinateSpace)
- {
- Rectangle screen = Tile!.ContentView!.ViewportToScreen (Rectangle.Empty);
-
- return intoCoordinateSpace.ScreenToFrame (new (screen.X, screen.Y - 1));
- }
-
- internal string GetTrimmedTitle ()
- {
- Dim? spaceDim = Tile?.ContentView?.Width;
-
- int spaceAbs = spaceDim!.GetAnchor (Parent!.Viewport.Width);
-
- var title = $" {Tile!.Title} ";
-
- if (title.Length > spaceAbs)
- {
- return title!.Substring (0, spaceAbs);
- }
-
- return title;
- }
- }
-
- private class TileViewLineView : LineView
- {
- public Point? moveRuneRenderLocation;
-
- private Pos? dragOrignalPos;
- private Point? dragPosition;
-
- public TileViewLineView (TileView parent, int idx)
- {
- CanFocus = false;
- TabStop = TabBehavior.TabStop;
-
- Parent = parent;
- Idx = idx;
- AddCommand (Command.Right, () => MoveSplitter (1, 0));
-
- AddCommand (Command.Left, () => MoveSplitter (-1, 0));
-
- AddCommand (Command.Up, () => MoveSplitter (0, -1));
-
- AddCommand (Command.Down, () => MoveSplitter (0, 1));
-
- KeyBindings.Add (Key.CursorRight, Command.Right);
- KeyBindings.Add (Key.CursorLeft, Command.Left);
- KeyBindings.Add (Key.CursorUp, Command.Up);
- KeyBindings.Add (Key.CursorDown, Command.Down);
- }
-
- public int Idx { get; }
- public TileView Parent { get; }
-
- public void DrawSplitterSymbol ()
- {
- if (dragPosition is { } || CanFocus)
- {
- Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2);
-
- AddRune (location.X, location.Y, Glyphs.Diamond);
- }
- }
-
- protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
- {
- if (!dragPosition.HasValue && mouseEvent.Flags == MouseFlags.Button1Pressed)
- {
- // Start a Drag
- SetFocus ();
-
- if (mouseEvent.Flags == MouseFlags.Button1Pressed)
- {
- dragPosition = mouseEvent.Position;
- dragOrignalPos = Orientation == Orientation.Horizontal ? Y : X;
- Application.MouseGrabHandler.GrabMouse (this);
-
- if (Orientation == Orientation.Horizontal)
- { }
- else
- {
- moveRuneRenderLocation = new Point (
- 0,
- Math.Max (1, Math.Min (Viewport.Height - 2, mouseEvent.Position.Y))
- );
- }
- }
-
- return true;
- }
-
- if (
- dragPosition.HasValue && mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))
- {
- // Continue Drag
-
- // how far has user dragged from original location?
- if (Orientation == Orientation.Horizontal)
- {
- int dy = mouseEvent.Position.Y - dragPosition.Value.Y;
- Parent.SetSplitterPos (Idx, Offset (Y, dy));
- moveRuneRenderLocation = new Point (mouseEvent.Position.X, 0);
- }
- else
- {
- int dx = mouseEvent.Position.X - dragPosition.Value.X;
- Parent.SetSplitterPos (Idx, Offset (X, dx));
- moveRuneRenderLocation = new Point (0, Math.Max (1, Math.Min (Viewport.Height - 2, mouseEvent.Position.Y)));
- }
-
- Parent.SetNeedsLayout ();
-
- return true;
- }
-
- if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) && dragPosition.HasValue)
- {
- // End Drag
-
- Application.MouseGrabHandler.UngrabMouse ();
-
- //Driver.UncookMouse ();
- FinalisePosition (
- dragOrignalPos!,
- Orientation == Orientation.Horizontal ? Y : X
- );
- dragPosition = null;
- moveRuneRenderLocation = null;
- }
-
- return false;
- }
-
- ///
- protected override bool OnClearingViewport () { return true; }
-
- protected override bool OnDrawingContent ()
- {
- DrawSplitterSymbol ();
-
- return true;
- }
-
- public override Point? PositionCursor ()
- {
- base.PositionCursor ();
-
- Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2);
- Move (location.X, location.Y);
-
- return null; // Hide cursor
- }
-
- ///
- ///
- /// Determines the absolute position of and returns a that
- /// describes the percentage of that.
- ///
- ///
- /// Effectively turning any into a (as if created with
- /// )
- ///
- ///
- /// The to convert to
- /// The Height/Width that lies within
- ///
- private Pos ConvertToPosPercent (Pos p, int parentLength)
- {
- // Calculate position in the 'middle' of the cell at p distance along parentLength
- float position = p.GetAnchor (parentLength) + 0.5f;
-
- // Calculate the percentage
- var percent = (int)Math.Round (position / parentLength * 100);
-
- // Return a new PosPercent object
- return Pos.Percent (percent);
- }
-
- ///
- ///
- /// Moves to
- /// preserving format (absolute / relative) that
- /// had.
- ///
- ///
- /// This ensures that if splitter location was e.g. 50% before and you move it to absolute 5 then you end up
- /// with 10% (assuming a parent had 50 width).
- ///
- ///
- ///
- ///
- private bool FinalisePosition (Pos oldValue, Pos newValue)
- {
- SetNeedsDraw ();
-
- SetNeedsLayout ();
-
- if (oldValue is PosPercent)
- {
- if (Orientation == Orientation.Horizontal)
- {
- return Parent.SetSplitterPos (Idx, ConvertToPosPercent (newValue, Parent.Viewport.Height));
- }
-
- return Parent.SetSplitterPos (Idx, ConvertToPosPercent (newValue, Parent.Viewport.Width));
- }
-
- return Parent.SetSplitterPos (Idx, newValue);
- }
-
- private bool MoveSplitter (int distanceX, int distanceY)
- {
- if (Orientation == Orientation.Vertical)
- {
- // Cannot move in this direction
- if (distanceX == 0)
- {
- return false;
- }
-
- Pos oldX = X;
-
- return FinalisePosition (oldX, Offset (X, distanceX));
- }
-
- // Cannot move in this direction
- if (distanceY == 0)
- {
- return false;
- }
-
- Pos oldY = Y;
-
- return FinalisePosition (oldY, Offset (Y, distanceY));
- }
-
- private Pos Offset (Pos pos, int delta)
- {
- int posAbsolute = pos.GetAnchor (
- Orientation == Orientation.Horizontal
- ? Parent.Viewport.Height
- : Parent.Viewport.Width
- );
-
- return posAbsolute + delta;
- }
- }
-}
-
-/// Represents a method that will handle splitter events.
-public delegate void SplitterEventHandler (object? sender, SplitterEventArgs e);
diff --git a/Tests/UnitTests/FileServices/FileDialogTests.cs b/Tests/UnitTests/FileServices/FileDialogTests.cs
index 3aa7830111..11e0972c61 100644
--- a/Tests/UnitTests/FileServices/FileDialogTests.cs
+++ b/Tests/UnitTests/FileServices/FileDialogTests.cs
@@ -798,8 +798,14 @@ private TextField GetTextField (FileDialog dlg, FileDialogPart part)
private TableView GetTableView (FileDialog dlg)
{
- var tile = dlg.SubViews.OfType ().Single ();
- return (TableView)tile.Tiles.ElementAt (1).ContentView.SubViews.ElementAt(0);
+ // The TableView is now directly in _rightPanel
+ var rightPanel = dlg.SubViews.FirstOrDefault(v => v.Id == "rightPanel");
+ if (rightPanel != null)
+ {
+ return (TableView)rightPanel.SubViews.First(s => s is TableView);
+ }
+ // Fallback - shouldn't reach here
+ throw new InvalidOperationException("Could not find rightPanel in FileDialog");
}
private enum FileDialogPart
diff --git a/Tests/UnitTests/Views/TileViewTests.cs b/Tests/UnitTests/Views/TileViewTests.cs
deleted file mode 100644
index 4cc7ee2ea4..0000000000
--- a/Tests/UnitTests/Views/TileViewTests.cs
+++ /dev/null
@@ -1,2406 +0,0 @@
-using UnitTests;
-using Xunit.Abstractions;
-
-namespace Terminal.Gui.ViewsTests;
-
-public class TileViewTests (ITestOutputHelper output)
-{
- [Fact]
- [AutoInitShutdown]
- public void Test_SplitTop_WholeBottom ()
- {
- var tileView = new TileView (2)
- {
- Width = 20, Height = 10, Orientation = Orientation.Horizontal, LineStyle = LineStyle.Single
- };
-
- Assert.True (tileView.TrySplitTile (0, 2, out TileView top));
-
- top.Tiles.ElementAt (0).ContentView!.Add (new Label { Text = "bleh" });
- top.Tiles.ElementAt (1).ContentView!.Add (new Label { Text = "blah" });
- top.Layout ();
-
- tileView.Tiles.ElementAt (1).ContentView!.Add (new Label { Text = "Hello" });
- tileView.SetScheme (new ());
- top.SetScheme (new ());
-
- top.Layout ();
- tileView.Layout ();
- tileView.Draw ();
-
- var looksLike =
- @"
-┌─────────┬────────┐
-│bleh │blah │
-│ │ │
-│ │ │
-│ │ │
-├─────────┴────────┤
-│Hello │
-│ │
-│ │
-└──────────────────┘";
-
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter1 ()
- {
- TileView tv = Get5x1TilesView ();
-
- tv.Tiles.ElementAt (0).MinSize = int.MaxValue;
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 0; x <= 5; x++)
- {
- // All these values would result in tile 0 getting smaller
- // so are not allowed (tile[0] has a min size of Int.Max)
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 6; x < 10; x++)
- {
- // All these values would result in tile 0 getting bigger
- // so are allowed
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 10; x < 100; x++)
- {
- // These values would result in the first splitter moving past
- // the second splitter so are not allowed
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────────┬┬────┬────┬───┐
-│11111111││3333│4444│555│
-│ ││ │ │ │
-└────────┴┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter1_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- tv.Tiles.ElementAt (0).MinSize = int.MaxValue;
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 0; x <= 5; x++)
- {
- // All these values would result in tile 0 getting smaller
- // so are not allowed (tile[0] has a min size of Int.Max)
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 6; x < 10; x++)
- {
- // All these values would result in tile 0 getting bigger
- // so are allowed
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 10; x < 100; x++)
- {
- // These values would result in the first splitter moving past
- // the second splitter so are not allowed
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-111111111││3333│4444│5555
- ││ │ │
- ││ │ │
- ││ │ │
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter2 ()
- {
- TileView tv = Get5x1TilesView ();
-
- tv.Tiles.ElementAt (1).MinSize = 2;
- tv.Tiles.ElementAt (2).MinSize = 3;
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x > 7; x--)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 7; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬──┬──────┬────┬───┐
-│1111│22│333333│4444│555│
-│ │ │ │ │ │
-└────┴──┴──────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x < 12; x++)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 12; x < 25; x++)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- Application.Top!.Layout ();
- tv.Draw ();
-
- looksLike =
- @"
-┌────┬─────┬───┬────┬───┐
-│1111│22222│333│4444│555│
-│ │ │ │ │ │
-└────┴─────┴───┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter2_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- tv.Tiles.ElementAt (1).MinSize = 2;
- tv.Tiles.ElementAt (2).MinSize = 3;
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x > 7; x--)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 7; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-
-11111│22│333333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x < 12; x++)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 12; x < 25; x++)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│22222│333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter4 ()
- {
- TileView tv = Get5x1TilesView ();
-
- tv.Tiles.ElementAt (3).MinSize = 2;
- tv.Tiles.ElementAt (4).MinSize = 1;
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x > 17; x--)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 17; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬────┬────┬──┬─────┐
-│1111│2222│3333│44│55555│
-│ │ │ │ │ │
-└────┴────┴────┴──┴─────┘
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x < 23; x++)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 23; x < 100; x++)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬────┬────┬──────┬─┐
-│1111│2222│3333│444444│5│
-│ │ │ │ │ │
-└────┴────┴────┴──────┴─┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_MinSizes_VerticalSplitters_ResizeSplitter4_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- tv.Tiles.ElementAt (3).MinSize = 2;
- tv.Tiles.ElementAt (4).MinSize = 1;
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x > 17; x--)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 17; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│2222│3333│44│555555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x < 24; x++)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 24; x < 100; x++)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│2222│3333│4444444│5
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter1_CannotCrossBorder ()
- {
- TileView tv = Get5x1TilesView ();
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 5; x > 0; x--)
- {
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- Assert.False (tv.SetSplitterPos (0, 0));
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌┬────────┬────┬────┬───┐
-││22222222│3333│4444│555│
-││ │ │ │ │
-└┴────────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 6; x < 10; x++)
- {
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 10; x < 100; x++)
- {
- // These values would result in the first splitter moving past
- // the second splitter so are not allowed
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────────┬┬────┬────┬───┐
-│11111111││3333│4444│555│
-│ ││ │ │ │
-└────────┴┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter1_CannotCrossBorder_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 5; x >= 0; x--)
- {
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-│222222222│3333│4444│5555
-│ │ │ │
-│ │ │ │
-│ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 6; x < 10; x++)
- {
- Assert.True (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- for (var x = 10; x < 100; x++)
- {
- // These values would result in the first splitter moving past
- // the second splitter so are not allowed
- Assert.False (tv.SetSplitterPos (0, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-111111111││3333│4444│5555
- ││ │ │
- ││ │ │
- ││ │ │
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter2_CannotMoveOverNeighbours ()
- {
- TileView tv = Get5x1TilesView ();
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x > 5; x--)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 5; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬┬────────┬────┬───┐
-│1111││33333333│4444│555│
-│ ││ │ │ │
-└────┴┴────────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x < 15; x++)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 15; x < 25; x++)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬────────┬┬────┬───┐
-│1111│22222222││4444│555│
-│ │ ││ │ │
-└────┴────────┴┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter2_CannotMoveOverNeighbours_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x > 5; x--)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 5; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111││33333333│4444│5555
- ││ │ │
- ││ │ │
- ││ │ │
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 10; x < 15; x++)
- {
- Assert.True (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- for (var x = 15; x < 25; x++)
- {
- Assert.False (tv.SetSplitterPos (1, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│22222222││4444│5555
- │ ││ │
- │ ││ │
- │ ││ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter4_CannotMoveOverNeighbours ()
- {
- TileView tv = Get5x1TilesView ();
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-┌────┬────┬────┬────┬───┐
-│1111│2222│3333│4444│555│
-│ │ │ │ │ │
-└────┴────┴────┴────┴───┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x > 15; x--)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 15; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬────┬────┬┬───────┐
-│1111│2222│3333││5555555│
-│ │ │ ││ │
-└────┴────┴────┴┴───────┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x < 24; x++)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 24; x < 100; x++)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-┌────┬────┬────┬───────┬┐
-│1111│2222│3333│4444444││
-│ │ │ │ ││
-└────┴────┴────┴───────┴┘
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- [AutoInitShutdown]
- public void Test5Panel_NoMinSizes_VerticalSplitters_ResizeSplitter4_CannotMoveOverNeighbours_NoBorder ()
- {
- TileView tv = Get5x1TilesView (false);
-
- AutoInitShutdownAttribute.RunIteration ();
-
- var looksLike =
- @"
-11111│2222│3333│4444│5555
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x > 15; x--)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 15; x > 0; x--)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│2222│3333││55555555
- │ │ ││
- │ │ ││
- │ │ ││
-
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
-
- for (var x = 20; x < 25; x++)
- {
- Assert.True (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- for (var x = 25; x < 100; x++)
- {
- Assert.False (tv.SetSplitterPos (3, x), $"Assert failed for x={x}");
- }
-
- AutoInitShutdownAttribute.RunIteration ();
-
- looksLike =
- @"
-11111│2222│3333│44444444│
- │ │ │ │
- │ │ │ │
- │ │ │ │
-";
- DriverAssert.AssertDriverContentsAre (looksLike, output);
- }
-
- [Fact]
- public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringInsertTile ()
- {
- TileView tv = GetTileView (20, 10);
-
- var myReusableView = new DisposeCounter ();
-
- // I want my view in the first tile
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
- Assert.Equal (0, myReusableView.DisposalCount);
-
- // I've changed my mind, I want 3 tiles now
- tv.InsertTile (0);
- tv.InsertTile (2);
-
- // but I still want my view in the first tile
- // BUGBUG: Adding a view twice is not legit
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
-
- Assert.Multiple (
- () => Assert.Equal (0, myReusableView.DisposalCount),
- () =>
- {
- tv.Dispose ();
- Assert.True (myReusableView.DisposalCount >= 1);
- }
- );
- }
-
- [Fact]
- public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRebuildForTileCount ()
- {
- TileView tv = GetTileView (20, 10);
-
- var myReusableView = new DisposeCounter ();
-
- // I want my view in the first tile
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
- Assert.Equal (0, myReusableView.DisposalCount);
-
- // I've changed my mind, I want 3 tiles now
- tv.RebuildForTileCount (3);
-
- // but I still want my view in the first tile
- // BUGBUG: Adding a view twice is not legit
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
-
- Assert.Multiple (
- () => Assert.Equal (0, myReusableView.DisposalCount),
- () =>
- {
- tv.Dispose ();
- Assert.Equal (1, myReusableView.DisposalCount);
- }
- );
-
- Assert.NotNull (Application.Top);
- Application.Top.Dispose ();
- Application.Shutdown ();
- }
-
- [Theory]
- [InlineData (0)]
- [InlineData (1)]
- public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRemoveTile (int idx)
- {
- TileView tv = GetTileView (20, 10);
-
- var myReusableView = new DisposeCounter ();
-
- // I want my view in the first tile
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
- Assert.Equal (0, myReusableView.DisposalCount);
-
- tv.RemoveTile (idx);
-
- // but I still want my view in the first tile
- // BUGBUG: Adding a view twice is not legit
- tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
-
- Assert.Multiple (
- () => Assert.Equal (0, myReusableView.DisposalCount),
- () =>
- {
- tv.Dispose ();
- Assert.True (myReusableView.DisposalCount >= 1);
- }
- );
-
- Assert.NotNull (Application.Top);
- Application.Top.Dispose ();
- Application.Shutdown ();
- }
-
- [Fact]
- [AutoInitShutdown]
- public void TestNestedContainer2LeftAnd1Right_RendersNicely ()
- {
- TileView tileView = GetNestedContainer2Left1Right (false);
-
- Assert.Equal (20, tileView.Frame.Width);
- Assert.Equal (10, tileView.Tiles.ElementAt (0).ContentView.Frame.Width);
- Assert.Equal (9, tileView.Tiles.ElementAt (1).ContentView.Frame.Width);
-
- Assert.IsType (tileView.Tiles.ElementAt (0).ContentView);
- var left = (TileView)tileView.Tiles.ElementAt (0).ContentView;
- Assert.Same (left.SuperView, tileView);
-
- Assert.Equal (2, left.Tiles.ElementAt (0).ContentView.SubViews.Count);
- Assert.IsType