diff --git a/Terminal.Gui/Views/SplitContainer.cs b/Terminal.Gui/Views/SplitContainer.cs index aebc2ad2a..f57397a6d 100644 --- a/Terminal.Gui/Views/SplitContainer.cs +++ b/Terminal.Gui/Views/SplitContainer.cs @@ -1,4 +1,8 @@ -using System; +using NStack; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using Terminal.Gui.Graphs; namespace Terminal.Gui { @@ -7,15 +11,12 @@ namespace Terminal.Gui { /// A consisting of a moveable bar that divides /// the display area into 2 resizeable panels. /// - public class SplitContainer : View { + public class SplitContainer : FrameView { - private LineView splitterLine; - private bool panel1Collapsed; - private bool panel2Collapsed; + private SplitContainerLineView splitterLine; private Pos splitterDistance = Pos.Percent (50); private Orientation orientation = Orientation.Vertical; - private Pos panel1MinSize = 0; - private Pos panel2MinSize = 0; + private SplitterPanel [] splitterPanels = { new SplitterPanel(), new SplitterPanel() }; /// /// Creates a new instance of the SplitContainer class. @@ -24,34 +25,29 @@ namespace Terminal.Gui { { splitterLine = new SplitContainerLineView (this); - this.Add (Panel1); + this.Add (splitterPanels [0]); this.Add (splitterLine); - this.Add (Panel2); + this.Add (splitterPanels [1]); - Setup (); + LayoutStarted += (e) => Setup (); CanFocus = false; } /// - /// The left or top panel of the - /// (depending on ). Add panel contents - /// to this using . + /// Gets the list of panels. Currently only supports 2 panels. + /// + /// + /// The first item in the list is either the leftmost or topmost panel; + /// the second item is either the rightmost or bottom panel + /// (depending on ) + /// + /// + /// Add panel contents to the s using . + /// + /// /// - public View Panel1 { get; } = new View (); - - /// - /// The minimum size can be when adjusting - /// . - /// - public Pos Panel1MinSize { - get { return panel1MinSize; } - set { - panel1MinSize = value; - Setup (); - } - } - + public List Panels { get { return splitterPanels.ToList(); } } /// /// Invoked when the is changed @@ -66,59 +62,6 @@ namespace Terminal.Gui { SplitterMoved?.Invoke (this, new SplitterEventArgs (this, splitterDistance)); } - - /// - /// This determines if is collapsed. - /// - public bool Panel1Collapsed { - get { return panel1Collapsed; } - set { - panel1Collapsed = value; - if (value && panel2Collapsed) { - panel2Collapsed = false; - } - - Setup (); - } - - } - - /// - /// The right or bottom panel of the - /// (depending on ). Add panel contents - /// to this using - /// - public View Panel2 { get; } = new View (); - - /// - /// The minimum size can be when adjusting - /// . - /// - public Pos Panel2MinSize { - get { - return panel2MinSize; - } - - set { - panel2MinSize = value; - Setup (); - } - } - - /// - /// This determines if is collapsed. - /// - public bool Panel2Collapsed { - get { return panel2Collapsed; } - set { - panel2Collapsed = value; - if (value && panel1Collapsed) { - panel1Collapsed = false; - } - Setup (); - } - } - /// /// Orientation of the dividing line (Horizontal or Vertical). /// @@ -130,7 +73,6 @@ namespace Terminal.Gui { } } - /// /// Distance Horizontally or Vertically to the splitter line when /// neither panel is collapsed. @@ -164,85 +106,103 @@ namespace Terminal.Gui { Driver.SetAttribute (ColorScheme.Normal); Clear (); base.Redraw (bounds); + + // Draw Splitter over Border (to get Ts) + if (splitterLine.Visible) { + splitterLine.Redraw (bounds); + } + + // Draw Titles over Border + var screen = ViewToScreen (bounds); + if (splitterPanels[0].Visible && splitterPanels[0].Title.Length > 0) { + Driver.SetAttribute (splitterPanels[0].HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal); + Driver.DrawWindowTitle (new Rect (screen.X, screen.Y, splitterPanels[0].Frame.Width, 1), splitterPanels[0].Title, 0, 0, 0, 0); + } + if (splitterLine.Visible) { + screen = ViewToScreen (splitterLine.Frame); + } else { + screen.X--; + screen.Y--; + } + if (Orientation == Orientation.Horizontal) { + if (splitterPanels[1].Visible && splitterPanels[1].Title.Length > 0) { + + Driver.SetAttribute (splitterPanels[1].HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal); + Driver.DrawWindowTitle (new Rect (screen.X + 1, screen.Y + 1, splitterPanels[1].Bounds.Width, 1), splitterPanels[1].Title, 0, 0, 0, 0); + } + } else { + if (splitterPanels[1].Visible && splitterPanels[1].Title.Length > 0) { + Driver.SetAttribute (splitterPanels[1].HasFocus ? ColorScheme.HotNormal : ColorScheme.Normal); + Driver.DrawWindowTitle (new Rect (screen.X + 1, screen.Y + 1, splitterPanels[1].Bounds.Width, 1), splitterPanels[1].Title, 0, 0, 0, 0); + } + } } private void Setup () { splitterLine.Orientation = Orientation; + splitterLine.Text = splitterPanels[1].Title; - if (panel1Collapsed || panel2Collapsed) { - SetupForCollapsedPanel (); + if (!splitterPanels[0].Visible || !splitterPanels[1].Visible) { + View toFullSize = !splitterPanels[0].Visible ? splitterPanels[1] : splitterPanels[0]; + + splitterLine.Visible = false; + + toFullSize.X = 0; + toFullSize.Y = 0; + toFullSize.Width = Dim.Fill (); + toFullSize.Height = Dim.Fill (); } else { - SetupForNormal (); + splitterLine.Visible = true; + + splitterDistance = BoundByMinimumSizes (splitterDistance); + + splitterPanels[0].X = 0; + splitterPanels[0].Y = 0; + + splitterPanels[1].Width = Dim.Fill (); + splitterPanels[1].Height = Dim.Fill (); + + switch (Orientation) { + case Orientation.Horizontal: + splitterLine.X = -1; + splitterLine.Y = splitterDistance; + splitterLine.Width = Dim.Fill () + 1; + splitterLine.Height = 1; + splitterLine.LineRune = Driver.HLine; + + splitterPanels[0].Width = Dim.Fill (); + splitterPanels[0].Height = new Dim.DimFunc (() => + splitterDistance.Anchor (Bounds.Height)) - 1; + + splitterPanels[1].Y = Pos.Bottom (splitterLine); + splitterPanels[1].X = 0; + break; + + case Orientation.Vertical: + splitterLine.X = splitterDistance; + splitterLine.Y = -1; + splitterLine.Width = 1; + splitterLine.Height = Dim.Fill () + 1; + splitterLine.LineRune = Driver.VLine; + + splitterPanels[0].Height = Dim.Fill (); + splitterPanels[0].Width = new Dim.DimFunc (() => + splitterDistance.Anchor (Bounds.Width)) - 1; + + splitterPanels[1].X = Pos.Right (splitterLine); + splitterPanels[1].Y = 0; + break; + + default: throw new ArgumentOutOfRangeException (nameof (orientation)); + }; } } - private void SetupForNormal () - { - // Ensure all our component views are here - // (e.g. if we are transitioning from a collapsed state) - - if (!this.Subviews.Contains (splitterLine)) { - this.Add (splitterLine); - } - if (!this.Subviews.Contains (Panel1)) { - this.Add (Panel1); - } - if (!this.Subviews.Contains (Panel2)) { - this.Add (Panel2); - } - - splitterDistance = BoundByMinimumSizes (splitterDistance); - - switch (Orientation) { - case Orientation.Horizontal: - splitterLine.X = 0; - splitterLine.Y = splitterDistance; - splitterLine.Width = Dim.Fill (); - splitterLine.Height = 1; - splitterLine.LineRune = Driver.HLine; - - this.Panel1.X = 0; - this.Panel1.Y = 0; - this.Panel1.Width = Dim.Fill (); - this.Panel1.Height = new Dim.DimFunc (() => - splitterDistance.Anchor (Bounds.Height)); - - this.Panel2.Y = Pos.Bottom (splitterLine); - this.Panel2.X = 0; - this.Panel2.Width = Dim.Fill (); - this.Panel2.Height = Dim.Fill (); - break; - - case Orientation.Vertical: - splitterLine.X = splitterDistance; - splitterLine.Y = 0; - splitterLine.Width = 1; - splitterLine.Height = Dim.Fill (); - splitterLine.LineRune = Driver.VLine; - - this.Panel1.X = 0; - this.Panel1.Y = 0; - this.Panel1.Height = Dim.Fill (); - this.Panel1.Width = new Dim.DimFunc (() => - splitterDistance.Anchor (Bounds.Width)); - - this.Panel2.X = Pos.Right (splitterLine); - this.Panel2.Y = 0; - this.Panel2.Width = Dim.Fill (); - this.Panel2.Height = Dim.Fill (); - break; - - default: throw new ArgumentOutOfRangeException (nameof (orientation)); - }; - - this.LayoutSubviews (); - } - /// /// Considers as a candidate for - /// then either returns (if valid) or returns adjusted if invalid with respect to - /// or . + /// then either returns (if valid) or returns adjusted if invalid with respect to the + /// of the panels. /// /// /// @@ -258,48 +218,70 @@ namespace Terminal.Gui { var availableSpace = Orientation == Orientation.Horizontal ? this.Bounds.Height : this.Bounds.Width; var idealPosition = pos.Anchor (availableSpace); - var panel1MinSizeAbs = panel1MinSize.Anchor (availableSpace); - var panel2MinSizeAbs = panel2MinSize.Anchor (availableSpace); - // bad position because not enough space for panel1 - if (idealPosition < panel1MinSizeAbs) { + // bad position because not enough space for splitterPanels[0] + if (idealPosition < splitterPanels [0].MinSize.Anchor (availableSpace)) { // TODO: we should preserve Absolute/Percent status here not just force it to absolute - return (Pos)Math.Min (panel1MinSizeAbs, availableSpace); + return (Pos)Math.Min (splitterPanels [0].MinSize.Anchor (availableSpace), availableSpace); } - // bad position because not enough space for panel2 - if (availableSpace - idealPosition <= panel2MinSizeAbs) { + // bad position because not enough space for splitterPanels[1] + if (availableSpace - idealPosition <= splitterPanels [1].MinSize.Anchor (availableSpace)) { // 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 - (panel2MinSizeAbs + 1), 0); + return (Pos)Math.Max (availableSpace - (splitterPanels [1].MinSize.Anchor (availableSpace) + 1), 0); } // this splitter position is fine, there is enough space for everyone return pos; } - private void SetupForCollapsedPanel () - { - View toRemove = panel1Collapsed ? Panel1 : Panel2; - View toFullSize = panel1Collapsed ? Panel2 : Panel1; + /// + /// A panel within a . + /// + public class SplitterPanel : View { + Pos minSize = 2; - if (this.Subviews.Contains (splitterLine)) { - this.Remove (splitterLine); - } - if (this.Subviews.Contains (toRemove)) { - this.Remove (toRemove); - } - if (!this.Subviews.Contains (toFullSize)) { - this.Add (toFullSize); + /// + /// Gets or sets the minimum size for the panel. + /// + public Pos MinSize { get => minSize; + set { + minSize = value; + SuperView?.SetNeedsLayout (); + } } - toFullSize.X = 0; - toFullSize.Y = 0; - toFullSize.Width = Dim.Fill (); - toFullSize.Height = Dim.Fill (); + ustring title = ustring.Empty; + /// + /// The title to be displayed for this . The title will be rendered + /// on the top border aligned to the left of the panel. + /// + /// The title. + public ustring Title { + get => title; + set { + title = value; + SetNeedsDisplay (); + } + } + + /// + public override void Redraw (Rect bounds) + { + Driver.SetAttribute (ColorScheme.Normal); + base.Redraw (bounds); + } + + /// + public override void OnVisibleChanged () + { + base.OnVisibleChanged (); + SuperView?.SetNeedsLayout (); + } } private class SplitContainerLineView : LineView { @@ -309,7 +291,6 @@ namespace Terminal.Gui { Pos dragOrignalPos; Point? moveRuneRenderLocation; - // TODO: Make focusable and allow moving with keyboard public SplitContainerLineView (SplitContainer parent) { CanFocus = true; @@ -337,10 +318,19 @@ namespace Terminal.Gui { AddKeyBinding (Key.CursorLeft, Command.Left); AddKeyBinding (Key.CursorUp, Command.LineUp); AddKeyBinding (Key.CursorDown, Command.LineDown); + + LayoutStarted += (e) => { + moveRuneRenderLocation = null; + if (Orientation == Orientation.Horizontal) { + StartingAnchor = Driver.LeftTee; + EndingAnchor = Driver.RightTee; + } else { + StartingAnchor = Driver.TopTee; + EndingAnchor = Driver.BottomTee; + } + }; } - - /// public override bool ProcessKey (KeyEvent kb) { if (!CanFocus || !HasFocus) { @@ -353,10 +343,13 @@ namespace Terminal.Gui { return base.ProcessKey (kb); } + public override void PositionCursor () { base.PositionCursor (); - Move (this.Bounds.Width / 2, this.Bounds.Height / 2); + var location = moveRuneRenderLocation ?? + new Point (Bounds.Width / 2, Bounds.Height / 2); + Move (location.X, location.Y); } public override bool OnEnter (View view) @@ -366,21 +359,19 @@ namespace Terminal.Gui { return base.OnEnter (view); } + public override void Redraw (Rect bounds) { base.Redraw (bounds); if (CanFocus && HasFocus) { - var location = moveRuneRenderLocation ?? new Point (Bounds.Width / 2, Bounds.Height / 2); AddRune (location.X, location.Y, Driver.Diamond); } - } - /// public override bool MouseEvent (MouseEvent mouseEvent) { if (!CanFocus) { @@ -397,6 +388,12 @@ namespace Terminal.Gui { dragPosition = new Point (mouseEvent.X, mouseEvent.Y); dragOrignalPos = Orientation == Orientation.Horizontal ? Y : X; Application.GrabMouse (this); + + if (Orientation == Orientation.Horizontal) { + + } else { + moveRuneRenderLocation = new Point (0, Math.Max (1, Math.Min (Bounds.Height - 2, mouseEvent.Y))); + } } return true; @@ -414,7 +411,7 @@ namespace Terminal.Gui { } else { int dx = mouseEvent.X - dragPosition.Value.X; parent.SplitterDistance = Offset (X, dx); - moveRuneRenderLocation = new Point (0, mouseEvent.Y); + moveRuneRenderLocation = new Point (0, Math.Max (1, Math.Min (Bounds.Height - 2, mouseEvent.Y))); } parent.SetNeedsDisplay (); @@ -431,11 +428,12 @@ namespace Terminal.Gui { dragOrignalPos, Orientation == Orientation.Horizontal ? Y : X); dragPosition = null; - moveRuneRenderLocation = null; + //moveRuneRenderLocation = null; } return false; } + private bool MoveSplitter (int distanceX, int distanceY) { if (Orientation == Orientation.Vertical) { @@ -461,7 +459,6 @@ namespace Terminal.Gui { } } - private Pos Offset (Pos pos, int delta) { var posAbsolute = pos.Anchor (Orientation == Orientation.Horizontal ? diff --git a/UICatalog/Scenarios/SplitContainerExample.cs b/UICatalog/Scenarios/SplitContainerExample.cs index 474adef44..a32d22e8c 100644 --- a/UICatalog/Scenarios/SplitContainerExample.cs +++ b/UICatalog/Scenarios/SplitContainerExample.cs @@ -5,54 +5,51 @@ using Terminal.Gui.Graphs; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Split Container", Description: "Demonstrates the SplitContainer functionality")] [ScenarioCategory ("Controls")] + [ScenarioCategory ("LineView")] public class SplitContainerExample : Scenario { private SplitContainer splitContainer; - - private MenuItem miVertical; private MenuItem miShowBoth; private MenuItem miShowPanel1; private MenuItem miShowPanel2; + private MenuItem miShowNeither; /// /// Setup the scenario. /// public override void Setup () { - // Scenario Window's. + // Scenario Windows. Win.Title = this.GetName (); Win.Y = 1; - Win.Add (new Label ("This is a SplitContainer with a minimum panel size of 2. Drag the splitter to resize:")); - Win.Add (new LineView (Orientation.Horizontal) { Y = 1 }); + Win.Add (new Label ("This is a SplitContainer with a minimum panel size of 4. Drag the splitter to resize:")); splitContainer = new SplitContainer { Y = 2, - Width = Dim.Fill (), - Height = Dim.Fill (), + X = 2, + Width = Dim.Fill () - 2, + Height = Dim.Fill () - 1, SplitterDistance = Pos.Percent (50), // TODO: get this to work with drag resizing and percents - Panel1MinSize = 2, - Panel2MinSize = 2, }; - + splitContainer.Panels [0].MinSize = 4; + splitContainer.Panels [1].MinSize = 4; Label lbl1; - splitContainer.Panel1.Add (new Label ("Hello")); - splitContainer.Panel1.Add (lbl1 = new Label ("Type Something:"){Y=2}); - splitContainer.Panel1.Add (new TextField (){Width = Dim.Fill(),Y=2,X=Pos.Right(lbl1)+1}); - - Label lbl2; - splitContainer.Panel2.Add (new Label ("World")); - splitContainer.Panel2.Add (lbl2 = new Label ("Type Here Too:"){Y=2}); - splitContainer.Panel2.Add (new TextField (){Width = Dim.Fill(),Y=2,X=Pos.Right(lbl2)+1}); - splitContainer.Panel2.Add (new Label ("Here is a Text box:") { Y = 4 }); - splitContainer.Panel2.Add (new TextView () { Y = 5, Width = Dim.Fill(), Height = Dim.Fill(), AllowsTab = false}); + splitContainer.Panels [0].Title = "Hello"; + splitContainer.Panels [0].Add (lbl1 = new Label ("Type Something:") { Y = 1 }); + splitContainer.Panels [0].Add (new TextField () { Width = Dim.Fill (), Y = 1, X = Pos.Right (lbl1) + 1 }); + Label lbl2; + splitContainer.Panels [1].Title = "World"; + splitContainer.Panels [1].Add (lbl2 = new Label ("Type Here Too:") { Y = 1 }); + splitContainer.Panels [1].Add (new TextField () { Width = Dim.Fill (), Y = 1, X = Pos.Right (lbl2) + 1 }); + splitContainer.Panels [1].Add (new Label ("Here is a Text box:") { Y = 3 }); + splitContainer.Panels [1].Add (new TextView () { Y = 4, Width = Dim.Fill (), Height = Dim.Fill (), AllowsTab = false }); Win.Add (splitContainer); - var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { new MenuItem ("_Quit", "", () => Quit()), @@ -65,46 +62,53 @@ namespace UICatalog.Scenarios { }, new MenuBarItem ("_Show", new MenuItem [] { miShowBoth = new MenuItem ("Both", "",()=>{ - splitContainer.Panel1Collapsed = false; - splitContainer.Panel2Collapsed = false; + splitContainer.Panels [0].Visible = true; + splitContainer.Panels [1].Visible = true; UpdateShowMenuCheckedStates(); }), - miShowPanel1 = new MenuItem ("Panel1", "", () => { - - splitContainer.Panel2Collapsed = true; + miShowPanel1 = new MenuItem ("Panel 1", "", () => { + splitContainer.Panels [0].Visible = true; + splitContainer.Panels [1].Visible = false; UpdateShowMenuCheckedStates(); }), - miShowPanel2 = new MenuItem ("Panel2", "", () => { - splitContainer.Panel1Collapsed = true; + miShowPanel2 = new MenuItem ("Panel 2", "", () => { + splitContainer.Panels [0].Visible = false; + splitContainer.Panels [1].Visible = true; UpdateShowMenuCheckedStates(); - }), + }), + miShowNeither = new MenuItem ("Neither", "",()=>{ + splitContainer.Panels [0].Visible = false; + splitContainer.Panels [1].Visible = false; + UpdateShowMenuCheckedStates(); + }), }) }), - - }) ; + }); UpdateShowMenuCheckedStates (); - + Application.Top.Add (menu); } private void UpdateShowMenuCheckedStates () { - miShowBoth.Checked = (!splitContainer.Panel1Collapsed) && (!splitContainer.Panel2Collapsed); + miShowBoth.Checked = (splitContainer.Panels [0].Visible) && (splitContainer.Panels [1].Visible); miShowBoth.CheckType = MenuItemCheckStyle.Checked; - miShowPanel1.Checked = splitContainer.Panel2Collapsed; + miShowPanel1.Checked = splitContainer.Panels [0].Visible && !splitContainer.Panels [1].Visible; miShowPanel1.CheckType = MenuItemCheckStyle.Checked; - miShowPanel2.Checked = splitContainer.Panel1Collapsed; + miShowPanel2.Checked = !splitContainer.Panels [0].Visible && splitContainer.Panels [1].Visible; miShowPanel2.CheckType = MenuItemCheckStyle.Checked; + + miShowNeither.Checked = (!splitContainer.Panels [0].Visible) && (!splitContainer.Panels [1].Visible); + miShowNeither.CheckType = MenuItemCheckStyle.Checked; } - public void ToggleOrientation() + public void ToggleOrientation () { - miVertical.Checked = !miVertical.Checked; - splitContainer.Orientation = miVertical.Checked ? Orientation.Vertical : Orientation.Horizontal; + splitContainer.Orientation = miVertical.Checked ? Orientation.Vertical : Orientation.Horizontal; } private void Quit () diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 3637c0d34..2fd44ebbf 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -151,8 +151,7 @@ namespace UICatalog { public MenuItem miIsMouseDisabled; public MenuItem miHeightAsBuffer; - public FrameView ContentPane; - public SplitContainer SplitContainer; + public SplitContainer ContentPane; public ListView CategoryListView; public ListView ScenarioListView; @@ -208,23 +207,17 @@ namespace UICatalog { DriverName, }; - ContentPane = new FrameView ("Categories") { + ContentPane = new SplitContainer () { X = 0, Y = 1, // for menu Width = Dim.Fill (), Height = Dim.Fill (1), CanFocus = true, - Shortcut = Key.CtrlMask | Key.C - }; - - ContentPane.ShortcutAction = () => ContentPane.SetFocus (); - - SplitContainer = new SplitContainer { - Width = Dim.Fill (0), - Height = Dim.Fill (0), + Shortcut = Key.CtrlMask | Key.C, SplitterDistance = 25 }; - + ContentPane.ShortcutAction = () => ContentPane.SetFocus (); + CategoryListView = new ListView (_categories) { X = 0, Y = 0, @@ -237,16 +230,9 @@ namespace UICatalog { ScenarioListView.SetFocus (); }; CategoryListView.SelectedItemChanged += CategoryListView_SelectedChanged; - ContentPane.Add (SplitContainer); - - SplitContainer.Panel1.Add (CategoryListView); - - SetTitlePaddingToAlignScenariosHeader (); - - SplitContainer.SplitterMoved += (s, e) => { - SetTitlePaddingToAlignScenariosHeader (); - }; + ContentPane.Panels [0].Title = "Categories"; + ContentPane.Panels [0].Add (CategoryListView); ScenarioListView = new ListView () { X = 0, @@ -258,11 +244,14 @@ namespace UICatalog { }; ScenarioListView.OpenSelectedItem += ScenarioListView_OpenSelectedItem; - SplitContainer.Panel2.Add (ScenarioListView); + + ContentPane.Panels [1].Title = "Scenarios"; + ContentPane.Panels [1].Add (ScenarioListView); KeyDown += KeyDownHandler; Add (MenuBar); Add (ContentPane); + Add (StatusBar); Loaded += LoadedHandler; @@ -271,22 +260,7 @@ namespace UICatalog { CategoryListView.SelectedItem = _cachedCategoryIndex; ScenarioListView.SelectedItem = _cachedScenarioIndex; } - - private void SetTitlePaddingToAlignScenariosHeader () - { - // Pos.Anchor is internal so we have to use reflection to access it - var anchor = typeof (Pos).GetMethod ("Anchor", BindingFlags.Instance | BindingFlags.NonPublic); - var splitterWidth = (int)anchor.Invoke ( - SplitContainer.SplitterDistance, new object [] { SplitContainer.Bounds.Width} - ); - - var newTitle = $"Categories ({ContentPane.ShortcutTag})"; - newTitle = newTitle.PadRight (splitterWidth + 1, (char)Driver.HLine); - newTitle += "Scenarios"; - - ContentPane.Title = newTitle; - } - + void LoadedHandler () { Application.HeightAsBuffer = _heightAsBuffer;