mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Added horizontal scenario stuff
This commit is contained in:
@@ -1,14 +1,17 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
namespace Terminal.Gui;
|
namespace Terminal.Gui;
|
||||||
|
|
||||||
|
#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides context for a <see cref="Command"/> that is being invoked.
|
/// Provides context for a <see cref="Command"/> that is being invoked.
|
||||||
/// </summary
|
/// </summary
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// To define a <see cref="Command"/> that is invoked with context,
|
/// To define a <see cref="Command"/> that is invoked with context,
|
||||||
/// use <see cref="View.AddCommand(Command,Func{CommandContext,Nullable{bool}})"/>
|
/// use <see cref="View.AddCommand(Command,Func{CommandContext,System.Nullable{bool}})"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
#pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved
|
||||||
public record struct CommandContext
|
public record struct CommandContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -336,6 +336,24 @@ public abstract class Pos
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal virtual bool ReferencesOtherViews () { return false; }
|
internal virtual bool ReferencesOtherViews () { return false; }
|
||||||
|
|
||||||
|
public bool Has (Type type, out Pos pos)
|
||||||
|
{
|
||||||
|
pos = this;
|
||||||
|
if (type == GetType())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are a PosCombine, we have to check the left and right
|
||||||
|
// to see if they are of the type we are looking for.
|
||||||
|
if (this is PosCombine { } combine && (combine.Left.Has (type, out pos) || combine.Right.Has (type, out pos)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion virtual methods
|
#endregion virtual methods
|
||||||
|
|
||||||
#region operators
|
#region operators
|
||||||
|
|||||||
@@ -70,59 +70,67 @@ public class PosAlign : Pos
|
|||||||
List<int> dimensionsList = new ();
|
List<int> dimensionsList = new ();
|
||||||
|
|
||||||
// PERF: If this proves a perf issue, consider caching a ref to this list in each item
|
// PERF: If this proves a perf issue, consider caching a ref to this list in each item
|
||||||
List<View> viewsInGroup = views.Where (
|
List<PosAlign?> posAligns = views.Select (
|
||||||
v =>
|
v =>
|
||||||
{
|
{
|
||||||
return dimension switch
|
switch (dimension)
|
||||||
{
|
{
|
||||||
Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId,
|
case Dimension.Width when v.X.Has (typeof (PosAlign), out var pos):
|
||||||
Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId,
|
|
||||||
_ => false
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.ToList ();
|
|
||||||
|
|
||||||
if (viewsInGroup.Count == 0)
|
if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId)
|
||||||
{
|
{
|
||||||
return;
|
return posAlignX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Dimension.Height when v.Y.Has (typeof (PosAlign), out var pos):
|
||||||
|
if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId)
|
||||||
|
{
|
||||||
|
return posAlignY;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.ToList ();
|
||||||
|
|
||||||
// PERF: We iterate over viewsInGroup multiple times here.
|
// PERF: We iterate over viewsInGroup multiple times here.
|
||||||
|
|
||||||
Aligner? firstInGroup = null;
|
Aligner? firstInGroup = null;
|
||||||
|
|
||||||
// Update the dimensionList with the sizes of the views
|
// Update the dimensionList with the sizes of the views
|
||||||
for (var index = 0; index < viewsInGroup.Count; index++)
|
for (var index = 0; index < posAligns.Count; index++)
|
||||||
{
|
{
|
||||||
View view = viewsInGroup [index];
|
if (posAligns [index] is { })
|
||||||
PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign;
|
|
||||||
|
|
||||||
if (posAlign is { })
|
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (firstInGroup is null)
|
||||||
{
|
{
|
||||||
firstInGroup = posAlign.Aligner;
|
firstInGroup = posAligns [index]!.Aligner;
|
||||||
}
|
}
|
||||||
|
|
||||||
dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height);
|
dimensionsList.Add (dimension == Dimension.Width ? views [index].Frame.Width : views [index].Frame.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (firstInGroup is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the first item in the group with the new container size.
|
// Update the first item in the group with the new container size.
|
||||||
firstInGroup!.ContainerSize = size;
|
firstInGroup.ContainerSize = size;
|
||||||
|
|
||||||
// Align
|
// Align
|
||||||
int [] locations = firstInGroup.Align (dimensionsList.ToArray ());
|
int [] locations = firstInGroup.Align (dimensionsList.ToArray ());
|
||||||
|
|
||||||
// Update the cached location for each item
|
// Update the cached location for each item
|
||||||
for (var index = 0; index < viewsInGroup.Count; index++)
|
for (int posIndex = 0, locIndex = 0; posIndex < posAligns.Count; posIndex++)
|
||||||
{
|
{
|
||||||
View view = viewsInGroup [index];
|
if (posAligns [posIndex] is { })
|
||||||
PosAlign? align = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign;
|
|
||||||
|
|
||||||
if (align is { })
|
|
||||||
{
|
{
|
||||||
align._cachedLocation = locations [index];
|
posAligns [posIndex]!._cachedLocation = locations [locIndex++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,6 +176,14 @@ public class PosAlign : Pos
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this.
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the minimum size a group of views with the same <paramref name="groupId"/> can be.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupId"></param>
|
||||||
|
/// <param name="views"></param>
|
||||||
|
/// <param name="dimension"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static int CalculateMinDimension (int groupId, IList<View> views, Dimension dimension)
|
public static int CalculateMinDimension (int groupId, IList<View> views, Dimension dimension)
|
||||||
{
|
{
|
||||||
List<int> dimensionsList = new ();
|
List<int> dimensionsList = new ();
|
||||||
@@ -177,11 +193,11 @@ public class PosAlign : Pos
|
|||||||
v =>
|
v =>
|
||||||
{
|
{
|
||||||
return dimension switch
|
return dimension switch
|
||||||
{
|
{
|
||||||
Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId,
|
Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId,
|
||||||
Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId,
|
Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId,
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.ToList ();
|
.ToList ();
|
||||||
|
|
||||||
@@ -192,8 +208,6 @@ public class PosAlign : Pos
|
|||||||
|
|
||||||
// PERF: We iterate over viewsInGroup multiple times here.
|
// PERF: We iterate over viewsInGroup multiple times here.
|
||||||
|
|
||||||
Aligner? firstInGroup = null;
|
|
||||||
|
|
||||||
// Update the dimensionList with the sizes of the views
|
// Update the dimensionList with the sizes of the views
|
||||||
for (var index = 0; index < viewsInGroup.Count; index++)
|
for (var index = 0; index < viewsInGroup.Count; index++)
|
||||||
{
|
{
|
||||||
@@ -203,26 +217,11 @@ public class PosAlign : Pos
|
|||||||
|
|
||||||
if (posAlign is { })
|
if (posAlign is { })
|
||||||
{
|
{
|
||||||
if (index == 0)
|
|
||||||
{
|
|
||||||
firstInGroup = posAlign.Aligner;
|
|
||||||
|
|
||||||
//if (!posAlign._cachedLocation.HasValue)
|
|
||||||
//{
|
|
||||||
// AlignAndUpdateGroup (groupId, viewsInGroup, dimension, firstInGroup.ContainerSize );
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height);
|
dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align
|
// Align
|
||||||
var aligner = firstInGroup;
|
|
||||||
aligner.ContainerSize = dimensionsList.Sum();
|
|
||||||
int [] locations = aligner.Align (dimensionsList.ToArray ());
|
|
||||||
|
|
||||||
return dimensionsList.Sum ();
|
return dimensionsList.Sum ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class ColorPicker : View
|
|||||||
|
|
||||||
private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me)
|
private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me)
|
||||||
{
|
{
|
||||||
if (CanFocus)
|
// if (CanFocus)
|
||||||
{
|
{
|
||||||
Cursor = new Point (me.MouseEvent.Position.X / _boxWidth, me.MouseEvent.Position.Y / _boxHeight);
|
Cursor = new Point (me.MouseEvent.Position.X / _boxWidth, me.MouseEvent.Position.Y / _boxHeight);
|
||||||
SetFocus ();
|
SetFocus ();
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ namespace Terminal.Gui;
|
|||||||
/// right side.
|
/// right side.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// The command text can be set by setting the <see cref="CommandView"/>'s Text property or by setting
|
/// The command text can be set by setting the <see cref="CommandView"/>'s Text property.
|
||||||
/// <see cref="View.Title"/>.
|
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// The help text can be set by setting the <see cref="HelpText"/> property or by setting <see cref="View.Text"/>.
|
/// The help text can be set by setting the <see cref="HelpText"/> property or by setting <see cref="View.Text"/>.
|
||||||
@@ -59,27 +58,31 @@ public class Shortcut : View
|
|||||||
|
|
||||||
TitleChanged += Shortcut_TitleChanged; // This needs to be set before CommandView is set
|
TitleChanged += Shortcut_TitleChanged; // This needs to be set before CommandView is set
|
||||||
|
|
||||||
CommandView = new ();
|
CommandView = new ()
|
||||||
|
{
|
||||||
|
Width = Dim.Auto (),
|
||||||
|
Height = Dim.Auto (),
|
||||||
|
};
|
||||||
|
|
||||||
HelpView.Id = "_helpView";
|
HelpView.Id = "_helpView";
|
||||||
HelpView.CanFocus = false;
|
HelpView.CanFocus = false;
|
||||||
SetHelpViewDefaultLayout ();
|
SetHelpViewDefaultLayout ();
|
||||||
Add (HelpView);
|
Add (HelpView);
|
||||||
HelpView.MouseClick += Shortcut_MouseClick;
|
|
||||||
|
|
||||||
KeyView.Id = "_keyView";
|
KeyView.Id = "_keyView";
|
||||||
KeyView.CanFocus = false;
|
KeyView.CanFocus = false;
|
||||||
SetKeyViewDefaultLayout ();
|
SetKeyViewDefaultLayout ();
|
||||||
Add (KeyView);
|
Add (KeyView);
|
||||||
|
|
||||||
|
// If the user clicks anywhere on the Shortcut, other than the CommandView, invoke the Command
|
||||||
|
MouseClick += Shortcut_MouseClick;
|
||||||
|
HelpView.MouseClick += Shortcut_MouseClick;
|
||||||
KeyView.MouseClick += Shortcut_MouseClick;
|
KeyView.MouseClick += Shortcut_MouseClick;
|
||||||
|
|
||||||
MouseClick += Shortcut_MouseClick;
|
LayoutStarted += OnLayoutStarted;
|
||||||
|
|
||||||
Initialized += OnInitialized;
|
Initialized += OnInitialized;
|
||||||
|
|
||||||
LayoutStarted += OnLayoutStarted;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void OnInitialized (object sender, EventArgs e)
|
void OnInitialized (object sender, EventArgs e)
|
||||||
@@ -111,10 +114,19 @@ public class Shortcut : View
|
|||||||
// Helper to set Width consistently
|
// Helper to set Width consistently
|
||||||
Dim GetWidthDimAuto ()
|
Dim GetWidthDimAuto ()
|
||||||
{
|
{
|
||||||
|
// TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this.
|
||||||
return Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)));
|
return Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="Orientation"/> for this <see cref="Shortcut"/>. The default is
|
||||||
|
/// <see cref="Orientation.Horizontal"/>, which is ideal for status bars and toolbars. If set to <see cref="Orientation.Vertical"/>,
|
||||||
|
/// the Shortcut will be configured for vertical layout, which is ideal for menus.
|
||||||
|
/// </summary>
|
||||||
|
public Orientation Orientation { get; set; } = Orientation.Horizontal;
|
||||||
|
|
||||||
// When one of the subviews is "empty" we don't want to show it. So we
|
// When one of the subviews is "empty" we don't want to show it. So we
|
||||||
// Use Add/Remove. We need to be careful to add them in the right order
|
// Use Add/Remove. We need to be careful to add them in the right order
|
||||||
// so Pos.Align works correctly.
|
// so Pos.Align works correctly.
|
||||||
@@ -122,7 +134,7 @@ public class Shortcut : View
|
|||||||
{
|
{
|
||||||
RemoveAll ();
|
RemoveAll ();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty (CommandView.Text))
|
if (CommandView.Visible)
|
||||||
{
|
{
|
||||||
Add (CommandView);
|
Add (CommandView);
|
||||||
}
|
}
|
||||||
@@ -161,7 +173,7 @@ public class Shortcut : View
|
|||||||
if (currentWidth < _minimumDimAutoWidth)
|
if (currentWidth < _minimumDimAutoWidth)
|
||||||
{
|
{
|
||||||
int delta = _minimumDimAutoWidth.Value - currentWidth;
|
int delta = _minimumDimAutoWidth.Value - currentWidth;
|
||||||
int maxHelpWidth = int.Max (0, HelpView.Text.GetColumns () + 2 - delta);
|
int maxHelpWidth = int.Max (0, HelpView.Text.GetColumns () + Margin.Thickness.Horizontal - delta);
|
||||||
|
|
||||||
switch (maxHelpWidth)
|
switch (maxHelpWidth)
|
||||||
{
|
{
|
||||||
@@ -180,13 +192,14 @@ public class Shortcut : View
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Scrunch just the right margin
|
// Scrunch just the right margin
|
||||||
HelpView.Margin.Thickness = new (1, 0, 0, 0);
|
var t = GetMarginThickness ();
|
||||||
|
HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Default margin
|
// Default margin
|
||||||
HelpView.Margin.Thickness = new (1, 0, 1, 0);
|
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -208,6 +221,18 @@ public class Shortcut : View
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Thickness GetMarginThickness ()
|
||||||
|
{
|
||||||
|
if (Orientation == Orientation.Vertical)
|
||||||
|
{
|
||||||
|
return new Thickness (1, 0, 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Thickness (1, 0, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Color? _savedForeColor;
|
private Color? _savedForeColor;
|
||||||
|
|
||||||
private void Shortcut_Highlight (object sender, HighlightEventArgs e)
|
private void Shortcut_Highlight (object sender, HighlightEventArgs e)
|
||||||
@@ -339,18 +364,26 @@ public class Shortcut : View
|
|||||||
|
|
||||||
// TODO: Determine if it makes sense to allow the CommandView to be focusable.
|
// TODO: Determine if it makes sense to allow the CommandView to be focusable.
|
||||||
// Right now, we don't set CanFocus to false here.
|
// Right now, we don't set CanFocus to false here.
|
||||||
_commandView.CanFocus = false;
|
//_commandView.CanFocus = true;
|
||||||
|
|
||||||
|
//// Bar will set the width of all CommandViews to the width of the widest CommandViews.
|
||||||
|
////if (_commandView.Width == Dim.Absolute(0))
|
||||||
|
//{
|
||||||
|
// _commandView.Width = Dim.Auto ();
|
||||||
|
//}
|
||||||
|
|
||||||
|
////if (_commandView.Height == Dim.Absolute (0))
|
||||||
|
//{
|
||||||
|
// _commandView.Height = Dim.Auto ();
|
||||||
|
//}
|
||||||
|
|
||||||
// Bar will set the width of all CommandViews to the width of the widest CommandViews.
|
|
||||||
_commandView.Width = Dim.Auto ();
|
|
||||||
_commandView.Height = Dim.Auto ();
|
|
||||||
_commandView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
_commandView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
||||||
_commandView.Y = 0; //Pos.Center ();
|
_commandView.Y = 0; //Pos.Center ();
|
||||||
|
|
||||||
_commandView.MouseClick += Shortcut_MouseClick;
|
_commandView.MouseClick += Shortcut_MouseClick;
|
||||||
_commandView.Accept += CommandViewAccept;
|
_commandView.Accept += CommandViewAccept;
|
||||||
|
|
||||||
_commandView.Margin.Thickness = new (1, 0, 1, 0);
|
_commandView.Margin.Thickness = GetMarginThickness ();
|
||||||
|
|
||||||
_commandView.HotKeyChanged += (s, e) =>
|
_commandView.HotKeyChanged += (s, e) =>
|
||||||
{
|
{
|
||||||
@@ -364,7 +397,6 @@ public class Shortcut : View
|
|||||||
_commandView.HotKeySpecifier = new ('_');
|
_commandView.HotKeySpecifier = new ('_');
|
||||||
|
|
||||||
Title = _commandView.Text;
|
Title = _commandView.Text;
|
||||||
_commandView.TextChanged += CommandViewTextChanged;
|
|
||||||
|
|
||||||
SetHelpViewDefaultLayout ();
|
SetHelpViewDefaultLayout ();
|
||||||
SetKeyViewDefaultLayout ();
|
SetKeyViewDefaultLayout ();
|
||||||
@@ -373,8 +405,6 @@ public class Shortcut : View
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void CommandViewMouseEvent (object sender, MouseEventEventArgs e) { e.Handled = true; }
|
|
||||||
|
|
||||||
void CommandViewTextChanged (object sender, StateEventArgs<string> e)
|
void CommandViewTextChanged (object sender, StateEventArgs<string> e)
|
||||||
{
|
{
|
||||||
Title = _commandView.Text;
|
Title = _commandView.Text;
|
||||||
@@ -417,11 +447,12 @@ public class Shortcut : View
|
|||||||
|
|
||||||
private void SetHelpViewDefaultLayout ()
|
private void SetHelpViewDefaultLayout ()
|
||||||
{
|
{
|
||||||
HelpView.Margin.Thickness = new (1, 0, 1, 0);
|
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||||
HelpView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
HelpView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
||||||
HelpView.Y = 0; //Pos.Center (),
|
HelpView.Y = 0; //Pos.Center (),
|
||||||
HelpView.Width = Dim.Auto (DimAutoStyle.Text);
|
HelpView.Width = Dim.Auto (DimAutoStyle.Text);
|
||||||
HelpView.Height = Dim.Height (CommandView);
|
HelpView.Height = CommandView?.IsAdded == true ? Dim.Height (CommandView) : 1;
|
||||||
|
|
||||||
HelpView.Visible = true;
|
HelpView.Visible = true;
|
||||||
HelpView.VerticalTextAlignment = Alignment.Center;
|
HelpView.VerticalTextAlignment = Alignment.Center;
|
||||||
}
|
}
|
||||||
@@ -537,12 +568,12 @@ public class Shortcut : View
|
|||||||
|
|
||||||
private void SetKeyViewDefaultLayout ()
|
private void SetKeyViewDefaultLayout ()
|
||||||
{
|
{
|
||||||
KeyView.Margin.Thickness = new (1, 0, 1, 0);
|
KeyView.Margin.Thickness = GetMarginThickness();
|
||||||
KeyView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
KeyView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast);
|
||||||
|
|
||||||
//KeyView.Y = Pos.Center ();
|
//KeyView.Y = Pos.Center ();
|
||||||
KeyView.Width = Dim.Auto (DimAutoStyle.Text, Dim.Func (GetMinimumKeyViewSize));
|
KeyView.Width = Dim.Auto (DimAutoStyle.Text, Dim.Func (GetMinimumKeyViewSize));
|
||||||
KeyView.Height = Dim.Height (CommandView);
|
KeyView.Height = CommandView?.IsAdded == true ? Dim.Height (CommandView) : 1;
|
||||||
|
|
||||||
KeyView.Visible = true;
|
KeyView.Visible = true;
|
||||||
|
|
||||||
// Right align the text in the keyview
|
// Right align the text in the keyview
|
||||||
@@ -582,6 +613,7 @@ public class Shortcut : View
|
|||||||
switch (KeyBindingScope)
|
switch (KeyBindingScope)
|
||||||
{
|
{
|
||||||
case KeyBindingScope.Application:
|
case KeyBindingScope.Application:
|
||||||
|
handled = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyBindingScope.Focused:
|
case KeyBindingScope.Focused:
|
||||||
@@ -663,18 +695,9 @@ public class Shortcut : View
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool OnLeave (View view)
|
public override bool OnLeave (View view)
|
||||||
{
|
{
|
||||||
|
// Reset the color scheme (to SuperView).
|
||||||
ColorScheme = null;
|
ColorScheme = null;
|
||||||
|
|
||||||
return base.OnLeave (view);
|
|
||||||
if (SuperView is { })
|
|
||||||
{
|
|
||||||
ColorScheme = new (SuperView?.ColorScheme)
|
|
||||||
{
|
|
||||||
Normal = SuperView.ColorScheme.Normal,
|
|
||||||
HotNormal = SuperView.ColorScheme.HotNormal
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnLeave (view);
|
return base.OnLeave (view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
using Terminal.Gui;
|
using Terminal.Gui;
|
||||||
|
|
||||||
namespace UICatalog.Scenarios;
|
namespace UICatalog.Scenarios;
|
||||||
@@ -34,15 +35,16 @@ public class Shortcuts : Scenario
|
|||||||
{
|
{
|
||||||
X = Pos.AnchorEnd (),
|
X = Pos.AnchorEnd (),
|
||||||
Width = 40,
|
Width = 40,
|
||||||
Height = Dim.Fill (),
|
Height = Dim.Fill (4),
|
||||||
ColorScheme = Colors.ColorSchemes ["Toplevel"],
|
ColorScheme = Colors.ColorSchemes ["Toplevel"],
|
||||||
Source = new ListWrapper<string> (eventSource)
|
Source = new ListWrapper<string> (eventSource)
|
||||||
};
|
};
|
||||||
Application.Top.Add (eventLog);
|
Application.Top.Add (eventLog);
|
||||||
|
|
||||||
var shortcut1 = new Shortcut
|
var vShortcut1 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
|
X = 0,
|
||||||
Width = 35,
|
Width = 35,
|
||||||
Title = "A_pp Shortcut",
|
Title = "A_pp Shortcut",
|
||||||
Key = Key.F1,
|
Key = Key.F1,
|
||||||
@@ -50,14 +52,15 @@ public class Shortcuts : Scenario
|
|||||||
KeyBindingScope = KeyBindingScope.Application,
|
KeyBindingScope = KeyBindingScope.Application,
|
||||||
BorderStyle = LineStyle.Dotted
|
BorderStyle = LineStyle.Dotted
|
||||||
};
|
};
|
||||||
shortcut1.Border.Thickness = new (1, 1, 1, 1);
|
vShortcut1.Border.Thickness = new (1, 1, 1, 1);
|
||||||
Application.Top.Add (shortcut1);
|
Application.Top.Add (vShortcut1);
|
||||||
|
|
||||||
var shortcut2 = new Shortcut
|
var vShortcut2 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcut1) - 1,
|
X = 0,
|
||||||
Width = Dim.Width (shortcut1),
|
Y = Pos.Bottom (vShortcut1) - 1,
|
||||||
|
Width = Dim.Width (vShortcut1),
|
||||||
Key = Key.F2,
|
Key = Key.F2,
|
||||||
Text = "Width is ^",
|
Text = "Width is ^",
|
||||||
KeyBindingScope = KeyBindingScope.HotKey,
|
KeyBindingScope = KeyBindingScope.HotKey,
|
||||||
@@ -69,71 +72,73 @@ public class Shortcuts : Scenario
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
((RadioGroup)shortcut2.CommandView).SelectedItemChanged += (o, args) =>
|
((RadioGroup)vShortcut2.CommandView).SelectedItemChanged += (o, args) =>
|
||||||
{
|
{
|
||||||
eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}");
|
eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}");
|
||||||
eventLog.MoveDown ();
|
eventLog.MoveDown ();
|
||||||
};
|
};
|
||||||
|
|
||||||
shortcut2.Accept += (o, args) =>
|
vShortcut2.Accept += (o, args) =>
|
||||||
{
|
{
|
||||||
// Cycle to next item. If at end, set 0
|
// Cycle to next item. If at end, set 0
|
||||||
if (((RadioGroup)shortcut2.CommandView).SelectedItem < ((RadioGroup)shortcut2.CommandView).RadioLabels.Length - 1)
|
if (((RadioGroup)vShortcut2.CommandView).SelectedItem < ((RadioGroup)vShortcut2.CommandView).RadioLabels.Length - 1)
|
||||||
{
|
{
|
||||||
((RadioGroup)shortcut2.CommandView).SelectedItem++;
|
((RadioGroup)vShortcut2.CommandView).SelectedItem++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((RadioGroup)shortcut2.CommandView).SelectedItem = 0;
|
((RadioGroup)vShortcut2.CommandView).SelectedItem = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
shortcut2.Border.Thickness = new (1, 1, 1, 1);
|
vShortcut2.Border.Thickness = new (1, 1, 1, 1);
|
||||||
Application.Top.Add (shortcut2);
|
Application.Top.Add (vShortcut2);
|
||||||
|
|
||||||
var shortcut3 = new Shortcut
|
var vShortcut3 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcut2),
|
X = 0,
|
||||||
|
Y = Pos.Bottom (vShortcut2),
|
||||||
CommandView = new CheckBox { Text = "_Align" },
|
CommandView = new CheckBox { Text = "_Align" },
|
||||||
Key = Key.F3,
|
Key = Key.F3,
|
||||||
HelpText = "Width is Fill",
|
HelpText = "Width is Fill",
|
||||||
Width = Dim.Fill () - Dim.Width (eventLog),
|
Width = Dim.Fill () - Dim.Width (eventLog),
|
||||||
KeyBindingScope = KeyBindingScope.HotKey,
|
KeyBindingScope = KeyBindingScope.HotKey,
|
||||||
BorderStyle = LineStyle.Dotted
|
BorderStyle = LineStyle.Rounded
|
||||||
};
|
};
|
||||||
shortcut3.CommandView.CanFocus = true;
|
vShortcut3.Border.Thickness = new (1, 1, 1, 0);
|
||||||
shortcut3.Border.Thickness = new (1, 1, 1, 0);
|
|
||||||
|
|
||||||
((CheckBox)shortcut3.CommandView).Toggled += (s, e) =>
|
((CheckBox)vShortcut3.CommandView).Toggled += (s, e) =>
|
||||||
{
|
{
|
||||||
if (shortcut3.CommandView is CheckBox cb)
|
if (vShortcut3.CommandView is CheckBox cb)
|
||||||
{
|
{
|
||||||
eventSource.Add ($"Toggled: {cb.Text}");
|
eventSource.Add ($"Toggled: {cb.Text}");
|
||||||
eventLog.MoveDown ();
|
eventLog.MoveDown ();
|
||||||
|
|
||||||
var max = 0;
|
var max = 0;
|
||||||
|
var toAlign = Application.Top.Subviews.Where (v => v is Shortcut s && s.Orientation == Orientation.Vertical && s.BorderStyle == LineStyle.Rounded);
|
||||||
|
|
||||||
if (e.NewValue == true)
|
if (e.NewValue == true)
|
||||||
{
|
{
|
||||||
foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!)
|
foreach (Shortcut peer in toAlign)
|
||||||
{
|
{
|
||||||
max = Math.Max (max, peer.KeyView.Text.GetColumns ());
|
max = Math.Max (max, peer.KeyView.Text.GetColumns ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!)
|
foreach (Shortcut peer in toAlign)
|
||||||
{
|
{
|
||||||
peer.MinimumKeyViewSize = max;
|
peer.MinimumKeyViewSize = max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Application.Top.Add (shortcut3);
|
Application.Top.Add (vShortcut3);
|
||||||
|
|
||||||
var shortcut4 = new Shortcut
|
var vShortcut4 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcut3),
|
X = 0,
|
||||||
Width = Dim.Width (shortcut3),
|
Y = Pos.Bottom (vShortcut3),
|
||||||
|
Width = Dim.Width (vShortcut3),
|
||||||
CommandView = new Button
|
CommandView = new Button
|
||||||
{
|
{
|
||||||
Title = "B_utton",
|
Title = "B_utton",
|
||||||
@@ -141,41 +146,56 @@ public class Shortcuts : Scenario
|
|||||||
HelpText = "Width is Fill",
|
HelpText = "Width is Fill",
|
||||||
Key = Key.K,
|
Key = Key.K,
|
||||||
KeyBindingScope = KeyBindingScope.HotKey,
|
KeyBindingScope = KeyBindingScope.HotKey,
|
||||||
BorderStyle = LineStyle.Dotted
|
BorderStyle = LineStyle.Rounded
|
||||||
};
|
};
|
||||||
Button button = (Button)shortcut4.CommandView;
|
Button button = (Button)vShortcut4.CommandView;
|
||||||
shortcut4.CommandView.Accept += Button_Clicked;
|
vShortcut4.CommandView.Accept += Button_Clicked;
|
||||||
shortcut4.CommandView.CanFocus = true;
|
vShortcut4.Border.Thickness = new (1, 0, 1, 0);
|
||||||
shortcut4.Border.Thickness = new (1, 0, 1,0);
|
|
||||||
|
|
||||||
Application.Top.Add (shortcut4);
|
Application.Top.Add (vShortcut4);
|
||||||
|
|
||||||
var shortcut5 = new Shortcut
|
var vShortcut5 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcut4) ,
|
X = 0,
|
||||||
Width = Dim.Width (shortcut4),
|
Y = Pos.Bottom (vShortcut4),
|
||||||
|
Width = Dim.Width (vShortcut4),
|
||||||
|
|
||||||
Title = "Fi_ve",
|
|
||||||
Key = Key.F5.WithCtrl.WithAlt.WithShift,
|
Key = Key.F5.WithCtrl.WithAlt.WithShift,
|
||||||
HelpText = "Width is Fill",
|
HelpText = "CommandView.CanFocus",
|
||||||
KeyBindingScope = KeyBindingScope.HotKey,
|
KeyBindingScope = KeyBindingScope.HotKey,
|
||||||
BorderStyle = LineStyle.Dotted
|
BorderStyle = LineStyle.Rounded,
|
||||||
|
CommandView = new CheckBox { Text = "_CanFocus" },
|
||||||
};
|
};
|
||||||
shortcut5.Border.Thickness = new (1, 0, 1, 1);
|
vShortcut5.Border.Thickness = new (1, 0, 1, 1);
|
||||||
|
|
||||||
Application.Top.Add (shortcut5);
|
((CheckBox)vShortcut5.CommandView).Toggled += (s, e) =>
|
||||||
|
{
|
||||||
|
if (vShortcut5.CommandView is CheckBox cb)
|
||||||
|
{
|
||||||
|
eventSource.Add ($"Toggled: {cb.Text}");
|
||||||
|
eventLog.MoveDown ();
|
||||||
|
|
||||||
var shortcutSlider = new Shortcut
|
foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!)
|
||||||
|
{
|
||||||
|
peer.CanFocus = e.NewValue == true;
|
||||||
|
peer.CommandView.CanFocus = e.NewValue == true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Application.Top.Add (vShortcut5);
|
||||||
|
|
||||||
|
var vShortcutSlider = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcut5) - 1,
|
X = 0,
|
||||||
|
Y = Pos.Bottom (vShortcut5) - 1,
|
||||||
Key = Key.F5,
|
Key = Key.F5,
|
||||||
HelpText = "Width is Fill",
|
HelpText = "Width is Fill",
|
||||||
Width = Dim.Width (shortcut5),
|
Width = Dim.Width (vShortcut5),
|
||||||
|
|
||||||
KeyBindingScope = KeyBindingScope.HotKey,
|
KeyBindingScope = KeyBindingScope.HotKey,
|
||||||
BorderStyle = LineStyle.Dotted,
|
BorderStyle = LineStyle.Rounded,
|
||||||
CommandView = new Slider<string>
|
CommandView = new Slider<string>
|
||||||
{
|
{
|
||||||
Orientation = Orientation.Vertical,
|
Orientation = Orientation.Vertical,
|
||||||
@@ -183,31 +203,151 @@ public class Shortcuts : Scenario
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
((Slider<string>)shortcutSlider.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } };
|
((Slider<string>)vShortcutSlider.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } };
|
||||||
((Slider<string>)shortcutSlider.CommandView).SetOption (0);
|
((Slider<string>)vShortcutSlider.CommandView).SetOption (0);
|
||||||
shortcutSlider.Border.Thickness = new (1, 1, 1, 1);
|
vShortcutSlider.Border.Thickness = new (1, 1, 1, 1);
|
||||||
|
|
||||||
((Slider<string>)shortcutSlider.CommandView).OptionsChanged += (o, args) =>
|
((Slider<string>)vShortcutSlider.CommandView).OptionsChanged += (o, args) =>
|
||||||
{
|
{
|
||||||
eventSource.Add ($"OptionsChanged: {o.GetType ().Name} - {args.Options}");
|
eventSource.Add ($"OptionsChanged: {o.GetType ().Name} - {args.Options}");
|
||||||
eventLog.MoveDown ();
|
eventLog.MoveDown ();
|
||||||
};
|
};
|
||||||
|
|
||||||
Application.Top.Add (shortcutSlider);
|
Application.Top.Add (vShortcutSlider);
|
||||||
|
|
||||||
var shortcut6 = new Shortcut
|
var vShortcut6 = new Shortcut
|
||||||
{
|
{
|
||||||
X = 20,
|
Orientation = Orientation.Vertical,
|
||||||
Y = Pos.Bottom (shortcutSlider) - 1,
|
X = 0,
|
||||||
Width = Dim.Width (shortcutSlider),
|
Y = Pos.Bottom (vShortcutSlider) - 1,
|
||||||
|
Width = Dim.Width (vShortcutSlider),
|
||||||
|
|
||||||
Title = "_No Key",
|
Title = "_No Key",
|
||||||
HelpText = "Keyless",
|
HelpText = "Keyless",
|
||||||
BorderStyle = LineStyle.Dotted
|
BorderStyle = LineStyle.Rounded
|
||||||
};
|
};
|
||||||
shortcut6.Border.Thickness = new (1, 1, 1, 1);
|
vShortcut6.Border.Thickness = new (1, 1, 1, 1);
|
||||||
|
|
||||||
|
Application.Top.Add (vShortcut6);
|
||||||
|
|
||||||
|
((CheckBox)vShortcut3.CommandView).OnToggled();
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
var hShortcut1 = new Shortcut
|
||||||
|
{
|
||||||
|
X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1),
|
||||||
|
Y = Pos.Bottom (eventLog) + 1,
|
||||||
|
Key = Key.F7,
|
||||||
|
HelpText = "Horizontal",
|
||||||
|
BorderStyle = LineStyle.Dashed,
|
||||||
|
CanFocus = false
|
||||||
|
};
|
||||||
|
hShortcut1.Border.Thickness = new (0, 0, 1, 0);
|
||||||
|
|
||||||
|
hShortcut1.CommandView = new ProgressBar
|
||||||
|
{
|
||||||
|
Text = "Progress",
|
||||||
|
Title = "P",
|
||||||
|
Fraction = 0.5f,
|
||||||
|
Width = 10,
|
||||||
|
Height = 1,
|
||||||
|
ProgressBarStyle = ProgressBarStyle.Continuous
|
||||||
|
};
|
||||||
|
hShortcut1.CommandView.Width = 10;
|
||||||
|
hShortcut1.CommandView.Height = 1;
|
||||||
|
hShortcut1.CommandView.CanFocus = false;
|
||||||
|
Timer timer = new (10)
|
||||||
|
{
|
||||||
|
AutoReset = true,
|
||||||
|
};
|
||||||
|
timer.Elapsed += (o, args) =>
|
||||||
|
{
|
||||||
|
if (hShortcut1.CommandView is ProgressBar pb)
|
||||||
|
{
|
||||||
|
if (pb.Fraction == 1.0)
|
||||||
|
{
|
||||||
|
pb.Fraction = 0;
|
||||||
|
}
|
||||||
|
pb.Fraction += 0.01f;
|
||||||
|
|
||||||
|
Application.Wakeup ();
|
||||||
|
|
||||||
|
pb.SetNeedsDisplay ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer.Start ();
|
||||||
|
|
||||||
|
Application.Top.Add (hShortcut1);
|
||||||
|
|
||||||
|
var textField = new TextField ()
|
||||||
|
{
|
||||||
|
Text = "Edit me",
|
||||||
|
Width = 10,
|
||||||
|
Height = 1,
|
||||||
|
CanFocus = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var hShortcut2 = new Shortcut
|
||||||
|
{
|
||||||
|
X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1),
|
||||||
|
Y = Pos.Top (hShortcut1),
|
||||||
|
Key = Key.F8,
|
||||||
|
HelpText = "Edit",
|
||||||
|
CanFocus = true,
|
||||||
|
BorderStyle = LineStyle.Dashed,
|
||||||
|
CommandView = textField,
|
||||||
|
};
|
||||||
|
hShortcut2.Border.Thickness = new (0, 0, 1, 0);
|
||||||
|
|
||||||
|
Application.Top.Add (hShortcut2);
|
||||||
|
|
||||||
|
var hShortcutBG = new Shortcut
|
||||||
|
{
|
||||||
|
X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1)-1,
|
||||||
|
Y = Pos.Top (hShortcut2),
|
||||||
|
Key = Key.F9,
|
||||||
|
HelpText = "BG Color",
|
||||||
|
BorderStyle = LineStyle.Dashed,
|
||||||
|
CanFocus = false
|
||||||
|
};
|
||||||
|
|
||||||
|
var bgColor = new ColorPicker ()
|
||||||
|
{
|
||||||
|
CanFocus = false,
|
||||||
|
BoxHeight = 1,
|
||||||
|
BoxWidth = 1,
|
||||||
|
};
|
||||||
|
bgColor.ColorChanged += (o, args) =>
|
||||||
|
{
|
||||||
|
Application.Top.ColorScheme = new ColorScheme (Application.Top.ColorScheme)
|
||||||
|
{
|
||||||
|
Normal = new Attribute (Application.Top.ColorScheme.Normal.Foreground, args.Color),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hShortcutBG.CommandView = bgColor;
|
||||||
|
hShortcutBG.Border.Thickness = new (1, 0, 1, 0);
|
||||||
|
|
||||||
|
Application.Top.Add (hShortcutBG);
|
||||||
|
|
||||||
|
var hShortcut3 = new Shortcut
|
||||||
|
{
|
||||||
|
X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1),
|
||||||
|
Y = Pos.Top (hShortcut2),
|
||||||
|
Key = Key.Esc,
|
||||||
|
KeyBindingScope = KeyBindingScope.Application,
|
||||||
|
Title = "Quit",
|
||||||
|
HelpText = "App Scope",
|
||||||
|
BorderStyle = LineStyle.Dashed,
|
||||||
|
CanFocus = false
|
||||||
|
};
|
||||||
|
hShortcut3.Border.Thickness = new (0);
|
||||||
|
hShortcut3.Accept += (o, args) =>
|
||||||
|
{
|
||||||
|
Application.RequestStop ();
|
||||||
|
};
|
||||||
|
|
||||||
|
Application.Top.Add (hShortcut3);
|
||||||
|
|
||||||
Application.Top.Add (shortcut6);
|
|
||||||
|
|
||||||
foreach (View sh in Application.Top.Subviews.Where (v => v is Shortcut)!)
|
foreach (View sh in Application.Top.Subviews.Where (v => v is Shortcut)!)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user