Files
Terminal.Gui/UICatalog/Scenarios/InteractiveTree.cs
BDisp 0484fc8bf9 Cleans up key handling in drivers (was "fixes VkeyPacketSimulator is broken") (#3078)
* Fixes #3054. VkeyPacketSimulator scenario is broken.

* Fix some key handle and unit tests.

* Remove unnecessary conditional.

* Improves key handling.

* Also allow map capslock to shift with accented characters.

* Change to MemberData.

* Remove unnecessary using.

* Fix merge errors.

* Fixes #3095. WindowsDriver should return the mask keys to IsShift, IsAlt and IsCtrl return the right value.

* Modifiers keys are valid to be handled on key down and key up.

* Map KeyCode.Enter to ConsoleKey.Enter and vice versa.

* Updated ScanCodeMapping table with readable constants

* Documented bugs

* Implemented mapping using MapVirtualKeyEx

* Implemented mapping using MapVirtualKeyEx

* Changed KeyCode special keys to match ConsoleKey values + max unicode codepoint

* Fixed bogus CollectionNavigator impl and tests

* Nuked DeleteChar. renamed InsertChar to Insert

* KeyCode.Enter = ConsoleKey.Enter, not \n

* Code cleanup

* Added diag for keyboard layout name

* Fixed AltGr support (hopefully)

* Simplified code

* Simplified KeyCode by removing ShiftKeys

* Fixed TextView

* Code cleanup

* Fixes cursesdriver (somewhat)

* Code cleanup

* netdriver wip

* Fixed netdriver under WSL

* Turned off debug spew

* Removed old code

---------

Co-authored-by: Tig Kindel <tig@users.noreply.github.com>
Co-authored-by: Tig Kindel <tig@kindel.com>
2024-01-04 12:37:01 -07:00

146 lines
3.4 KiB
C#

using System;
using System.Linq;
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Interactive Tree", Description: "Create nodes and child nodes in TreeView.")]
[ScenarioCategory ("Controls"), ScenarioCategory ("TreeView")]
public class InteractiveTree : Scenario {
TreeView treeView;
public override void Setup ()
{
Win.Title = this.GetName ();
Win.Y = 1; // menu
Win.Height = Dim.Fill (1); // status bar
var menu = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("_File", new MenuItem [] {
new MenuItem ("_Quit", "", () => Quit()),
})
});
Application.Top.Add (menu);
treeView = new TreeView () {
X = 0,
Y = 0,
Width = Dim.Fill (),
Height = Dim.Fill (1),
};
treeView.KeyDown += TreeView_KeyPress;
Win.Add (treeView);
var statusBar = new StatusBar (new StatusItem [] {
new StatusItem(Application.QuitKey, $"{Application.QuitKey} to Quit", () => Quit()),
new StatusItem(KeyCode.CtrlMask | KeyCode.C, "~^C~ Add Child", () => AddChildNode()),
new StatusItem(KeyCode.CtrlMask | KeyCode.T, "~^T~ Add Root", () => AddRootNode()),
new StatusItem(KeyCode.CtrlMask | KeyCode.R, "~^R~ Rename Node", () => RenameNode()),
});
Application.Top.Add (statusBar);
}
private void TreeView_KeyPress (object sender, Key obj)
{
if (obj.KeyCode == KeyCode.Delete) {
var toDelete = treeView.SelectedObject;
if (toDelete == null) {
return;
}
obj.Handled = true;
// if it is a root object remove it
if (treeView.Objects.Contains (toDelete)) {
treeView.Remove (toDelete);
} else {
var parent = treeView.GetParent (toDelete);
if (parent == null) {
MessageBox.ErrorQuery ("Could not delete", $"Parent of '{toDelete}' was unexpectedly null", "Ok");
} else {
//update the model
parent.Children.Remove (toDelete);
//refresh the tree
treeView.RefreshObject (parent);
}
}
}
}
private void RenameNode ()
{
var node = treeView.SelectedObject;
if (node != null) {
if (GetText ("Text", "Enter text for node:", node.Text, out string entered)) {
node.Text = entered;
treeView.RefreshObject (node);
}
}
}
private void AddRootNode ()
{
if (GetText ("Text", "Enter text for node:", "", out string entered)) {
treeView.AddObject (new TreeNode (entered));
}
}
private void AddChildNode ()
{
var node = treeView.SelectedObject;
if (node != null) {
if (GetText ("Text", "Enter text for node:", "", out string entered)) {
node.Children.Add (new TreeNode (entered));
treeView.RefreshObject (node);
}
}
}
private bool GetText (string title, string label, string initialText, out string enteredText)
{
bool okPressed = false;
var ok = new Button ("Ok", is_default: true);
ok.Clicked += (s,e) => { okPressed = true; Application.RequestStop (); };
var cancel = new Button ("Cancel");
cancel.Clicked += (s,e) => { Application.RequestStop (); };
var d = new Dialog (ok, cancel) { Title = title };
var lbl = new Label () {
X = 0,
Y = 1,
Text = label
};
var tf = new TextField () {
Text = initialText,
X = 0,
Y = 2,
Width = Dim.Fill ()
};
d.Add (lbl, tf);
tf.SetFocus ();
Application.Run (d);
enteredText = okPressed ? tf.Text : null;
return okPressed;
}
private void Quit ()
{
Application.RequestStop ();
}
}
}