Files
Terminal.Gui/Examples/UICatalog/Scenarios/ContextMenus.cs
Copilot e7a4df492d Fixes #4050. Rename Command.Select and Selecting to Activate/Activating (#4470)
* Initial plan

* Rename Command.Select to Command.Activate and Selecting to Activating

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Add Activating event propagation to SuperView

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Update all comments and docs referencing Select to Activate

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Fix event log messages in examples to use Activating/Activate

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Revert automatic Activating event propagation that broke tests

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Update docfx documentation to use Activate/Activating terminology

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* renames

* Revert "Add Activating event propagation to SuperView"

This reverts commit 6d82bee9ad.

* added command diagrams

* mermaid

* updated level 3

* again

* Select->Activate in MouseTests.cs

* Update Terminal.Gui/Views/Selectors/FlagSelector.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Refactor: Rename Selecting to Activating in View APIs

Renamed the `Selecting` event and `OnSelecting` method to
`Activating` and `OnActivating` to better reflect their purpose.
Updated all related comments, test method names, variables,
and assertions in `View` and `ViewCommandTests` to align with
the new terminology.

Improved code clarity by using `_` for unused parameters in
lambda expressions. Renamed properties like `HandleSelecting`
to `HandleActivating` and adjusted naming conventions for
consistency (e.g., `OnactivatingCount` to `OnActivatingCount`).

These changes enhance readability, maintainability, and
terminology consistency across the codebase.

* Update Terminal.Gui/Views/Selectors/OptionSelector.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Typos

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: tig <585482+tig@users.noreply.github.com>
Co-authored-by: Tig <tig@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-09 12:42:34 -07:00

275 lines
11 KiB
C#

