namespace Terminal.Gui;
///
/// Provides a horizontally or vertically oriented container for s to be used as a menu, toolbar, or status
/// bar.
///
///
///
/// Any can be added to a . However, the is designed to work with
/// objects. The class provides a way to display a command, help, and key and
/// align them in a specific order.
///
///
public class Bar : View
{
///
public Bar () : this ([]) { }
///
public Bar (IEnumerable shortcuts)
{
CanFocus = true;
Width = Dim.Auto ();
Height = Dim.Auto ();
Initialized += Bar_Initialized;
if (shortcuts is null)
{
return;
}
foreach (Shortcut shortcut in shortcuts)
{
Add (shortcut);
}
}
private void Bar_Initialized (object sender, EventArgs e) { ColorScheme = Colors.ColorSchemes ["Menu"]; }
///
public override void SetBorderStyle (LineStyle value)
{
// The default changes the thickness. We don't want that. We just set the style.
Border.LineStyle = value;
}
private Orientation _orientation = Orientation.Horizontal;
///
/// Gets or sets the for this . The default is
/// .
///
///
///
/// Horizontal orientation arranges the command, help, and key parts of each s from right to left
/// Vertical orientation arranges the command, help, and key parts of each s from left to right.
///
///
public Orientation Orientation
{
get => _orientation;
set
{
_orientation = value;
SetNeedsLayout ();
}
}
private AlignmentModes _alignmentModes = AlignmentModes.StartToEnd;
///
/// Gets or sets the for this . The default is
/// .
///
public AlignmentModes AlignmentModes
{
get => _alignmentModes;
set
{
_alignmentModes = value;
SetNeedsLayout ();
}
}
// TODO: Move this to View
/// Inserts a in the specified index of .
/// The zero-based index at which item should be inserted.
/// The item to insert.
public void AddShortcutAt (int index, Shortcut item)
{
List savedSubViewList = Subviews.ToList ();
int count = savedSubViewList.Count;
RemoveAll ();
for (var i = 0; i <= count; i++)
{
if (i == index)
{
Add (item);
}
if (i < count)
{
Add (savedSubViewList [i]);
}
}
SetNeedsDisplay ();
}
// TODO: Move this to View
/// Removes a at specified index of .
/// The zero-based index of the item to remove.
/// The removed.
public Shortcut RemoveShortcut (int index)
{
View toRemove = null;
for (var i = 0; i < Subviews.Count; i++)
{
if (i == index)
{
toRemove = Subviews [i];
}
}
if (toRemove is { })
{
Remove (toRemove);
SetNeedsDisplay ();
}
return toRemove as Shortcut;
}
///
internal override void OnLayoutStarted (LayoutEventArgs args)
{
base.OnLayoutStarted (args);
View prevBarItem = null;
switch (Orientation)
{
case Orientation.Horizontal:
for (var index = 0; index < Subviews.Count; index++)
{
View barItem = Subviews [index];
barItem.ColorScheme = ColorScheme;
barItem.X = Pos.Align (Alignment.Start, AlignmentModes);
barItem.Y = 0; //Pos.Center ();
// HACK: This should not be needed
barItem.SetRelativeLayout (GetContentSize ());
}
break;
case Orientation.Vertical:
// Set the overall size of the Bar and arrange the views vertically
var minKeyWidth = 0;
List shortcuts = Subviews.Where (s => s is Shortcut && s.Visible).Cast ().ToList ();
foreach (Shortcut shortcut in shortcuts)
{
// Let DimAuto do its thing to get the minimum width of each CommandView and HelpView
//shortcut.CommandView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
minKeyWidth = int.Max (minKeyWidth, shortcut.KeyView.Text.GetColumns ());
}
var maxBarItemWidth = 0;
var totalHeight = 0;
for (var index = 0; index < Subviews.Count; index++)
{
View barItem = Subviews [index];
barItem.ColorScheme = ColorScheme;
if (!barItem.Visible)
{
continue;
}
if (barItem is Shortcut scBarItem)
{
scBarItem.MinimumKeyTextSize = minKeyWidth;
// HACK: This should not be needed
scBarItem.SetRelativeLayout (GetContentSize ());
maxBarItemWidth = Math.Max (maxBarItemWidth, scBarItem.Frame.Width);
}
if (prevBarItem == null)
{
barItem.Y = 0;
}
else
{
// Align the view to the bottom of the previous view
barItem.Y = Pos.Bottom (prevBarItem);
}
prevBarItem = barItem;
barItem.X = 0;
totalHeight += barItem.Frame.Height;
}
foreach (View barItem in Subviews)
{
barItem.Width = maxBarItemWidth;
if (barItem is Line line)
{
}
}
Height = Dim.Auto (DimAutoStyle.Content, totalHeight);
break;
}
}
}