|
@@ -1,5 +1,4 @@
|
|
-using System.Diagnostics;
|
|
|
|
-
|
|
|
|
|
|
+#nullable enable
|
|
namespace Terminal.Gui;
|
|
namespace Terminal.Gui;
|
|
|
|
|
|
/// <summary>Control that hosts multiple sub views, presenting a single one at once.</summary>
|
|
/// <summary>Control that hosts multiple sub views, presenting a single one at once.</summary>
|
|
@@ -19,8 +18,8 @@ public class TabView : View
|
|
/// <summary>This sub view is the 2 or 3 line control that represents the actual tabs themselves.</summary>
|
|
/// <summary>This sub view is the 2 or 3 line control that represents the actual tabs themselves.</summary>
|
|
private readonly TabRowView _tabsBar;
|
|
private readonly TabRowView _tabsBar;
|
|
|
|
|
|
- private Tab _selectedTab;
|
|
|
|
- private TabToRender [] _tabLocations;
|
|
|
|
|
|
+ private Tab? _selectedTab;
|
|
|
|
+ private TabToRender []? _tabLocations;
|
|
private int _tabScrollOffset;
|
|
private int _tabScrollOffset;
|
|
|
|
|
|
/// <summary>Initializes a <see cref="TabView"/> class.</summary>
|
|
/// <summary>Initializes a <see cref="TabView"/> class.</summary>
|
|
@@ -48,7 +47,7 @@ public class TabView : View
|
|
() =>
|
|
() =>
|
|
{
|
|
{
|
|
TabScrollOffset = 0;
|
|
TabScrollOffset = 0;
|
|
- SelectedTab = Tabs.FirstOrDefault ();
|
|
|
|
|
|
+ SelectedTab = Tabs.FirstOrDefault ()!;
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -59,7 +58,7 @@ public class TabView : View
|
|
() =>
|
|
() =>
|
|
{
|
|
{
|
|
TabScrollOffset = Tabs.Count - 1;
|
|
TabScrollOffset = Tabs.Count - 1;
|
|
- SelectedTab = Tabs.LastOrDefault ();
|
|
|
|
|
|
+ SelectedTab = Tabs.LastOrDefault()!;
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -69,7 +68,7 @@ public class TabView : View
|
|
Command.PageDown,
|
|
Command.PageDown,
|
|
() =>
|
|
() =>
|
|
{
|
|
{
|
|
- TabScrollOffset += _tabLocations.Length;
|
|
|
|
|
|
+ TabScrollOffset += _tabLocations!.Length;
|
|
SelectedTab = Tabs.ElementAt (TabScrollOffset);
|
|
SelectedTab = Tabs.ElementAt (TabScrollOffset);
|
|
|
|
|
|
return true;
|
|
return true;
|
|
@@ -80,7 +79,7 @@ public class TabView : View
|
|
Command.PageUp,
|
|
Command.PageUp,
|
|
() =>
|
|
() =>
|
|
{
|
|
{
|
|
- TabScrollOffset -= _tabLocations.Length;
|
|
|
|
|
|
+ TabScrollOffset -= _tabLocations!.Length;
|
|
SelectedTab = Tabs.ElementAt (TabScrollOffset);
|
|
SelectedTab = Tabs.ElementAt (TabScrollOffset);
|
|
|
|
|
|
return true;
|
|
return true;
|
|
@@ -104,20 +103,20 @@ public class TabView : View
|
|
|
|
|
|
/// <summary>The currently selected member of <see cref="Tabs"/> chosen by the user.</summary>
|
|
/// <summary>The currently selected member of <see cref="Tabs"/> chosen by the user.</summary>
|
|
/// <value></value>
|
|
/// <value></value>
|
|
- public Tab SelectedTab
|
|
|
|
|
|
+ public Tab? SelectedTab
|
|
{
|
|
{
|
|
get => _selectedTab;
|
|
get => _selectedTab;
|
|
set
|
|
set
|
|
{
|
|
{
|
|
UnSetCurrentTabs ();
|
|
UnSetCurrentTabs ();
|
|
|
|
|
|
- Tab old = _selectedTab;
|
|
|
|
|
|
+ Tab? old = _selectedTab;
|
|
|
|
|
|
if (_selectedTab is { })
|
|
if (_selectedTab is { })
|
|
{
|
|
{
|
|
if (_selectedTab.View is { })
|
|
if (_selectedTab.View is { })
|
|
{
|
|
{
|
|
- _selectedTab.View.CanFocusChanged -= ContentViewCanFocus;
|
|
|
|
|
|
+ _selectedTab.View.CanFocusChanged -= ContentViewCanFocus!;
|
|
// remove old content
|
|
// remove old content
|
|
_contentView.Remove (_selectedTab.View);
|
|
_contentView.Remove (_selectedTab.View);
|
|
}
|
|
}
|
|
@@ -125,29 +124,26 @@ public class TabView : View
|
|
|
|
|
|
_selectedTab = value;
|
|
_selectedTab = value;
|
|
|
|
|
|
- if (value is { })
|
|
|
|
|
|
+ // add new content
|
|
|
|
+ if (_selectedTab?.View != null)
|
|
{
|
|
{
|
|
- // add new content
|
|
|
|
- if (_selectedTab.View is { })
|
|
|
|
- {
|
|
|
|
- _selectedTab.View.CanFocusChanged += ContentViewCanFocus;
|
|
|
|
- _contentView.Add (_selectedTab.View);
|
|
|
|
- // _contentView.Id = $"_contentView for {_selectedTab.DisplayText}";
|
|
|
|
- }
|
|
|
|
|
|
+ _selectedTab.View.CanFocusChanged += ContentViewCanFocus!;
|
|
|
|
+ _contentView.Add (_selectedTab.View);
|
|
|
|
+ // _contentView.Id = $"_contentView for {_selectedTab.DisplayText}";
|
|
}
|
|
}
|
|
|
|
|
|
- ContentViewCanFocus (null, null);
|
|
|
|
|
|
+ ContentViewCanFocus (null!, null!);
|
|
|
|
|
|
EnsureSelectedTabIsVisible ();
|
|
EnsureSelectedTabIsVisible ();
|
|
|
|
|
|
- if (old != value)
|
|
|
|
|
|
+ if (old != _selectedTab)
|
|
{
|
|
{
|
|
if (old?.HasFocus == true)
|
|
if (old?.HasFocus == true)
|
|
{
|
|
{
|
|
SelectedTab?.SetFocus ();
|
|
SelectedTab?.SetFocus ();
|
|
}
|
|
}
|
|
|
|
|
|
- OnSelectedTabChanged (old, value);
|
|
|
|
|
|
+ OnSelectedTabChanged (old!, _selectedTab!);
|
|
}
|
|
}
|
|
SetNeedsLayout ();
|
|
SetNeedsLayout ();
|
|
}
|
|
}
|
|
@@ -297,7 +293,7 @@ public class TabView : View
|
|
public int EnsureValidScrollOffsets (int value) { return Math.Max (Math.Min (value, Tabs.Count - 1), 0); }
|
|
public int EnsureValidScrollOffsets (int value) { return Math.Max (Math.Min (value, Tabs.Count - 1), 0); }
|
|
|
|
|
|
/// <inheritdoc />
|
|
/// <inheritdoc />
|
|
- protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View focusedView)
|
|
|
|
|
|
+ protected override void OnHasFocusChanged (bool newHasFocus, View? previousFocusedView, View? focusedView)
|
|
{
|
|
{
|
|
if (SelectedTab is { } && !_contentView.CanFocus && focusedView == this)
|
|
if (SelectedTab is { } && !_contentView.CanFocus && focusedView == this)
|
|
{
|
|
{
|
|
@@ -333,7 +329,7 @@ public class TabView : View
|
|
/// tab's hosted <see cref="Tab.View"/> if appropriate.
|
|
/// tab's hosted <see cref="Tab.View"/> if appropriate.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="tab"></param>
|
|
/// <param name="tab"></param>
|
|
- public void RemoveTab (Tab tab)
|
|
|
|
|
|
+ public void RemoveTab (Tab? tab)
|
|
{
|
|
{
|
|
if (tab is null || !_tabs.Contains (tab))
|
|
if (tab is null || !_tabs.Contains (tab))
|
|
{
|
|
{
|
|
@@ -366,7 +362,7 @@ public class TabView : View
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Event for when <see cref="SelectedTab"/> changes.</summary>
|
|
/// <summary>Event for when <see cref="SelectedTab"/> changes.</summary>
|
|
- public event EventHandler<TabChangedEventArgs> SelectedTabChanged;
|
|
|
|
|
|
+ public event EventHandler<TabChangedEventArgs>? SelectedTabChanged;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Changes the <see cref="SelectedTab"/> by the given <paramref name="amount"/>. Positive for right, negative for
|
|
/// Changes the <see cref="SelectedTab"/> by the given <paramref name="amount"/>. Positive for right, negative for
|
|
@@ -415,7 +411,7 @@ public class TabView : View
|
|
/// Event fired when a <see cref="Tab"/> is clicked. Can be used to cancel navigation, show context menu (e.g. on
|
|
/// Event fired when a <see cref="Tab"/> is clicked. Can be used to cancel navigation, show context menu (e.g. on
|
|
/// right click) etc.
|
|
/// right click) etc.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public event EventHandler<TabMouseEventArgs> TabClicked;
|
|
|
|
|
|
+ public event EventHandler<TabMouseEventArgs>? TabClicked;
|
|
|
|
|
|
/// <summary>Disposes the control and all <see cref="Tabs"/>.</summary>
|
|
/// <summary>Disposes the control and all <see cref="Tabs"/>.</summary>
|
|
/// <param name="disposing"></param>
|
|
/// <param name="disposing"></param>
|
|
@@ -448,7 +444,7 @@ public class TabView : View
|
|
UnSetCurrentTabs ();
|
|
UnSetCurrentTabs ();
|
|
|
|
|
|
var i = 1;
|
|
var i = 1;
|
|
- View prevTab = null;
|
|
|
|
|
|
+ View? prevTab = null;
|
|
|
|
|
|
// Starting at the first or scrolled to tab
|
|
// Starting at the first or scrolled to tab
|
|
foreach (Tab tab in Tabs.Skip (TabScrollOffset))
|
|
foreach (Tab tab in Tabs.Skip (TabScrollOffset))
|
|
@@ -483,9 +479,9 @@ public class TabView : View
|
|
if (maxWidth == 0)
|
|
if (maxWidth == 0)
|
|
{
|
|
{
|
|
tab.Visible = true;
|
|
tab.Visible = true;
|
|
- tab.MouseClick += Tab_MouseClick;
|
|
|
|
|
|
+ tab.MouseClick += Tab_MouseClick!;
|
|
|
|
|
|
- yield return new TabToRender (i, tab, string.Empty, Equals (SelectedTab, tab), 0);
|
|
|
|
|
|
+ yield return new TabToRender (tab, string.Empty, Equals (SelectedTab, tab));
|
|
|
|
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -509,9 +505,9 @@ public class TabView : View
|
|
|
|
|
|
// there is enough space!
|
|
// there is enough space!
|
|
tab.Visible = true;
|
|
tab.Visible = true;
|
|
- tab.MouseClick += Tab_MouseClick;
|
|
|
|
|
|
+ tab.MouseClick += Tab_MouseClick!;
|
|
|
|
|
|
- yield return new TabToRender (i, tab, text, Equals (SelectedTab, tab), tabTextWidth);
|
|
|
|
|
|
+ yield return new TabToRender (tab, text, Equals (SelectedTab, tab));
|
|
|
|
|
|
i += tabTextWidth + 1;
|
|
i += tabTextWidth + 1;
|
|
}
|
|
}
|
|
@@ -550,7 +546,7 @@ public class TabView : View
|
|
{
|
|
{
|
|
foreach (TabToRender tabToRender in _tabLocations)
|
|
foreach (TabToRender tabToRender in _tabLocations)
|
|
{
|
|
{
|
|
- tabToRender.Tab.MouseClick -= Tab_MouseClick;
|
|
|
|
|
|
+ tabToRender.Tab.MouseClick -= Tab_MouseClick!;
|
|
tabToRender.Tab.Visible = false;
|
|
tabToRender.Tab.Visible = false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -585,7 +581,7 @@ public class TabView : View
|
|
Visible = false,
|
|
Visible = false,
|
|
Text = Glyphs.RightArrow.ToString ()
|
|
Text = Glyphs.RightArrow.ToString ()
|
|
};
|
|
};
|
|
- _rightScrollIndicator.MouseClick += _host.Tab_MouseClick;
|
|
|
|
|
|
+ _rightScrollIndicator.MouseClick += _host.Tab_MouseClick!;
|
|
|
|
|
|
_leftScrollIndicator = new View
|
|
_leftScrollIndicator = new View
|
|
{
|
|
{
|
|
@@ -595,14 +591,14 @@ public class TabView : View
|
|
Visible = false,
|
|
Visible = false,
|
|
Text = Glyphs.LeftArrow.ToString ()
|
|
Text = Glyphs.LeftArrow.ToString ()
|
|
};
|
|
};
|
|
- _leftScrollIndicator.MouseClick += _host.Tab_MouseClick;
|
|
|
|
|
|
+ _leftScrollIndicator.MouseClick += _host.Tab_MouseClick!;
|
|
|
|
|
|
Add (_rightScrollIndicator, _leftScrollIndicator);
|
|
Add (_rightScrollIndicator, _leftScrollIndicator);
|
|
}
|
|
}
|
|
|
|
|
|
protected override bool OnMouseEvent (MouseEventArgs me)
|
|
protected override bool OnMouseEvent (MouseEventArgs me)
|
|
{
|
|
{
|
|
- Tab hit = me.View is Tab ? (Tab)me.View : null;
|
|
|
|
|
|
+ Tab? hit = me.View as Tab;
|
|
|
|
|
|
if (me.IsSingleClicked)
|
|
if (me.IsSingleClicked)
|
|
{
|
|
{
|
|
@@ -1235,9 +1231,14 @@ public class TabView : View
|
|
/// <summary>Renders the line with the tab names in it.</summary>
|
|
/// <summary>Renders the line with the tab names in it.</summary>
|
|
private void RenderTabLine ()
|
|
private void RenderTabLine ()
|
|
{
|
|
{
|
|
- TabToRender [] tabLocations = _host._tabLocations;
|
|
|
|
|
|
+ TabToRender []? tabLocations = _host._tabLocations;
|
|
|
|
+
|
|
|
|
+ if (tabLocations is null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- View selected = null;
|
|
|
|
|
|
+ View? selected = null;
|
|
int topLine = _host.Style.ShowTopLine ? 1 : 0;
|
|
int topLine = _host.Style.ShowTopLine ? 1 : 0;
|
|
|
|
|
|
foreach (TabToRender toRender in tabLocations)
|
|
foreach (TabToRender toRender in tabLocations)
|
|
@@ -1272,7 +1273,7 @@ public class TabView : View
|
|
tab.Margin.Thickness = new Thickness (0, 0, 0, 0);
|
|
tab.Margin.Thickness = new Thickness (0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- tab.Width = Math.Max (tab.Width.GetAnchor (0) - 1, 1);
|
|
|
|
|
|
+ tab.Width = Math.Max (tab.Width!.GetAnchor (0) - 1, 1);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
@@ -1287,7 +1288,7 @@ public class TabView : View
|
|
tab.Margin.Thickness = new Thickness (0, 0, 0, 0);
|
|
tab.Margin.Thickness = new Thickness (0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- tab.Width = Math.Max (tab.Width.GetAnchor (0) - 1, 1);
|
|
|
|
|
|
+ tab.Width = Math.Max (tab.Width!.GetAnchor (0) - 1, 1);
|
|
}
|
|
}
|
|
|
|
|
|
tab.Text = toRender.TextToRender;
|
|
tab.Text = toRender.TextToRender;
|
|
@@ -1332,7 +1333,7 @@ public class TabView : View
|
|
{
|
|
{
|
|
int y = GetUnderlineYPosition ();
|
|
int y = GetUnderlineYPosition ();
|
|
|
|
|
|
- TabToRender selected = _host._tabLocations.FirstOrDefault (t => t.IsSelected);
|
|
|
|
|
|
+ TabToRender? selected = _host._tabLocations?.FirstOrDefault (t => t.IsSelected);
|
|
|
|
|
|
if (selected is null)
|
|
if (selected is null)
|
|
{
|
|
{
|
|
@@ -1378,17 +1379,15 @@ public class TabView : View
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private bool ShouldDrawRightScrollIndicator () { return _host._tabLocations.LastOrDefault ()?.Tab != _host.Tabs.LastOrDefault (); }
|
|
|
|
|
|
+ private bool ShouldDrawRightScrollIndicator () { return _host._tabLocations!.LastOrDefault ()?.Tab != _host.Tabs.LastOrDefault (); }
|
|
}
|
|
}
|
|
|
|
|
|
private class TabToRender
|
|
private class TabToRender
|
|
{
|
|
{
|
|
- public TabToRender (int x, Tab tab, string textToRender, bool isSelected, int width)
|
|
|
|
|
|
+ public TabToRender (Tab tab, string textToRender, bool isSelected)
|
|
{
|
|
{
|
|
- X = x;
|
|
|
|
Tab = tab;
|
|
Tab = tab;
|
|
IsSelected = isSelected;
|
|
IsSelected = isSelected;
|
|
- Width = width;
|
|
|
|
TextToRender = textToRender;
|
|
TextToRender = textToRender;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1398,7 +1397,5 @@ public class TabView : View
|
|
|
|
|
|
public Tab Tab { get; }
|
|
public Tab Tab { get; }
|
|
public string TextToRender { get; }
|
|
public string TextToRender { get; }
|
|
- public int Width { get; }
|
|
|
|
- public int X { get; set; }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|