#nullable enable
using System.Globalization;
using JetBrains.Annotations;
// ReSharper disable AccessToDisposedClosure
namespace UICatalog.Scenarios;
[ScenarioMetadata ("ContextMenus", "Context Menu Sample.")]
[ScenarioCategory ("Menus")]
public class ContextMenus : Scenario
{
private PopoverMenu? _winContextMenu;
private TextField? _tfTopLeft, _tfTopRight, _tfMiddle, _tfBottomLeft, _tfBottomRight;
private readonly List<CultureInfo>? _cultureInfos = Application.SupportedCultures;
private readonly Key _winContextMenuKey = Key.Space.WithCtrl;
private Window? _appWindow;
public override void Main ()
{
// Init
Application.Init ();
// Setup - Create a top-level application window and configure it.
_appWindow = new ()
{
Title = GetQuitKeyAndName (),
Arrangement = ViewArrangement.Fixed,
SchemeName = "Runnable"
};
_appWindow.Initialized += AppWindowOnInitialized;
// Run - Start the application.
Application.Run (_appWindow);
_appWindow.Dispose ();
_appWindow.KeyDown -= OnAppWindowOnKeyDown;
_appWindow.Activating -= OnAppWindowOnActivating;
_winContextMenu?.Dispose ();
// Shutdown - Calling Application.Shutdown is required.
Application.Shutdown ();
return;
void AppWindowOnInitialized (object? sender, EventArgs e)
{
var text = "Context Menu";
var width = 20;
CreateWinContextMenu (Application.Instance);
var label = new Label
{
X = Pos.Center (), Y = 1, Text = $"Press '{_winContextMenuKey}' to open the Window context menu."
};
_appWindow.Add (label);
label = new ()
{
X = Pos.Center (),
Y = Pos.Bottom (label),
Text = $"Press '{PopoverMenu.DefaultKey}' to open the TextField context menu."
};
_appWindow.Add (label);
_tfTopLeft = new () { Id = "_tfTopLeft", Width = width, Text = text };
_appWindow.Add (_tfTopLeft);
_tfTopRight = new () { Id = "_tfTopRight", X = Pos.AnchorEnd (width), Width = width, Text = text };
_appWindow.Add (_tfTopRight);
_tfMiddle = new () { Id = "_tfMiddle", X = Pos.Center (), Y = Pos.Center (), Width = width, Text = text };
_appWindow.Add (_tfMiddle);
_tfBottomLeft = new () { Id = "_tfBottomLeft", Y = Pos.AnchorEnd (1), Width = width, Text = text };
_appWindow.Add (_tfBottomLeft);
_tfBottomRight = new () { Id = "_tfBottomRight", X = Pos.AnchorEnd (width), Y = Pos.AnchorEnd (1), Width = width, Text = text };
_appWindow.Add (_tfBottomRight);
_appWindow.KeyDown += OnAppWindowOnKeyDown;
_appWindow.Activating += OnAppWindowOnActivating;
CultureInfo originalCulture = Thread.CurrentThread.CurrentUICulture;
_appWindow.IsRunningChanged += (_, e) => {
if (!e.Value)
{
Thread.CurrentThread.CurrentUICulture = originalCulture;
} };
}
void OnAppWindowOnActivating (object? s, CommandEventArgs e)
{
if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
{
if (mouseArgs.Flags == MouseFlags.Button3Clicked)
{
// ReSharper disable once AccessToDisposedClosure
_winContextMenu?.MakeVisible (mouseArgs.ScreenPosition);
e.Handled = true;
}
}
}
void OnAppWindowOnKeyDown (object? s, Key e)
{
if (e == _winContextMenuKey)
{
// ReSharper disable once AccessToDisposedClosure
_winContextMenu?.MakeVisible ();
e.Handled = true;
}
}
}
private void CreateWinContextMenu (IApplication? app)
{
_winContextMenu = new (
[
new MenuItem
{
Title = "C_ultures",
SubMenu = GetSupportedCultureMenu (),
},
new Line (),
new MenuItem
{
Title = "_Configuration...",
HelpText = "Show configuration",
Action = () => MessageBox.Query (app,
50,
10,
"Configuration",
"This would be a configuration dialog",
"Ok"
)
},
new MenuItem
{
Title = "M_ore options",
SubMenu = new (
[
new ()
{
Title = "_Setup...",
HelpText = "Perform setup",
Action = () => MessageBox
.Query (app,
50,
10,
"Setup",
"This would be a setup dialog",
"Ok"
),
Key = Key.T.WithCtrl
},
new ()
{
Title = "_Maintenance...",
HelpText = "Maintenance mode",
Action = () => MessageBox
.Query (app,
50,
10,
"Maintenance",
"This would be a maintenance dialog",
"Ok"
)
}
])
},
new Line (),
new MenuItem
{
Title = "_Quit",
Action = () => Application.RequestStop ()
}
])
{
Key = _winContextMenuKey
};
Application.Popover?.Register (_winContextMenu);
}
private Menu GetSupportedCultureMenu ()
{
List<MenuItem> supportedCultures = [];
int index = -1;
foreach (CultureInfo c in _cultureInfos!)
{
MenuItem culture = new ();
culture.CommandView = new CheckBox { CanFocus = false };
if (index == -1)
{
// Create English because GetSupportedCultures doesn't include it
culture.Id = "_English";
culture.Title = "_English";
culture.HelpText = "en-US";
((CheckBox)culture.CommandView).CheckedState =
Thread.CurrentThread.CurrentUICulture.Name == "en-US" ? CheckState.Checked : CheckState.UnChecked;
CreateAction (supportedCultures, culture);
supportedCultures.Add (culture);
index++;
culture = new ();
culture.CommandView = new CheckBox { CanFocus = false };
}
culture.Id = $"_{c.Parent.EnglishName}";
culture.Title = $"_{c.Parent.EnglishName}";
culture.HelpText = c.Name;
((CheckBox)culture.CommandView).CheckedState =
Thread.CurrentThread.CurrentUICulture.Name == culture.HelpText ? CheckState.Checked : CheckState.UnChecked;
CreateAction (supportedCultures, culture);
supportedCultures.Add (culture);
}
Menu menu = new (supportedCultures.ToArray ());
return menu;
void CreateAction (List<MenuItem> cultures, MenuItem culture)
{
culture.Action += () =>
{
Thread.CurrentThread.CurrentUICulture = new (culture.HelpText);
foreach (MenuItem item in cultures)
{
((CheckBox)item.CommandView).CheckedState =
Thread.CurrentThread.CurrentUICulture.Name == item.HelpText ? CheckState.Checked : CheckState.UnChecked;
}
};
}
}
public override List<Key> GetDemoKeyStrokes ()
{
List<Key> keys =
[
Key.F10.WithShift,
Key.Esc,
Key.Space.WithCtrl,
Key.CursorDown,
Key.Enter,
Key.F10.WithShift,
Key.Esc,
Key.Tab,
Key.Space.WithCtrl,
Key.CursorDown,
Key.CursorDown,
Key.Enter,
Key.F10.WithShift,
Key.Esc,
Key.Tab,
Key.Space.WithCtrl,
Key.CursorDown,
Key.CursorDown,
Key.CursorDown,
Key.Enter,
Key.F10.WithShift,
Key.Esc
];
return keys;
}
}