diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs
index 48170eb22b..21e3df5ab7 100644
--- a/Terminal.Gui/Application/Application.Keyboard.cs
+++ b/Terminal.Gui/Application/Application.Keyboard.cs
@@ -9,7 +9,6 @@ public static partial class Application // Keyboard handling
/// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
- [JsonConverter (typeof (KeyJsonConverter))]
public static Key NextTabKey
{
get => _nextTabKey;
@@ -27,7 +26,6 @@ public static Key NextTabKey
/// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
- [JsonConverter (typeof (KeyJsonConverter))]
public static Key PrevTabKey
{
get => _prevTabKey;
@@ -45,7 +43,6 @@ public static Key PrevTabKey
/// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
- [JsonConverter (typeof (KeyJsonConverter))]
public static Key NextTabGroupKey
{
get => _nextTabGroupKey;
@@ -63,7 +60,6 @@ public static Key NextTabGroupKey
/// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
- [JsonConverter (typeof (KeyJsonConverter))]
public static Key PrevTabGroupKey
{
get => _prevTabGroupKey;
@@ -81,7 +77,6 @@ public static Key PrevTabGroupKey
/// Gets or sets the key to quit the application.
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
- [JsonConverter (typeof (KeyJsonConverter))]
public static Key QuitKey
{
get => _quitKey;
diff --git a/Terminal.Gui/Input/Key.cs b/Terminal.Gui/Input/Key.cs
index d2972bc04b..5c92cc4898 100644
--- a/Terminal.Gui/Input/Key.cs
+++ b/Terminal.Gui/Input/Key.cs
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+using System.Text.Json.Serialization;
namespace Terminal.Gui;
@@ -448,9 +449,9 @@ public override bool Equals (object obj)
#region String conversion
- /// Pretty prints the KeyEvent
+ /// Pretty prints the Key.
///
- public override string ToString () { return ToString (KeyCode, (Rune)'+'); }
+ public override string ToString () { return ToString (KeyCode, Separator); }
private static string GetKeyString (KeyCode key)
{
@@ -483,7 +484,7 @@ private static string GetKeyString (KeyCode key)
/// The formatted string. If the key is a printable character, it will be returned as a string. Otherwise, the key
/// name will be returned.
///
- public static string ToString (KeyCode key) { return ToString (key, (Rune)'+'); }
+ public static string ToString (KeyCode key) { return ToString (key, Separator); }
/// Formats a as a string.
/// The key to format.
@@ -584,7 +585,7 @@ public static bool TryParse (string text, [NotNullWhen (true)] out Key key)
key = null;
// Split the string into parts
- string [] parts = text.Split ('+', '-');
+ string [] parts = text.Split ('+', '-', (char)Separator.Value);
if (parts.Length is 0 or > 4 || parts.Any (string.IsNullOrEmpty))
{
@@ -971,4 +972,20 @@ out parsedInt
public static Key F24 => new (KeyCode.F24);
#endregion
+
+ private static Rune _separator = new ('+');
+
+ /// Gets or sets the separator character used when parsing and printing Keys. E.g. Ctrl+A. The default is '+'.
+ [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+ public static Rune Separator
+ {
+ get => _separator;
+ set
+ {
+ if (_separator != value)
+ {
+ _separator = value == default (Rune) ? new ('+') : value;
+ }
+ }
+ }
}
diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs
index ea4aa2d8b4..d5e776a538 100644
--- a/Terminal.Gui/Input/ShortcutHelper.cs
+++ b/Terminal.Gui/Input/ShortcutHelper.cs
@@ -23,7 +23,7 @@ public virtual KeyCode Shortcut
}
/// The keystroke combination used in the as string.
- public virtual string ShortcutTag => Key.ToString (shortcut, MenuBar.ShortcutDelimiter);
+ public virtual string ShortcutTag => Key.ToString (shortcut, Key.Separator);
/// Lookup for a on range of keys.
/// The source key.
@@ -59,7 +59,7 @@ public static KeyCode GetShortcutFromTag (string tag, Rune delimiter = default)
//var hasCtrl = false;
if (delimiter == default (Rune))
{
- delimiter = MenuBar.ShortcutDelimiter;
+ delimiter = Key.Separator;
}
string [] keys = sCut.Split (delimiter.ToString ());
diff --git a/Terminal.Gui/Resources/config.json b/Terminal.Gui/Resources/config.json
index d001326a08..adba1e584b 100644
--- a/Terminal.Gui/Resources/config.json
+++ b/Terminal.Gui/Resources/config.json
@@ -22,6 +22,7 @@
"Application.NextTabGroupKey": "F6",
"Application.PrevTabGroupKey": "Shift+F6",
"Application.QuitKey": "Esc",
+ "Key.Separator": "+",
"Theme": "Default",
"Themes": [
diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs
index 1b8e7d11ab..6bff5c9ad5 100644
--- a/Terminal.Gui/Views/Menu/Menu.cs
+++ b/Terminal.Gui/Views/Menu/Menu.cs
@@ -120,7 +120,7 @@ _barItems.Children [_currentChild]
}
);
- AddKeyBindings (_barItems);
+ AddKeyBindingsHotKey (_barItems);
}
public Menu ()
@@ -179,7 +179,7 @@ public Menu ()
KeyBindings.Add (Key.Enter, Command.Accept);
}
- private void AddKeyBindings (MenuBarItem menuBarItem)
+ private void AddKeyBindingsHotKey (MenuBarItem menuBarItem)
{
if (menuBarItem is null || menuBarItem.Children is null)
{
@@ -190,23 +190,30 @@ private void AddKeyBindings (MenuBarItem menuBarItem)
{
KeyBinding keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.HotKey, menuItem);
- if ((KeyCode)menuItem.HotKey.Value != KeyCode.Null)
+ if (menuItem.HotKey != Key.Empty)
{
- KeyBindings.Remove ((KeyCode)menuItem.HotKey.Value);
- KeyBindings.Add ((KeyCode)menuItem.HotKey.Value, keyBinding);
- KeyBindings.Remove ((KeyCode)menuItem.HotKey.Value | KeyCode.AltMask);
- KeyBindings.Add ((KeyCode)menuItem.HotKey.Value | KeyCode.AltMask, keyBinding);
+ KeyBindings.Remove (menuItem.HotKey);
+ KeyBindings.Add (menuItem.HotKey, keyBinding);
+ KeyBindings.Remove (menuItem.HotKey.WithAlt);
+ KeyBindings.Add (menuItem.HotKey.WithAlt, keyBinding);
}
+ }
+ }
+
+ private void RemoveKeyBindingsHotKey (MenuBarItem menuBarItem)
+ {
+ if (menuBarItem is null || menuBarItem.Children is null)
+ {
+ return;
+ }
- if (menuItem.Shortcut != KeyCode.Null)
+ foreach (MenuItem menuItem in menuBarItem.Children.Where (m => m is { }))
+ {
+ if (menuItem.HotKey != Key.Empty)
{
- keyBinding = new ([Command.Select], KeyBindingScope.HotKey, menuItem);
- KeyBindings.Remove (menuItem.Shortcut);
- KeyBindings.Add (menuItem.Shortcut, keyBinding);
+ KeyBindings.Remove (menuItem.HotKey);
+ KeyBindings.Remove (menuItem.HotKey.WithAlt);
}
-
- MenuBarItem subMenu = menuBarItem.SubMenu (menuItem);
- AddKeyBindings (subMenu);
}
}
@@ -910,6 +917,8 @@ internal bool CheckSubMenu ()
protected override void Dispose (bool disposing)
{
+ RemoveKeyBindingsHotKey (_barItems);
+
if (Application.Current is { })
{
Application.Current.DrawContentComplete -= Current_DrawContentComplete;
diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs
index 75acefe853..4f0db8da77 100644
--- a/Terminal.Gui/Views/Menu/MenuBar.cs
+++ b/Terminal.Gui/Views/Menu/MenuBar.cs
@@ -66,6 +66,8 @@ public class MenuBar : View, IDesignable
/// Initializes a new instance of the .
public MenuBar ()
{
+ MenuItem._menuBar = this;
+
TabStop = TabBehavior.NoStop;
X = 0;
Y = 0;
@@ -122,7 +124,7 @@ public MenuBar ()
return true;
}
);
- AddCommand (Command.ToggleExpandCollapse, ctx => Select ((int)ctx.KeyBinding?.Context!));
+ AddCommand (Command.ToggleExpandCollapse, ctx => Select (Menus.IndexOf (ctx.KeyBinding?.Context)));
AddCommand (Command.Select, ctx => Run ((ctx.KeyBinding?.Context as MenuItem)?.Action));
// Default key bindings for this view
@@ -172,19 +174,23 @@ public MenuBarItem [] Menus
{
MenuBarItem menuBarItem = Menus [i];
- if (menuBarItem?.HotKey != default (Rune))
+ if (menuBarItem?.HotKey != Key.Empty)
{
- KeyBinding keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.Focused, i);
- KeyBindings.Add ((KeyCode)menuBarItem.HotKey.Value, keyBinding);
- keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.HotKey, i);
- KeyBindings.Add ((KeyCode)menuBarItem.HotKey.Value | KeyCode.AltMask, keyBinding);
+ KeyBindings.Remove (menuBarItem!.HotKey);
+ KeyBinding keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.Focused, menuBarItem);
+ KeyBindings.Add (menuBarItem!.HotKey, keyBinding);
+ KeyBindings.Remove (menuBarItem.HotKey.WithAlt);
+ keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.HotKey, menuBarItem);
+ KeyBindings.Add (menuBarItem.HotKey.WithAlt, keyBinding);
}
- if (menuBarItem?.Shortcut != KeyCode.Null)
+ if (menuBarItem?.ShortcutKey != Key.Empty)
{
// Technically this will never run because MenuBarItems don't have shortcuts
- KeyBinding keyBinding = new ([Command.Select], KeyBindingScope.HotKey, i);
- KeyBindings.Add (menuBarItem.Shortcut, keyBinding);
+ // unless the IsTopLevel is true
+ KeyBindings.Remove (menuBarItem.ShortcutKey);
+ KeyBinding keyBinding = new ([Command.Select], KeyBindingScope.HotKey, menuBarItem);
+ KeyBindings.Add (menuBarItem.ShortcutKey, keyBinding);
}
menuBarItem?.AddShortcutKeyBindings (this);
@@ -1255,21 +1261,6 @@ public bool UseKeysUpDownAsKeysLeftRight
}
}
- private static Rune _shortcutDelimiter = new ('+');
-
- /// Sets or gets the shortcut delimiter separator. The default is "+".
- public static Rune ShortcutDelimiter
- {
- get => _shortcutDelimiter;
- set
- {
- if (_shortcutDelimiter != value)
- {
- _shortcutDelimiter = value == default (Rune) ? new ('+') : value;
- }
- }
- }
-
/// The specifier character for the hot keys.
public new static Rune HotKeySpecifier => (Rune)'_';
@@ -1321,6 +1312,10 @@ private bool Select (int index)
{
OpenMenu ();
}
+ else if (Menus [index].IsTopLevel)
+ {
+ Run (Menus [index].Action);
+ }
else
{
Activate (index);
@@ -1766,4 +1761,12 @@ public bool EnableForDesign (ref readonly TContext context) where TCon
];
return true;
}
+
+ ///
+ protected override void Dispose (bool disposing)
+ {
+ MenuItem._menuBar = null;
+
+ base.Dispose (disposing);
+ }
}
diff --git a/Terminal.Gui/Views/Menu/MenuBarItem.cs b/Terminal.Gui/Views/Menu/MenuBarItem.cs
index 81e7557370..698499cd76 100644
--- a/Terminal.Gui/Views/Menu/MenuBarItem.cs
+++ b/Terminal.Gui/Views/Menu/MenuBarItem.cs
@@ -2,7 +2,7 @@ namespace Terminal.Gui;
///
/// is a menu item on . MenuBarItems do not support
-/// .
+/// .
///
public class MenuBarItem : MenuItem
{
@@ -100,11 +100,9 @@ internal void AddShortcutKeyBindings (MenuBar menuBar)
{
// For MenuBar only add shortcuts for submenus
- if (menuItem.Shortcut != KeyCode.Null)
+ if (menuItem.ShortcutKey != Key.Empty)
{
- KeyBinding keyBinding = new ([Command.Select], KeyBindingScope.HotKey, menuItem);
- menuBar.KeyBindings.Remove (menuItem.Shortcut);
- menuBar.KeyBindings.Add (menuItem.Shortcut, keyBinding);
+ menuItem.UpdateShortcutKeyBinding (Key.Empty);
}
SubMenu (menuItem)?.AddShortcutKeyBindings (menuBar);
@@ -176,4 +174,75 @@ private void SetTitle (string title)
title ??= string.Empty;
Title = title;
}
+
+ ///
+ /// Add a dynamically into the .Menus.
+ ///
+ ///
+ public void AddMenuBarItem (MenuItem menuItem = null)
+ {
+ if (menuItem is null)
+ {
+ MenuBarItem [] menus = _menuBar.Menus;
+ Array.Resize (ref menus, menus.Length + 1);
+ menus [^1] = this;
+ _menuBar.Menus = menus;
+ }
+ else
+ {
+ MenuItem [] childrens = Children ?? [];
+ Array.Resize (ref childrens, childrens.Length + 1);
+ childrens [^1] = menuItem;
+ Children = childrens;
+ }
+ }
+
+ ///
+ public override void RemoveMenuItem ()
+ {
+ if (Children is { })
+ {
+ foreach (MenuItem menuItem in Children)
+ {
+ if (menuItem.ShortcutKey != Key.Empty)
+ {
+ // Remove an existent ShortcutKey
+ _menuBar?.KeyBindings.Remove (menuItem.ShortcutKey);
+ }
+ }
+ }
+
+ if (ShortcutKey != Key.Empty)
+ {
+ // Remove an existent ShortcutKey
+ _menuBar?.KeyBindings.Remove (ShortcutKey);
+ }
+
+ var index = _menuBar!.Menus.IndexOf (this);
+ if (index > -1)
+ {
+ if (_menuBar!.Menus [index].HotKey != Key.Empty)
+ {
+ // Remove an existent HotKey
+ _menuBar?.KeyBindings.Remove (HotKey.WithAlt);
+ }
+
+ _menuBar!.Menus [index] = null;
+ }
+
+ var i = 0;
+
+ foreach (MenuBarItem m in _menuBar.Menus)
+ {
+ if (m != null)
+ {
+ _menuBar.Menus [i] = m;
+ i++;
+ }
+ }
+
+ MenuBarItem [] menus = _menuBar.Menus;
+ Array.Resize (ref menus, menus.Length - 1);
+ _menuBar.Menus = menus;
+ }
}
diff --git a/Terminal.Gui/Views/Menu/MenuItem.cs b/Terminal.Gui/Views/Menu/MenuItem.cs
index 5743c47682..8b72cbb422 100644
--- a/Terminal.Gui/Views/Menu/MenuItem.cs
+++ b/Terminal.Gui/Views/Menu/MenuItem.cs
@@ -6,31 +6,25 @@ namespace Terminal.Gui;
///
public class MenuItem
{
- private readonly ShortcutHelper _shortcutHelper;
- private bool _allowNullChecked;
- private MenuItemCheckStyle _checkType;
+ internal static MenuBar _menuBar;
- private string _title;
-
- // TODO: Update to use Key instead of KeyCode
/// Initializes a new instance of
- public MenuItem (KeyCode shortcut = KeyCode.Null) : this ("", "", null, null, null, shortcut) { }
+ public MenuItem (Key shortcutKey = null) : this ("", "", null, null, null, shortcutKey) { }
- // TODO: Update to use Key instead of KeyCode
/// Initializes a new instance of .
/// Title for the menu item.
/// Help text to display.
/// Action to invoke when the menu item is activated.
/// Function to determine if the action can currently be executed.
/// The of this menu item.
- /// The keystroke combination.
+ /// The keystroke combination.
public MenuItem (
string title,
string help,
Action action,
Func canExecute = null,
MenuItem parent = null,
- KeyCode shortcut = KeyCode.Null
+ Key shortcutKey = null
)
{
Title = title ?? "";
@@ -38,14 +32,20 @@ public MenuItem (
Action = action;
CanExecute = canExecute;
Parent = parent;
- _shortcutHelper = new ();
- if (shortcut != KeyCode.Null)
+ if (Parent is { } && Parent.ShortcutKey != Key.Empty)
{
- Shortcut = shortcut;
+ Parent.ShortcutKey = Key.Empty;
}
+ // Setter will ensure Key.Empty if it's null
+ ShortcutKey = shortcutKey;
}
+ private bool _allowNullChecked;
+ private MenuItemCheckStyle _checkType;
+
+ private string _title;
+
/// Gets or sets the action to be invoked when the menu item is triggered.
/// Method to invoke.
public Action Action { get; set; }
@@ -104,6 +104,12 @@ public MenuItemCheckStyle CheckType
/// The help text.
public string Help { get; set; }
+ ///
+ /// Returns if the menu item is enabled. This method is a wrapper around
+ /// .
+ ///
+ public bool IsEnabled () { return CanExecute?.Invoke () ?? true; }
+
/// Gets the parent for this .
/// The parent.
public MenuItem Parent { get; set; }
@@ -125,46 +131,6 @@ public string Title
}
}
- /// Gets if this is from a sub-menu.
- internal bool IsFromSubMenu => Parent != null;
-
- internal int TitleLength => GetMenuBarItemLength (Title);
-
- //
- // ┌─────────────────────────────┐
- // │ Quit Quit UI Catalog Ctrl+Q │
- // └─────────────────────────────┘
- // ┌─────────────────┐
- // │ ◌ TopLevel Alt+T │
- // └─────────────────┘
- // TODO: Replace the `2` literals with named constants
- internal int Width => 1
- + // space before Title
- TitleLength
- + 2
- + // space after Title - BUGBUG: This should be 1
- (Checked == true || CheckType.HasFlag (MenuItemCheckStyle.Checked) || CheckType.HasFlag (MenuItemCheckStyle.Radio)
- ? 2
- : 0)
- + // check glyph + space
- (Help.GetColumns () > 0 ? 2 + Help.GetColumns () : 0)
- + // Two spaces before Help
- (ShortcutTag.GetColumns () > 0
- ? 2 + ShortcutTag.GetColumns ()
- : 0); // Pad two spaces before shortcut tag (which are also aligned right)
-
- /// Merely a debugging aid to see the interaction with main.
- internal bool GetMenuBarItem () { return IsFromSubMenu; }
-
- /// Merely a debugging aid to see the interaction with main.
- internal MenuItem GetMenuItem () { return this; }
-
- ///
- /// Returns if the menu item is enabled. This method is a wrapper around
- /// .
- ///
- public bool IsEnabled () { return CanExecute?.Invoke () ?? true; }
-
///
/// Toggle the between three states if is
/// or between two states if is .
@@ -193,6 +159,40 @@ public void ToggleChecked ()
}
}
+ /// Merely a debugging aid to see the interaction with main.
+ internal bool GetMenuBarItem () { return IsFromSubMenu; }
+
+ /// Merely a debugging aid to see the interaction with main.
+ internal MenuItem GetMenuItem () { return this; }
+
+ /// Gets if this is from a sub-menu.
+ internal bool IsFromSubMenu => Parent != null;
+
+ internal int TitleLength => GetMenuBarItemLength (Title);
+
+ //
+ // ┌─────────────────────────────┐
+ // │ Quit Quit UI Catalog Ctrl+Q │
+ // └─────────────────────────────┘
+ // ┌─────────────────┐
+ // │ ◌ TopLevel Alt+T │
+ // └─────────────────┘
+ // TODO: Replace the `2` literals with named constants
+ internal int Width => 1
+ + // space before Title
+ TitleLength
+ + 2
+ + // space after Title - BUGBUG: This should be 1
+ (Checked == true || CheckType.HasFlag (MenuItemCheckStyle.Checked) || CheckType.HasFlag (MenuItemCheckStyle.Radio)
+ ? 2
+ : 0)
+ + // check glyph + space
+ (Help.GetColumns () > 0 ? 2 + Help.GetColumns () : 0)
+ + // Two spaces before Help
+ (ShortcutTag.GetColumns () > 0
+ ? 2 + ShortcutTag.GetColumns ()
+ : 0); // Pad two spaces before shortcut tag (which are also aligned right)
+
private static int GetMenuBarItemLength (string title)
{
return title.EnumerateRunes ()
@@ -202,21 +202,32 @@ private static int GetMenuBarItemLength (string title)
#region Keyboard Handling
- // TODO: Update to use Key instead of Rune
+ private Key _hotKey = Key.Empty;
+
///
/// The HotKey is used to activate a with the keyboard. HotKeys are defined by prefixing the
/// of a MenuItem with an underscore ('_').
///
/// Pressing Alt-Hotkey for a (menu items on the menu bar) works even if the menu is
- /// not active). Once a menu has focus and is active, pressing just the HotKey will activate the MenuItem.
+ /// not active. Once a menu has focus and is active, pressing just the HotKey will activate the MenuItem.
///
///
/// For example for a MenuBar with a "_File" MenuBarItem that contains a "_New" MenuItem, Alt-F will open the
/// File menu. Pressing the N key will then activate the New MenuItem.
///
- /// See also which enable global key-bindings to menu items.
+ /// See also which enable global key-bindings to menu items.
///
- public Rune HotKey { get; set; }
+ public Key HotKey
+ {
+ get => _hotKey;
+ private set
+ {
+ var oldKey = _hotKey ?? Key.Empty;
+ _hotKey = value ?? Key.Empty;
+ UpdateHotKeyBinding (oldKey);
+ }
+ }
+
private void GetHotKey ()
{
var nextIsHot = false;
@@ -227,47 +238,130 @@ private void GetHotKey ()
{
nextIsHot = true;
}
- else
+ else if (nextIsHot)
{
- if (nextIsHot)
- {
- HotKey = (Rune)char.ToUpper (x);
+ HotKey = char.ToLower (x);
- break;
- }
-
- nextIsHot = false;
- HotKey = default (Rune);
+ return;
}
}
+
+ HotKey = Key.Empty;
}
- // TODO: Update to use Key instead of KeyCode
+ private Key _shortcutKey = Key.Empty;
+
///
/// Shortcut defines a key binding to the MenuItem that will invoke the MenuItem's action globally for the
/// that is the parent of the or this
/// .
///
- /// The will be drawn on the MenuItem to the right of the and
+ /// The will be drawn on the MenuItem to the right of the and
/// text. See .
///
///
- public KeyCode Shortcut
+ public Key ShortcutKey
{
- get => _shortcutHelper.Shortcut;
+ get => _shortcutKey;
set
{
- if (_shortcutHelper.Shortcut != value && (ShortcutHelper.PostShortcutValidation (value) || value == KeyCode.Null))
+ var oldKey = _shortcutKey ?? Key.Empty;
+ _shortcutKey = value ?? Key.Empty;
+ UpdateShortcutKeyBinding (oldKey);
+ }
+ }
+
+ /// Gets the text describing the keystroke combination defined by .
+ public string ShortcutTag => ShortcutKey != Key.Empty ? ShortcutKey.ToString () : string.Empty;
+
+ private void UpdateHotKeyBinding (Key oldKey)
+ {
+ if (_menuBar is null || _menuBar?.IsInitialized == false)
+ {
+ return;
+ }
+
+ if (oldKey != Key.Empty)
+ {
+ var index = _menuBar.Menus?.IndexOf (this);
+
+ if (index > -1)
+ {
+ _menuBar.KeyBindings.Remove (oldKey.WithAlt);
+ }
+ }
+
+ if (HotKey != Key.Empty)
+ {
+ var index = _menuBar.Menus?.IndexOf (this);
+
+ if (index > -1)
{
- _shortcutHelper.Shortcut = value;
+ _menuBar.KeyBindings.Remove (HotKey.WithAlt);
+ KeyBinding keyBinding = new ([Command.ToggleExpandCollapse], KeyBindingScope.HotKey, this);
+ _menuBar.KeyBindings.Add (HotKey.WithAlt, keyBinding);
}
}
}
- /// Gets the text describing the keystroke combination defined by .
- public string ShortcutTag => _shortcutHelper.Shortcut == KeyCode.Null
- ? string.Empty
- : Key.ToString (_shortcutHelper.Shortcut, MenuBar.ShortcutDelimiter);
+ internal void UpdateShortcutKeyBinding (Key oldKey)
+ {
+ if (_menuBar is null)
+ {
+ return;
+ }
+
+ if (oldKey != Key.Empty)
+ {
+ _menuBar.KeyBindings.Remove (oldKey);
+ }
+
+ if (ShortcutKey != Key.Empty)
+ {
+ KeyBinding keyBinding = new ([Command.Select], KeyBindingScope.HotKey, this);
+ // Remove an existent ShortcutKey
+ _menuBar?.KeyBindings.Remove (ShortcutKey);
+ _menuBar?.KeyBindings.Add (ShortcutKey, keyBinding);
+ }
+ }
#endregion Keyboard Handling
+
+ ///
+ /// Removes a dynamically from the .
+ ///
+ public virtual void RemoveMenuItem ()
+ {
+ if (Parent is { })
+ {
+ MenuItem [] childrens = ((MenuBarItem)Parent).Children;
+ var i = 0;
+
+ foreach (MenuItem c in childrens)
+ {
+ if (c != this)
+ {
+ childrens [i] = c;
+ i++;
+ }
+ }
+
+ Array.Resize (ref childrens, childrens.Length - 1);
+
+ if (childrens.Length == 0)
+ {
+ ((MenuBarItem)Parent).Children = null;
+ }
+ else
+ {
+ ((MenuBarItem)Parent).Children = childrens;
+ }
+ }
+
+ if (ShortcutKey != Key.Empty)
+ {
+ // Remove an existent ShortcutKey
+ _menuBar?.KeyBindings.Remove (ShortcutKey);
+ }
+ }
}
diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs
index 4e3b4dc34c..c0ae3cb80a 100644
--- a/UICatalog/Scenarios/ContextMenus.cs
+++ b/UICatalog/Scenarios/ContextMenus.cs
@@ -179,7 +179,7 @@ private void ShowContextMenu (int x, int y)
"This would open setup dialog",
"Ok"
),
- shortcut: KeyCode.T
+ shortcutKey: KeyCode.T
| KeyCode
.CtrlMask
),
diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs
index 79af23d233..1cd3ae0ef6 100644
--- a/UICatalog/Scenarios/DynamicMenuBar.cs
+++ b/UICatalog/Scenarios/DynamicMenuBar.cs
@@ -111,36 +111,55 @@ public DynamicMenuBarDetails (MenuItem menuItem = null, bool hasParent = false)
public DynamicMenuBarDetails ()
{
- var _lblTitle = new Label { Y = 1, Text = "Title:" };
- Add (_lblTitle);
+ var lblTitle = new Label { Y = 1, Text = "Title:" };
+ Add (lblTitle);
- TextTitle = new () { X = Pos.Right (_lblTitle) + 2, Y = Pos.Top (_lblTitle), Width = Dim.Fill () };
+ TextTitle = new () { X = Pos.Right (lblTitle) + 2, Y = Pos.Top (lblTitle), Width = Dim.Fill () };
Add (TextTitle);
- var _lblHelp = new Label { X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblTitle) + 1, Text = "Help:" };
- Add (_lblHelp);
+ var lblHelp = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblTitle) + 1, Text = "Help:" };
+ Add (lblHelp);
- TextHelp = new () { X = Pos.Left (TextTitle), Y = Pos.Top (_lblHelp), Width = Dim.Fill () };
+ TextHelp = new () { X = Pos.Left (TextTitle), Y = Pos.Top (lblHelp), Width = Dim.Fill () };
Add (TextHelp);
- var _lblAction = new Label { X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblHelp) + 1, Text = "Action:" };
- Add (_lblAction);
+ var lblAction = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblHelp) + 1, Text = "Action:" };
+ Add (lblAction);
TextAction = new ()
{
- X = Pos.Left (TextTitle), Y = Pos.Top (_lblAction), Width = Dim.Fill (), Height = 5
+ X = Pos.Left (TextTitle), Y = Pos.Top (lblAction), Width = Dim.Fill (), Height = 5
};
Add (TextAction);
+ var lblHotKey = new Label { X = Pos.Left (lblTitle), Y = Pos.Bottom (lblAction) + 5, Text = "HotKey:" };
+ Add (lblHotKey);
+
+ TextHotKey = new ()
+ {
+ X = Pos.Left (TextTitle), Y = Pos.Bottom (lblAction) + 5, Width = 2, ReadOnly = true
+ };
+
+ TextHotKey.TextChanging += (s, e) =>
+ {
+ if (!string.IsNullOrEmpty (e.NewValue) && char.IsLower (e.NewValue [0]))
+ {
+ e.NewValue = e.NewValue.ToUpper ();
+ }
+ };
+ TextHotKey.TextChanged += (s, _) => TextHotKey.SelectAll ();
+ TextHotKey.SelectAll ();
+ Add (TextHotKey);
+
CkbIsTopLevel = new ()
{
- X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblAction) + 5, Text = "IsTopLevel"
+ X = Pos.Left (lblTitle), Y = Pos.Bottom (lblHotKey) + 1, Text = "IsTopLevel"
};
Add (CkbIsTopLevel);
CkbSubMenu = new ()
{
- X = Pos.Left (_lblTitle),
+ X = Pos.Left (lblTitle),
Y = Pos.Bottom (CkbIsTopLevel),
CheckedState = (_menuItem == null ? !_hasParent : HasSubMenus (_menuItem)) ? CheckState.Checked : CheckState.UnChecked,
Text = "Has sub-menus"
@@ -149,130 +168,66 @@ public DynamicMenuBarDetails ()
CkbNullCheck = new ()
{
- X = Pos.Left (_lblTitle), Y = Pos.Bottom (CkbSubMenu), Text = "Allow null checked"
+ X = Pos.Left (lblTitle), Y = Pos.Bottom (CkbSubMenu), Text = "Allow null checked"
};
Add (CkbNullCheck);
- var _rChkLabels = new [] { "NoCheck", "Checked", "Radio" };
+ var rChkLabels = new [] { "NoCheck", "Checked", "Radio" };
RbChkStyle = new ()
{
- X = Pos.Left (_lblTitle), Y = Pos.Bottom (CkbSubMenu) + 1, RadioLabels = _rChkLabels
+ X = Pos.Left (lblTitle), Y = Pos.Bottom (CkbSubMenu) + 1, RadioLabels = rChkLabels
};
Add (RbChkStyle);
- var _lblShortcut = new Label
+ var lblShortcut = new Label
{
X = Pos.Right (CkbSubMenu) + 10, Y = Pos.Top (CkbSubMenu), Text = "Shortcut:"
};
- Add (_lblShortcut);
+ Add (lblShortcut);
- TextShortcut = new ()
+ TextShortcutKey = new ()
{
- X = Pos.X (_lblShortcut), Y = Pos.Bottom (_lblShortcut), Width = Dim.Fill (), ReadOnly = true
+ X = Pos.X (lblShortcut), Y = Pos.Bottom (lblShortcut), Width = Dim.Fill (), ReadOnly = true
};
- TextShortcut.KeyDown += (s, e) =>
+ TextShortcutKey.KeyDown += (s, e) =>
{
- if (!ProcessKey (e))
- {
- return;
- }
+ TextShortcutKey.Text = e.ToString ();
- if (CheckShortcut (e.KeyCode, true))
- {
- e.Handled = true;
- }
};
- bool ProcessKey (Key ev)
- {
- switch (ev.KeyCode)
- {
- case KeyCode.CursorUp:
- case KeyCode.CursorDown:
- case KeyCode.Tab:
- case KeyCode.Tab | KeyCode.ShiftMask:
- return false;
- }
-
- return true;
- }
+ Add (TextShortcutKey);
- bool CheckShortcut (KeyCode k, bool pre)
+ var btnShortcut = new Button
{
- MenuItem m = _menuItem != null ? _menuItem : new ();
-
- if (pre && !ShortcutHelper.PreShortcutValidation (k))
- {
- TextShortcut.Text = "";
-
- return false;
- }
-
- if (!pre)
- {
- if (!ShortcutHelper.PostShortcutValidation (
- ShortcutHelper.GetShortcutFromTag (TextShortcut.Text)
- ))
- {
- TextShortcut.Text = "";
-
- return false;
- }
-
- return true;
- }
-
- TextShortcut.Text =
- Key.ToString (
- k,
- MenuBar.ShortcutDelimiter
- ); // ShortcutHelper.GetShortcutTag (k);
-
- return true;
- }
-
- TextShortcut.KeyUp += (s, e) =>
- {
- if (CheckShortcut (e.KeyCode, false))
- {
- e.Handled = true;
- }
- };
- Add (TextShortcut);
-
- var _btnShortcut = new Button
- {
- X = Pos.X (_lblShortcut), Y = Pos.Bottom (TextShortcut) + 1, Text = "Clear Shortcut"
+ X = Pos.X (lblShortcut), Y = Pos.Bottom (TextShortcutKey) + 1, Text = "Clear Shortcut"
};
- _btnShortcut.Accept += (s, e) => { TextShortcut.Text = ""; };
- Add (_btnShortcut);
+ btnShortcut.Accept += (s, e) => { TextShortcutKey.Text = ""; };
+ Add (btnShortcut);
CkbIsTopLevel.CheckedStateChanging += (s, e) =>
{
- if ((_menuItem != null && _menuItem.Parent != null && CkbIsTopLevel.CheckedState == CheckState.Checked)
- || (_menuItem == null && _hasParent && CkbIsTopLevel.CheckedState == CheckState.Checked))
+ if ((_menuItem != null && _menuItem.Parent != null && e.NewValue == CheckState.Checked)
+ || (_menuItem == null && _hasParent && e.NewValue == CheckState.Checked))
{
MessageBox.ErrorQuery (
"Invalid IsTopLevel",
"Only menu bar can have top level menu item!",
"Ok"
);
- CkbIsTopLevel.CheckedState = CheckState.UnChecked;
+ e.Cancel = true;
return;
}
- if (CkbIsTopLevel.CheckedState == CheckState.Checked)
+ if (e.NewValue == CheckState.Checked)
{
CkbSubMenu.CheckedState = CheckState.UnChecked;
CkbSubMenu.SetNeedsDisplay ();
TextHelp.Enabled = true;
TextAction.Enabled = true;
-
- TextShortcut.Enabled =
- CkbIsTopLevel.CheckedState == CheckState.UnChecked && CkbSubMenu.CheckedState == CheckState.UnChecked;
+ TextShortcutKey.Enabled = true;
}
else
{
@@ -280,13 +235,15 @@ bool CheckShortcut (KeyCode k, bool pre)
{
CkbSubMenu.CheckedState = CheckState.Checked;
CkbSubMenu.SetNeedsDisplay ();
- TextShortcut.Enabled = false;
+ TextShortcutKey.Enabled = false;
}
TextHelp.Text = "";
TextHelp.Enabled = false;
TextAction.Text = "";
- TextAction.Enabled = false;
+
+ TextShortcutKey.Enabled =
+ e.NewValue == CheckState.Checked && CkbSubMenu.CheckedState == CheckState.UnChecked;
}
};
@@ -300,8 +257,8 @@ bool CheckShortcut (KeyCode k, bool pre)
TextHelp.Enabled = false;
TextAction.Text = "";
TextAction.Enabled = false;
- TextShortcut.Text = "";
- TextShortcut.Enabled = false;
+ TextShortcutKey.Text = "";
+ TextShortcutKey.Enabled = false;
}
else
{
@@ -309,14 +266,17 @@ bool CheckShortcut (KeyCode k, bool pre)
{
CkbIsTopLevel.CheckedState = CheckState.Checked;
CkbIsTopLevel.SetNeedsDisplay ();
- TextShortcut.Enabled = false;
+ TextShortcutKey.Enabled = true;
}
TextHelp.Enabled = true;
TextAction.Enabled = true;
- TextShortcut.Enabled =
- CkbIsTopLevel.CheckedState == CheckState.UnChecked && CkbSubMenu.CheckedState == CheckState.UnChecked;
+ if (_hasParent)
+ {
+ TextShortcutKey.Enabled = CkbIsTopLevel.CheckedState == CheckState.UnChecked
+ && e.NewValue == CheckState.UnChecked;
+ }
}
};
@@ -337,7 +297,8 @@ bool CheckShortcut (KeyCode k, bool pre)
public RadioGroup RbChkStyle { get; }
public TextView TextAction { get; }
public TextField TextHelp { get; }
- public TextField TextShortcut { get; }
+ public TextField TextHotKey { get; }
+ public TextField TextShortcutKey { get; }
public TextField TextTitle { get; }
public Action CreateAction (MenuItem menuItem, DynamicMenuItem item)
@@ -391,17 +352,20 @@ public void EditMenuBarItem (MenuItem menuItem)
TextTitle.Text = menuItem?.Title ?? "";
TextHelp.Text = menuItem?.Help ?? "";
- TextAction.Text = menuItem != null && menuItem.Action != null
+ TextAction.Text = menuItem.Action != null
? GetTargetAction (menuItem.Action)
: string.Empty;
+ TextHotKey.Text = menuItem?.HotKey != Key.Empty ? menuItem.HotKey.ToString () : "";
CkbIsTopLevel.CheckedState = IsTopLevel (menuItem) ? CheckState.Checked : CheckState.UnChecked;
CkbSubMenu.CheckedState = HasSubMenus (menuItem) ? CheckState.Checked : CheckState.UnChecked;
CkbNullCheck.CheckedState = menuItem.AllowNullChecked ? CheckState.Checked : CheckState.UnChecked;
- TextHelp.Enabled = CkbSubMenu.CheckedState == CheckState.Checked;
- TextAction.Enabled = CkbSubMenu.CheckedState == CheckState.Checked;
+ TextHelp.Enabled = CkbSubMenu.CheckedState == CheckState.UnChecked;
+ TextAction.Enabled = CkbSubMenu.CheckedState == CheckState.UnChecked;
RbChkStyle.SelectedItem = (int)(menuItem?.CheckType ?? MenuItemCheckStyle.NoCheck);
- TextShortcut.Text = menuItem?.ShortcutTag ?? "";
- TextShortcut.Enabled = CkbIsTopLevel.CheckedState == CheckState.UnChecked && CkbSubMenu.CheckedState == CheckState.UnChecked;
+ TextShortcutKey.Text = menuItem?.ShortcutTag ?? "";
+
+ TextShortcutKey.Enabled = CkbIsTopLevel.CheckedState == CheckState.Checked && CkbSubMenu.CheckedState == CheckState.UnChecked
+ || CkbIsTopLevel.CheckedState == CheckState.UnChecked && CkbSubMenu.CheckedState == CheckState.UnChecked;
}
public DynamicMenuItem EnterMenuItem ()
@@ -414,12 +378,13 @@ public DynamicMenuItem EnterMenuItem ()
TextTitle.Text = m.Title;
TextHelp.Text = m.Help;
TextAction.Text = m.Action;
+ TextHotKey.Text = m.HotKey ?? string.Empty;
CkbIsTopLevel.CheckedState = CheckState.UnChecked;
CkbSubMenu.CheckedState = !_hasParent ? CheckState.Checked : CheckState.UnChecked;
CkbNullCheck.CheckedState = CheckState.UnChecked;
TextHelp.Enabled = _hasParent;
TextAction.Enabled = _hasParent;
- TextShortcut.Enabled = _hasParent;
+ TextShortcutKey.Enabled = _hasParent;
}
else
{
@@ -466,12 +431,13 @@ public DynamicMenuItem EnterMenuItem ()
Title = TextTitle.Text,
Help = TextHelp.Text,
Action = TextAction.Text,
+ HotKey = TextHotKey.Text,
IsTopLevel = CkbIsTopLevel?.CheckedState == CheckState.Checked,
- HasSubMenu = CkbSubMenu?.CheckedState == CheckState.UnChecked,
+ HasSubMenu = CkbSubMenu?.CheckedState == CheckState.Checked,
CheckStyle = RbChkStyle.SelectedItem == 0 ? MenuItemCheckStyle.NoCheck :
RbChkStyle.SelectedItem == 1 ? MenuItemCheckStyle.Checked :
MenuItemCheckStyle.Radio,
- Shortcut = TextShortcut.Text,
+ ShortcutKey = TextShortcutKey.Text,
AllowNullChecked = CkbNullCheck?.CheckedState == CheckState.Checked,
};
}
@@ -515,10 +481,11 @@ private void CleanEditMenuBarItem ()
TextTitle.Text = "";
TextHelp.Text = "";
TextAction.Text = "";
+ TextHotKey.Text = "";
CkbIsTopLevel.CheckedState = CheckState.UnChecked;
CkbSubMenu.CheckedState = CheckState.UnChecked;
RbChkStyle.SelectedItem = (int)MenuItemCheckStyle.NoCheck;
- TextShortcut.Text = "";
+ TextShortcutKey.Text = "";
}
private string GetTargetAction (Action action)
@@ -580,7 +547,7 @@ public DynamicMenuBarSample ()
{
DataContext = new ();
- var _frmDelimiter = new FrameView
+ var frmDelimiter = new FrameView
{
X = Pos.Center (),
Y = 3,
@@ -589,114 +556,117 @@ public DynamicMenuBarSample ()
Title = "Shortcut Delimiter:"
};
- var _txtDelimiter = new TextField
+ var txtDelimiter = new TextField
{
- X = Pos.Center (), Width = 2, Text = MenuBar.ShortcutDelimiter.ToString ()
+ X = Pos.Center (), Width = 2, Text = Key.Separator.ToString ()
};
- _txtDelimiter.TextChanged += (s, _) =>
- MenuBar.ShortcutDelimiter = _txtDelimiter.Text.ToRunes () [0];
- _frmDelimiter.Add (_txtDelimiter);
-
- Add (_frmDelimiter);
- var _frmMenu = new FrameView { Y = 7, Width = Dim.Percent (50), Height = Dim.Fill (), Title = "Menus:" };
+ var frmMenu = new FrameView { Y = 7, Width = Dim.Percent (50), Height = Dim.Fill (), Title = "Menus:" };
- var _btnAddMenuBar = new Button { Y = 1, Text = "Add a MenuBar" };
- _frmMenu.Add (_btnAddMenuBar);
+ var btnAddMenuBar = new Button { Y = 1, Text = "Add a MenuBar" };
+ frmMenu.Add (btnAddMenuBar);
- var _btnMenuBarUp = new Button { X = Pos.Center (), Text = CM.Glyphs.UpArrow.ToString () };
- _frmMenu.Add (_btnMenuBarUp);
+ var btnMenuBarUp = new Button { X = Pos.Center (), Text = CM.Glyphs.UpArrow.ToString () };
+ frmMenu.Add (btnMenuBarUp);
- var _btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (_btnMenuBarUp), Text = CM.Glyphs.DownArrow.ToString () };
- _frmMenu.Add (_btnMenuBarDown);
+ var btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (btnMenuBarUp), Text = CM.Glyphs.DownArrow.ToString () };
+ frmMenu.Add (btnMenuBarDown);
- var _btnRemoveMenuBar = new Button { Y = 1, Text = "Remove a MenuBar" };
+ var btnRemoveMenuBar = new Button { Y = 1, Text = "Remove a MenuBar" };
- _btnRemoveMenuBar.X = Pos.AnchorEnd (0) - (Pos.Right (_btnRemoveMenuBar) - Pos.Left (_btnRemoveMenuBar));
- _frmMenu.Add (_btnRemoveMenuBar);
+ btnRemoveMenuBar.X = Pos.AnchorEnd (0) - (Pos.Right (btnRemoveMenuBar) - Pos.Left (btnRemoveMenuBar));
+ frmMenu.Add (btnRemoveMenuBar);
- var _btnPrevious = new Button
+ var btnPrevious = new Button
{
- X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnAddMenuBar) + 2, Text = CM.Glyphs.LeftArrow.ToString ()
+ X = Pos.Left (btnAddMenuBar), Y = Pos.Top (btnAddMenuBar) + 2, Text = CM.Glyphs.LeftArrow.ToString ()
};
- _frmMenu.Add (_btnPrevious);
+ frmMenu.Add (btnPrevious);
- var _btnAdd = new Button { Y = Pos.Top (_btnPrevious) + 2, Text = " Add " };
- _btnAdd.X = Pos.AnchorEnd ();
- _frmMenu.Add (_btnAdd);
+ var btnAdd = new Button { Y = Pos.Top (btnPrevious) + 2, Text = " Add " };
+ btnAdd.X = Pos.AnchorEnd ();
+ frmMenu.Add (btnAdd);
- var _btnNext = new Button { X = Pos.X (_btnAdd), Y = Pos.Top (_btnPrevious), Text = CM.Glyphs.RightArrow.ToString () };
- _frmMenu.Add (_btnNext);
+ var btnNext = new Button { X = Pos.X (btnAdd), Y = Pos.Top (btnPrevious), Text = CM.Glyphs.RightArrow.ToString () };
+ frmMenu.Add (btnNext);
- var _lblMenuBar = new Label
+ var lblMenuBar = new Label
{
ColorScheme = Colors.ColorSchemes ["Dialog"],
TextAlignment = Alignment.Center,
- X = Pos.Right (_btnPrevious) + 1,
- Y = Pos.Top (_btnPrevious),
+ X = Pos.Right (btnPrevious) + 1,
+ Y = Pos.Top (btnPrevious),
- Width = Dim.Fill () - Dim.Func (() => _btnAdd.Frame.Width + 1),
+ Width = Dim.Fill () - Dim.Func (() => btnAdd.Frame.Width + 1),
Height = 1
};
- _frmMenu.Add (_lblMenuBar);
- _lblMenuBar.WantMousePositionReports = true;
- _lblMenuBar.CanFocus = true;
- var _lblParent = new Label
+ lblMenuBar.TextChanged += (s, e) =>
+ {
+ if (lblMenuBar.Text.Contains ("_"))
+ {
+ lblMenuBar.Text = lblMenuBar.Text.Replace ("_", "");
+ }
+ };
+ frmMenu.Add (lblMenuBar);
+ lblMenuBar.WantMousePositionReports = true;
+ lblMenuBar.CanFocus = true;
+
+ var lblParent = new Label
{
TextAlignment = Alignment.Center,
- X = Pos.Right (_btnPrevious) + 1,
- Y = Pos.Top (_btnPrevious) + 1,
+ X = Pos.Right (btnPrevious) + 1,
+ Y = Pos.Top (btnPrevious) + 1,
- Width = Dim.Fill () - Dim.Width (_btnAdd) - 1
+ Width = Dim.Fill () - Dim.Width (btnAdd) - 1
};
- _frmMenu.Add (_lblParent);
+ frmMenu.Add (lblParent);
- var _btnPreviowsParent = new Button
+ var btnPreviowsParent = new Button
{
- X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnPrevious) + 1, Text = ".."
+ X = Pos.Left (btnAddMenuBar), Y = Pos.Top (btnPrevious) + 1, Text = ".."
};
- _frmMenu.Add (_btnPreviowsParent);
+ frmMenu.Add (btnPreviowsParent);
_lstMenus = new ()
{
ColorScheme = Colors.ColorSchemes ["Dialog"],
- X = Pos.Right (_btnPrevious) + 1,
- Y = Pos.Top (_btnPrevious) + 2,
- Width = _lblMenuBar.Width,
+ X = Pos.Right (btnPrevious) + 1,
+ Y = Pos.Top (btnPrevious) + 2,
+ Width = lblMenuBar.Width,
Height = Dim.Fill (),
Source = new ListWrapper ([])
};
- _frmMenu.Add (_lstMenus);
+ frmMenu.Add (_lstMenus);
- _lblMenuBar.TabIndex = _btnPrevious.TabIndex + 1;
- _lstMenus.TabIndex = _lblMenuBar.TabIndex + 1;
- _btnNext.TabIndex = _lstMenus.TabIndex + 1;
- _btnAdd.TabIndex = _btnNext.TabIndex + 1;
+ lblMenuBar.TabIndex = btnPrevious.TabIndex + 1;
+ _lstMenus.TabIndex = lblMenuBar.TabIndex + 1;
+ btnNext.TabIndex = _lstMenus.TabIndex + 1;
+ btnAdd.TabIndex = btnNext.TabIndex + 1;
- var _btnRemove = new Button { X = Pos.Left (_btnAdd), Y = Pos.Top (_btnAdd) + 1, Text = "Remove" };
- _frmMenu.Add (_btnRemove);
+ var btnRemove = new Button { X = Pos.Left (btnAdd), Y = Pos.Top (btnAdd) + 1, Text = "Remove" };
+ frmMenu.Add (btnRemove);
- var _btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
- _frmMenu.Add (_btnUp);
+ var btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
+ frmMenu.Add (btnUp);
- var _btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
- _frmMenu.Add (_btnDown);
+ var btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
+ frmMenu.Add (btnDown);
- Add (_frmMenu);
+ Add (frmMenu);
- var _frmMenuDetails = new DynamicMenuBarDetails
+ var frmMenuDetails = new DynamicMenuBarDetails
{
- X = Pos.Right (_frmMenu),
- Y = Pos.Top (_frmMenu),
+ X = Pos.Right (frmMenu),
+ Y = Pos.Top (frmMenu),
Width = Dim.Fill (),
Height = Dim.Fill (2),
Title = "Menu Details:"
};
- Add (_frmMenuDetails);
+ Add (frmMenuDetails);
- _btnMenuBarUp.Accept += (s, e) =>
+ btnMenuBarUp.Accept += (s, e) =>
{
int i = _currentSelectedMenuBar;
@@ -718,7 +688,7 @@ public DynamicMenuBarSample ()
}
};
- _btnMenuBarDown.Accept += (s, e) =>
+ btnMenuBarDown.Accept += (s, e) =>
{
int i = _currentSelectedMenuBar;
@@ -740,7 +710,7 @@ public DynamicMenuBarSample ()
}
};
- _btnUp.Accept += (s, e) =>
+ btnUp.Accept += (s, e) =>
{
int i = _lstMenus.SelectedItem;
MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
@@ -762,7 +732,7 @@ public DynamicMenuBarSample ()
}
};
- _btnDown.Accept += (s, e) =>
+ btnDown.Accept += (s, e) =>
{
int i = _lstMenus.SelectedItem;
MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
@@ -784,7 +754,7 @@ public DynamicMenuBarSample ()
}
};
- _btnPreviowsParent.Accept += (s, e) =>
+ btnPreviowsParent.Accept += (s, e) =>
{
if (_currentMenuBarItem != null && _currentMenuBarItem.Parent != null)
{
@@ -813,18 +783,39 @@ public DynamicMenuBarSample ()
}
};
- var _btnOk = new Button { X = Pos.Right (_frmMenu) + 20, Y = Pos.Bottom (_frmMenuDetails), Text = "Ok" };
- Add (_btnOk);
+ var btnOk = new Button { X = Pos.Right (frmMenu) + 20, Y = Pos.Bottom (frmMenuDetails), Text = "Ok" };
+ Add (btnOk);
- var _btnCancel = new Button { X = Pos.Right (_btnOk) + 3, Y = Pos.Top (_btnOk), Text = "Cancel" };
- _btnCancel.Accept += (s, e) => { SetFrameDetails (_currentEditMenuBarItem); };
- Add (_btnCancel);
+ var btnCancel = new Button { X = Pos.Right (btnOk) + 3, Y = Pos.Top (btnOk), Text = "Cancel" };
+ btnCancel.Accept += (s, e) => { SetFrameDetails (_currentEditMenuBarItem); };
+ Add (btnCancel);
+
+ txtDelimiter.TextChanging += (s, e) =>
+ {
+ if (!string.IsNullOrEmpty (e.NewValue))
+ {
+ Key.Separator = e.NewValue.ToRunes () [0];
+ }
+ else
+ {
+ e.Cancel = true;
+ txtDelimiter.SelectAll ();
+ }
+ };
+ txtDelimiter.TextChanged += (s, _) =>
+ {
+ txtDelimiter.SelectAll ();
+ SetFrameDetails ();
+ };
+ frmDelimiter.Add (txtDelimiter);
+ txtDelimiter.SelectAll ();
+ Add (frmDelimiter);
_lstMenus.SelectedItemChanged += (s, e) => { SetFrameDetails (); };
- _btnOk.Accept += (s, e) =>
+ btnOk.Accept += (s, e) =>
{
- if (string.IsNullOrEmpty (_frmMenuDetails.TextTitle.Text) && _currentEditMenuBarItem != null)
+ if (string.IsNullOrEmpty (frmMenuDetails.TextTitle.Text) && _currentEditMenuBarItem != null)
{
MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok");
}
@@ -832,28 +823,29 @@ public DynamicMenuBarSample ()
{
var menuItem = new DynamicMenuItem
{
- Title = _frmMenuDetails.TextTitle.Text,
- Help = _frmMenuDetails.TextHelp.Text,
- Action = _frmMenuDetails.TextAction.Text,
- IsTopLevel = _frmMenuDetails.CkbIsTopLevel?.CheckedState == CheckState.UnChecked,
- HasSubMenu = _frmMenuDetails.CkbSubMenu?.CheckedState == CheckState.UnChecked,
- CheckStyle = _frmMenuDetails.RbChkStyle.SelectedItem == 0
+ Title = frmMenuDetails.TextTitle.Text,
+ Help = frmMenuDetails.TextHelp.Text,
+ Action = frmMenuDetails.TextAction.Text,
+ HotKey = frmMenuDetails.TextHotKey.Text,
+ IsTopLevel = frmMenuDetails.CkbIsTopLevel?.CheckedState == CheckState.Checked,
+ HasSubMenu = frmMenuDetails.CkbSubMenu?.CheckedState == CheckState.Checked,
+ CheckStyle = frmMenuDetails.RbChkStyle.SelectedItem == 0
? MenuItemCheckStyle.NoCheck
- : _frmMenuDetails.RbChkStyle.SelectedItem == 1
+ : frmMenuDetails.RbChkStyle.SelectedItem == 1
? MenuItemCheckStyle.Checked
: MenuItemCheckStyle.Radio,
- Shortcut = _frmMenuDetails.TextShortcut.Text
+ ShortcutKey = frmMenuDetails.TextShortcutKey.Text
};
UpdateMenuItem (_currentEditMenuBarItem, menuItem, _lstMenus.SelectedItem);
}
};
- _btnAdd.Accept += (s, e) =>
+ btnAdd.Accept += (s, e) =>
{
if (MenuBar == null)
{
MessageBox.ErrorQuery ("Menu Bar Error", "Must add a MenuBar first!", "Ok");
- _btnAddMenuBar.SetFocus ();
+ btnAddMenuBar.SetFocus ();
return;
}
@@ -883,97 +875,50 @@ public DynamicMenuBarSample ()
{
MenuItem newMenu = CreateNewMenu (item, _currentMenuBarItem);
var menuBarItem = _currentMenuBarItem as MenuBarItem;
+ menuBarItem.AddMenuBarItem (newMenu);
- if (menuBarItem == null)
- {
- menuBarItem = new (
- _currentMenuBarItem.Title,
- new [] { newMenu },
- _currentMenuBarItem.Parent
- );
- }
- else if (menuBarItem.Children == null)
- {
- menuBarItem.Children = new [] { newMenu };
- }
- else
- {
- MenuItem [] childrens = menuBarItem.Children;
- Array.Resize (ref childrens, childrens.Length + 1);
- childrens [childrens.Length - 1] = newMenu;
- menuBarItem.Children = childrens;
- }
DataContext.Menus.Add (new () { Title = newMenu.Title, MenuItem = newMenu });
_lstMenus.MoveDown ();
}
};
- _btnRemove.Accept += (s, e) =>
- {
- MenuItem menuItem = DataContext.Menus.Count > 0
+ btnRemove.Accept += (s, e) =>
+ {
+ MenuItem menuItem = (DataContext.Menus.Count > 0 && _lstMenus.SelectedItem > -1
? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
- : null;
-
- if (menuItem != null)
- {
- MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
- childrens [_lstMenus.SelectedItem] = null;
- var i = 0;
+ : _currentEditMenuBarItem);
- foreach (MenuItem c in childrens)
- {
- if (c != null)
- {
- childrens [i] = c;
- i++;
- }
- }
+ if (menuItem != null)
+ {
+ menuItem.RemoveMenuItem ();
- Array.Resize (ref childrens, childrens.Length - 1);
+ if (_currentEditMenuBarItem == menuItem)
+ {
+ _currentEditMenuBarItem = null;
- if (childrens.Length == 0)
- {
- if (_currentMenuBarItem.Parent == null)
- {
- ((MenuBarItem)_currentMenuBarItem).Children = null;
+ if (menuItem.Parent is null)
+ {
+ _currentSelectedMenuBar = Math.Max (Math.Min (_currentSelectedMenuBar, _menuBar.Menus.Length - 1), 0);
+ }
- //_currentMenuBarItem.Action = _frmMenuDetails.CreateAction (_currentEditMenuBarItem, new DynamicMenuItem (_currentMenuBarItem.Title));
- }
- else
- {
- _currentMenuBarItem = new (
- _currentMenuBarItem.Title,
- _currentMenuBarItem.Help,
- _frmMenuDetails.CreateAction (
- _currentEditMenuBarItem,
- new ()
- {
- Title = _currentEditMenuBarItem
- .Title
- }
- ),
- null,
- _currentMenuBarItem.Parent
- );
- }
- }
- else
- {
- ((MenuBarItem)_currentMenuBarItem).Children = childrens;
- }
+ SelectCurrentMenuBarItem ();
+ }
- DataContext.Menus.RemoveAt (_lstMenus.SelectedItem);
+ if (_lstMenus.SelectedItem > -1)
+ {
+ DataContext.Menus?.RemoveAt (_lstMenus.SelectedItem);
+ }
- if (_lstMenus.Source.Count > 0 && _lstMenus.SelectedItem > _lstMenus.Source.Count - 1)
- {
- _lstMenus.SelectedItem = _lstMenus.Source.Count - 1;
- }
+ if (_lstMenus.Source.Count > 0 && _lstMenus.SelectedItem > _lstMenus.Source.Count - 1)
+ {
+ _lstMenus.SelectedItem = _lstMenus.Source.Count - 1;
+ }
- _lstMenus.SetNeedsDisplay ();
- SetFrameDetails ();
- }
- };
+ _lstMenus.SetNeedsDisplay ();
+ SetFrameDetails ();
+ }
+ };
_lstMenus.OpenSelectedItem += (s, e) =>
{
@@ -1001,7 +946,7 @@ public DynamicMenuBarSample ()
SetFrameDetails (menuBarItem);
};
- _btnNext.Accept += (s, e) =>
+ btnNext.Accept += (s, e) =>
{
if (_menuBar != null && _currentSelectedMenuBar + 1 < _menuBar.Menus.Length)
{
@@ -1011,7 +956,7 @@ public DynamicMenuBarSample ()
SelectCurrentMenuBarItem ();
};
- _btnPrevious.Accept += (s, e) =>
+ btnPrevious.Accept += (s, e) =>
{
if (_currentSelectedMenuBar - 1 > -1)
{
@@ -1021,7 +966,7 @@ public DynamicMenuBarSample ()
SelectCurrentMenuBarItem ();
};
- _lblMenuBar.Enter += (s, e) =>
+ lblMenuBar.Enter += (s, e) =>
{
if (_menuBar?.Menus != null)
{
@@ -1030,7 +975,7 @@ public DynamicMenuBarSample ()
}
};
- _btnAddMenuBar.Accept += (s, e) =>
+ btnAddMenuBar.Accept += (s, e) =>
{
var frameDetails = new DynamicMenuBarDetails (null);
DynamicMenuItem item = frameDetails.EnterMenuItem ();
@@ -1047,22 +992,25 @@ public DynamicMenuBarSample ()
}
var newMenu = CreateNewMenu (item) as MenuBarItem;
+ newMenu.AddMenuBarItem ();
- MenuBarItem [] menus = _menuBar.Menus;
- Array.Resize (ref menus, menus.Length + 1);
- menus [^1] = newMenu;
- _menuBar.Menus = menus;
_currentMenuBarItem = newMenu;
_currentMenuBarItem.CheckType = item.CheckStyle;
- _currentSelectedMenuBar = menus.Length - 1;
+
+ if (Key.TryParse (item.ShortcutKey, out Key key))
+ {
+ _currentMenuBarItem.ShortcutKey = key;
+ }
+
+ _currentSelectedMenuBar = _menuBar.Menus.Length - 1;
_menuBar.Menus [_currentSelectedMenuBar] = newMenu;
- _lblMenuBar.Text = newMenu.Title;
+ lblMenuBar.Text = newMenu.Title;
SetListViewSource (_currentMenuBarItem, true);
SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
_menuBar.SetNeedsDisplay ();
};
- _btnRemoveMenuBar.Accept += (s, e) =>
+ btnRemoveMenuBar.Accept += (s, e) =>
{
if (_menuBar == null || _menuBar.Menus.Length == 0)
{
@@ -1071,21 +1019,9 @@ public DynamicMenuBarSample ()
if (_menuBar != null && _menuBar.Menus.Length > 0)
{
- _menuBar.Menus [_currentSelectedMenuBar] = null;
- var i = 0;
+ _currentMenuBarItem.RemoveMenuItem ();
- foreach (MenuBarItem m in _menuBar.Menus)
- {
- if (m != null)
- {
- _menuBar.Menus [i] = m;
- i++;
- }
- }
- MenuBarItem [] menus = _menuBar.Menus;
- Array.Resize (ref menus, menus.Length - 1);
- _menuBar.Menus = menus;
if (_currentSelectedMenuBar - 1 >= 0 && _menuBar.Menus.Length > 0)
{
@@ -1100,15 +1036,16 @@ public DynamicMenuBarSample ()
if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
{
Remove (_menuBar);
+ _menuBar.Dispose ();
_menuBar = null;
DataContext.Menus = new ();
_currentMenuBarItem = null;
_currentSelectedMenuBar = -1;
- _lblMenuBar.Text = string.Empty;
+ lblMenuBar.Text = string.Empty;
}
else
{
- _lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
+ lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
}
SetListViewSource (_currentMenuBarItem, true);
@@ -1120,9 +1057,9 @@ public DynamicMenuBarSample ()
var ustringConverter = new UStringValueConverter ();
ListWrapperConverter listWrapperConverter = new ListWrapperConverter ();
- var lblMenuBar = new Binding (this, "MenuBar", _lblMenuBar, "Text", ustringConverter);
- var lblParent = new Binding (this, "Parent", _lblParent, "Text", ustringConverter);
- var lstMenus = new Binding (this, "Menus", _lstMenus, "Source", listWrapperConverter);
+ var bdgMenuBar = new Binding (this, "MenuBar", lblMenuBar, "Text", ustringConverter);
+ var bdgParent = new Binding (this, "Parent", lblParent, "Text", ustringConverter);
+ var bdgMenus = new Binding (this, "Menus", _lstMenus, "Source", listWrapperConverter);
void SetFrameDetails (MenuItem menuBarItem = null)
{
@@ -1132,7 +1069,7 @@ void SetFrameDetails (MenuItem menuBarItem = null)
{
menuItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
- : null;
+ : _currentEditMenuBarItem;
}
else
{
@@ -1140,13 +1077,13 @@ void SetFrameDetails (MenuItem menuBarItem = null)
}
_currentEditMenuBarItem = menuItem;
- _frmMenuDetails.EditMenuBarItem (menuItem);
- bool f = _btnOk.Enabled == _frmMenuDetails.Enabled;
+ frmMenuDetails.EditMenuBarItem (menuItem);
+ bool f = btnOk.Enabled == frmMenuDetails.Enabled;
if (!f)
{
- _btnOk.Enabled = _frmMenuDetails.Enabled;
- _btnCancel.Enabled = _frmMenuDetails.Enabled;
+ btnOk.Enabled = frmMenuDetails.Enabled;
+ btnCancel.Enabled = frmMenuDetails.Enabled;
}
}
@@ -1154,23 +1091,28 @@ void SelectCurrentMenuBarItem ()
{
MenuBarItem menuBarItem = null;
- if (_menuBar?.Menus != null)
+ if (_menuBar?.Menus is { Length: > 0 })
{
menuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
- _lblMenuBar.Text = menuBarItem.Title;
+ lblMenuBar.Text = menuBarItem.Title;
}
SetFrameDetails (menuBarItem);
_currentMenuBarItem = menuBarItem;
DataContext.Menus = new ();
SetListViewSource (_currentMenuBarItem, true);
- _lblParent.Text = string.Empty;
+ lblParent.Text = string.Empty;
+
+ if (_currentMenuBarItem is null)
+ {
+ lblMenuBar.Text = string.Empty;
+ }
}
- void SetListViewSource (MenuItem _currentMenuBarItem, bool fill = false)
+ void SetListViewSource (MenuItem currentMenuBarItem, bool fill = false)
{
DataContext.Menus = [];
- var menuBarItem = _currentMenuBarItem as MenuBarItem;
+ var menuBarItem = currentMenuBarItem as MenuBarItem;
if (menuBarItem != null && menuBarItem?.Children == null)
{
@@ -1204,103 +1146,123 @@ MenuItem CreateNewMenu (DynamicMenuItem item, MenuItem parent = null)
{
newMenu = new (item.Title, item.Help, null, null, parent);
newMenu.CheckType = item.CheckStyle;
- newMenu.Action = _frmMenuDetails.CreateAction (newMenu, item);
- newMenu.Shortcut = ShortcutHelper.GetShortcutFromTag (item.Shortcut);
+ newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
+
+ if (Key.TryParse (item.ShortcutKey, out Key key))
+ {
+ newMenu.ShortcutKey = key;
+ }
newMenu.AllowNullChecked = item.AllowNullChecked;
}
else if (item.IsTopLevel)
{
newMenu = new MenuBarItem (item.Title, item.Help, null);
- newMenu.Action = _frmMenuDetails.CreateAction (newMenu, item);
+ newMenu.Action = frmMenuDetails.CreateAction (newMenu, item);
+
+ if (Key.TryParse (item.ShortcutKey, out Key key))
+ {
+ newMenu.ShortcutKey = key;
+ }
}
else
{
newMenu = new MenuBarItem (item.Title, item.Help, null);
((MenuBarItem)newMenu).Children [0].Action =
- _frmMenuDetails.CreateAction (newMenu, item);
+ frmMenuDetails.CreateAction (newMenu, item);
- ((MenuBarItem)newMenu).Children [0].Shortcut =
- ShortcutHelper.GetShortcutFromTag (item.Shortcut);
+ if (Key.TryParse (item.ShortcutKey, out Key key))
+ {
+ ((MenuBarItem)newMenu).Children [0].ShortcutKey = key;
+ }
}
return newMenu;
}
- void UpdateMenuItem (MenuItem _currentEditMenuBarItem, DynamicMenuItem menuItem, int index)
+ void UpdateMenuItem (MenuItem currentEditMenuBarItem, DynamicMenuItem menuItem, int index)
{
- _currentEditMenuBarItem.Title = menuItem.Title;
- _currentEditMenuBarItem.Help = menuItem.Help;
- _currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
- var parent = _currentEditMenuBarItem.Parent as MenuBarItem;
+ currentEditMenuBarItem.Title = menuItem.Title;
+ currentEditMenuBarItem.Help = menuItem.Help;
+ currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
- if (parent != null && parent.Children.Length == 1 && _currentEditMenuBarItem.CheckType == MenuItemCheckStyle.Radio)
+ if (currentEditMenuBarItem.Parent is MenuBarItem parent
+ && parent.Children.Length == 1
+ && currentEditMenuBarItem.CheckType == MenuItemCheckStyle.Radio)
{
- _currentEditMenuBarItem.Checked = true;
+ currentEditMenuBarItem.Checked = true;
}
- if (menuItem.IsTopLevel && _currentEditMenuBarItem is MenuBarItem)
+ if (menuItem.IsTopLevel && currentEditMenuBarItem is MenuBarItem)
{
- ((MenuBarItem)_currentEditMenuBarItem).Children = null;
+ ((MenuBarItem)currentEditMenuBarItem).Children = null;
+
+ currentEditMenuBarItem.Action =
+ frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
- _currentEditMenuBarItem.Action =
- _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem);
- SetListViewSource (_currentEditMenuBarItem, true);
+ if (Key.TryParse (menuItem.ShortcutKey, out Key key))
+ {
+ currentEditMenuBarItem.ShortcutKey = key;
+ }
+
+ SetListViewSource (currentEditMenuBarItem, true);
}
else if (menuItem.HasSubMenu)
{
- _currentEditMenuBarItem.Action = null;
+ currentEditMenuBarItem.Action = null;
- if (_currentEditMenuBarItem is MenuBarItem && ((MenuBarItem)_currentEditMenuBarItem).Children == null)
+ if (currentEditMenuBarItem is MenuBarItem && ((MenuBarItem)currentEditMenuBarItem).Children == null)
{
- ((MenuBarItem)_currentEditMenuBarItem).Children = new MenuItem [] { };
+ ((MenuBarItem)currentEditMenuBarItem).Children = new MenuItem [] { };
}
- else if (_currentEditMenuBarItem.Parent != null)
+ else if (currentEditMenuBarItem.Parent != null)
{
- _frmMenuDetails.UpdateParent (ref _currentEditMenuBarItem);
+ frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
}
else
{
- _currentEditMenuBarItem =
+ currentEditMenuBarItem =
new MenuBarItem (
- _currentEditMenuBarItem.Title,
+ currentEditMenuBarItem.Title,
new MenuItem [] { },
- _currentEditMenuBarItem.Parent
+ currentEditMenuBarItem.Parent
);
}
- SetListViewSource (_currentEditMenuBarItem, true);
+ SetListViewSource (currentEditMenuBarItem, true);
}
- else if (_currentEditMenuBarItem is MenuBarItem && _currentEditMenuBarItem.Parent != null)
+ else if (currentEditMenuBarItem is MenuBarItem && currentEditMenuBarItem.Parent != null)
{
- _frmMenuDetails.UpdateParent (ref _currentEditMenuBarItem);
+ frmMenuDetails.UpdateParent (ref currentEditMenuBarItem);
- _currentEditMenuBarItem = new (
+ currentEditMenuBarItem = new (
menuItem.Title,
menuItem.Help,
- _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem),
+ frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem),
null,
- _currentEditMenuBarItem.Parent
+ currentEditMenuBarItem.Parent
);
}
else
{
- if (_currentEditMenuBarItem is MenuBarItem)
+ if (currentEditMenuBarItem is MenuBarItem)
{
- ((MenuBarItem)_currentEditMenuBarItem).Children = null;
+ ((MenuBarItem)currentEditMenuBarItem).Children = null;
DataContext.Menus = new ();
}
- _currentEditMenuBarItem.Action =
- _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem);
+ currentEditMenuBarItem.Action =
+ frmMenuDetails.CreateAction (currentEditMenuBarItem, menuItem);
- _currentEditMenuBarItem.Shortcut =
- ShortcutHelper.GetShortcutFromTag (menuItem.Shortcut);
+ if (Key.TryParse (menuItem.ShortcutKey, out Key key))
+ {
+ currentEditMenuBarItem.ShortcutKey = key;
+ }
}
- if (_currentEditMenuBarItem.Parent == null)
+ if (currentEditMenuBarItem.Parent == null)
{
- DataContext.MenuBar = _currentEditMenuBarItem.Title;
+ DataContext.MenuBar = currentEditMenuBarItem.Title;
}
else
{
@@ -1309,7 +1271,7 @@ void UpdateMenuItem (MenuItem _currentEditMenuBarItem, DynamicMenuItem menuItem,
DataContext.Menus.Add (
new ()
{
- Title = _currentEditMenuBarItem.Title, MenuItem = _currentEditMenuBarItem
+ Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
}
);
}
@@ -1317,12 +1279,12 @@ void UpdateMenuItem (MenuItem _currentEditMenuBarItem, DynamicMenuItem menuItem,
DataContext.Menus [index] =
new ()
{
- Title = _currentEditMenuBarItem.Title, MenuItem = _currentEditMenuBarItem
+ Title = currentEditMenuBarItem.Title, MenuItem = currentEditMenuBarItem
};
}
- _currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
- SetFrameDetails (_currentEditMenuBarItem);
+ currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
+ SetFrameDetails (currentEditMenuBarItem);
}
//_frmMenuDetails.Initialized += (s, e) => _frmMenuDetails.Enabled = false;
@@ -1339,7 +1301,8 @@ public class DynamicMenuItem
public bool HasSubMenu { get; set; }
public string Help { get; set; } = string.Empty;
public bool IsTopLevel { get; set; }
- public string Shortcut { get; set; }
+ public string HotKey { get; set; }
+ public string ShortcutKey { get; set; }
public string Title { get; set; } = "_New";
}
@@ -1347,7 +1310,7 @@ public class DynamicMenuItemList
{
public MenuItem MenuItem { get; set; }
public string Title { get; set; }
- public override string ToString () { return $"{Title}, {MenuItem}"; }
+ public override string ToString () { return $"{Title}, {MenuItem.HotKey}, {MenuItem.ShortcutKey} "; }
}
public class DynamicMenuItemModel : INotifyPropertyChanged
diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs
index 551e4ad36f..828b2dab71 100644
--- a/UICatalog/Scenarios/DynamicStatusBar.cs
+++ b/UICatalog/Scenarios/DynamicStatusBar.cs
@@ -15,7 +15,7 @@ public class DynamicStatusBar : Scenario
{
public override void Main ()
{
-
+ Application.Init ();
Application.Run ().Dispose ();
Application.Shutdown ();
}
@@ -125,58 +125,9 @@ public DynamicStatusBarDetails ()
TextShortcut.KeyDown += (s, e) =>
{
- if (!ProcessKey (e))
- {
- return;
- }
+ TextShortcut.Text = e.ToString ();
- if (CheckShortcut (e.KeyCode, true))
- {
- e.Handled = true;
- }
};
-
- bool ProcessKey (Key ev)
- {
- switch (ev.KeyCode)
- {
- case KeyCode.CursorUp:
- case KeyCode.CursorDown:
- case KeyCode.Tab:
- case KeyCode.Tab | KeyCode.ShiftMask:
- return false;
- }
-
- return true;
- }
-
- bool CheckShortcut (KeyCode k, bool pre)
- {
- Shortcut m = _statusItem != null ? _statusItem : new Shortcut (k, "", null);
-
- if (pre && !ShortcutHelper.PreShortcutValidation (k))
- {
- TextShortcut.Text = "";
-
- return false;
- }
-
- if (!pre)
- {
- return true;
- }
-
- TextShortcut.Text = k.ToString ();
- return true;
- }
-
- TextShortcut.KeyUp += (s, e) =>
- {
- if (CheckShortcut (e.KeyCode, true))
- {
- e.Handled = true;
- }
- };
Add (TextShortcut);
var _btnShortcut = new Button
@@ -210,7 +161,7 @@ public void EditStatusItem (Shortcut statusItem)
? GetTargetAction (statusItem.Action)
: string.Empty;
- TextShortcut.Text = statusItem.CommandView.Text;
+ TextShortcut.Text = statusItem.Key;
}
public DynamicStatusItem EnterStatusItem ()
@@ -238,13 +189,6 @@ public DynamicStatusItem EnterStatusItem ()
}
else
{
- if (!string.IsNullOrEmpty (TextShortcut.Text))
- {
- TextTitle.Text = DynamicStatusBarSample.SetTitleText (
- TextTitle.Text,
- TextShortcut.Text
- );
- }
valid = true;
Application.RequestStop ();
@@ -433,10 +377,6 @@ public DynamicStatusBarSample ()
}
else if (_currentEditStatusItem != null)
{
- _frmStatusBarDetails.TextTitle.Text = SetTitleText (
- _frmStatusBarDetails.TextTitle.Text,
- _frmStatusBarDetails.TextShortcut.Text
- );
var statusItem = new DynamicStatusItem
{
@@ -487,6 +427,7 @@ public DynamicStatusBarSample ()
if (statusItem != null)
{
_statusBar.RemoveShortcut (_currentSelectedStatusBar);
+ statusItem.Dispose ();
DataContext.Items.RemoveAt (_lstItems.SelectedItem);
if (_lstItems.Source.Count > 0 && _lstItems.SelectedItem > _lstItems.Source.Count - 1)
@@ -526,6 +467,7 @@ public DynamicStatusBarSample ()
}
Remove (_statusBar);
+ _statusBar.Dispose ();
_statusBar = null;
DataContext.Items = [];
_currentStatusItem = null;
@@ -588,7 +530,7 @@ void SetListViewSource (Shortcut _currentStatusItem, bool fill = false)
Shortcut CreateNewStatusBar (DynamicStatusItem item)
{
- var newStatusItem = new Shortcut (Key.Empty, item.Title, null);
+ var newStatusItem = new Shortcut (item.Shortcut, item.Title, _frmStatusBarDetails.CreateAction (item));
return newStatusItem;
}
@@ -599,8 +541,9 @@ void UpdateStatusItem (
int index
)
{
- _currentEditStatusItem = CreateNewStatusBar (statusItem);
- //_statusBar.Items [index] = _currentEditStatusItem;
+ _statusBar.Subviews [index].Title = statusItem.Title;
+ ((Shortcut)_statusBar.Subviews [index]).Action = _frmStatusBarDetails.CreateAction (statusItem);
+ ((Shortcut)_statusBar.Subviews [index]).Key = statusItem.Shortcut;
if (DataContext.Items.Count == 0)
{
@@ -624,23 +567,9 @@ int index
public DynamicStatusItemModel DataContext { get; set; }
- public static string SetTitleText (string title, string shortcut)
- {
- string txt = title;
- string [] split = title.Split ('~');
- if (split.Length > 1)
- {
- txt = split [2].Trim ();
- }
- if (string.IsNullOrEmpty (shortcut) || shortcut == "Null")
- {
- return txt;
- }
- return $"~{shortcut}~ {txt}";
- }
}
public class DynamicStatusItem
@@ -662,7 +591,7 @@ public DynamicStatusItemList (string title, Shortcut statusItem)
public Shortcut Shortcut { get; set; }
public string Title { get; set; }
- public override string ToString () { return $"{Title}, {Shortcut}"; }
+ public override string ToString () { return $"{Title}, {Shortcut.Key}"; }
}
public class DynamicStatusItemModel : INotifyPropertyChanged
diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs
index 975775f454..66e8267432 100644
--- a/UICatalog/Scenarios/VkeyPacketSimulator.cs
+++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs
@@ -119,7 +119,7 @@ public override void Main ()
"Keys",
$"'{Key.ToString (
e.KeyCode,
- MenuBar.ShortcutDelimiter
+ Key.Separator
)}' pressed!",
"Ok"
)
diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs
index 25425782db..60353f59fd 100644
--- a/UICatalog/UICatalog.cs
+++ b/UICatalog/UICatalog.cs
@@ -676,7 +676,7 @@ public void ConfigChanged ()
ColorScheme = Colors.ColorSchemes [_topLevelColorScheme];
- MenuBar!.Menus [0].Children [0].Shortcut = (KeyCode)Application.QuitKey;
+ MenuBar!.Menus [0].Children [0].ShortcutKey = Application.QuitKey;
if (StatusBar is { })
{
@@ -700,8 +700,8 @@ public void ConfigChanged ()
{
var item = new MenuItem
{
- Title = $"_{theme.Key}",
- Shortcut = (KeyCode)new Key ((KeyCode)((uint)KeyCode.D1 + schemeCount++))
+ Title = theme.Key == "Dark" ? $"{theme.Key.Substring (0, 3)}_{theme.Key.Substring (3, 1)}" : $"_{theme.Key}",
+ ShortcutKey = new Key ((KeyCode)((uint)KeyCode.D1 + schemeCount++))
.WithCtrl
};
item.CheckType |= MenuItemCheckStyle.Checked;
@@ -735,6 +735,7 @@ public void ConfigChanged ()
ColorScheme = Colors.ColorSchemes [_topLevelColorScheme];
Application.Top!.SetNeedsDisplay ();
};
+ item.ShortcutKey = ((Key)sc.Key [0].ToString ().ToLower ()).WithCtrl;
schemeMenuItems.Add (item);
}
@@ -796,7 +797,7 @@ private MenuItem [] CreateDiagnosticFlagsMenuItems ()
{
var item = new MenuItem
{
- Title = GetDiagnosticsTitle (diag), Shortcut = (KeyCode)new Key (index.ToString () [0]).WithAlt
+ Title = GetDiagnosticsTitle (diag), ShortcutKey = new Key (index.ToString () [0]).WithAlt
};
index++;
item.CheckType |= MenuItemCheckStyle.Checked;
@@ -951,9 +952,8 @@ private MenuItem [] CreateDisabledEnabledMenuBorder ()
List