Partially modernizes Scenarios (#4512)

This commit is contained in:
Tig
2025-12-19 20:02:04 -07:00
committed by GitHub
parent 8f4ad8a7d4
commit af0efb3c64
17 changed files with 1307 additions and 1045 deletions

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace UICatalog.Scenarios;
@@ -14,24 +9,27 @@ public class Bars : Scenario
public override void Main ()
{
Application.Init ();
Runnable app = new ();
using IApplication app = Application.Instance;
app.IsModalChanged += App_Loaded;
using Runnable mainWindow = new ();
Application.Run (app);
app.Dispose ();
Application.Shutdown ();
mainWindow.IsModalChanged += App_Loaded;
app.Run (mainWindow);
}
// Setting everything up in Loaded handler because we change the
// QuitKey and it only sticks if changed after init
// QuitKey it only sticks if changed after init
private void App_Loaded (object sender, EventArgs e)
{
Application.TopRunnableView!.Title = GetQuitKeyAndName ();
if (sender is not Runnable mainWindow)
{
return;
}
ObservableCollection<string> eventSource = new ();
ListView eventLog = new ListView ()
ListView eventLog = new ()
{
Title = "Event Log",
X = Pos.AnchorEnd (),
@@ -41,7 +39,7 @@ public class Bars : Scenario
Source = new ListWrapper<string> (eventSource)
};
eventLog.Border!.Thickness = new (0, 1, 0, 0);
Application.TopRunnableView.Add (eventLog);
mainWindow.Add (eventLog);
FrameView menuBarLikeExamples = new ()
{
@@ -49,30 +47,30 @@ public class Bars : Scenario
X = 0,
Y = 0,
Width = Dim.Fill () - Dim.Width (eventLog),
Height = Dim.Percent(33),
Height = Dim.Percent (33)
};
Application.TopRunnableView.Add (menuBarLikeExamples);
mainWindow.Add (menuBarLikeExamples);
Label label = new Label ()
Label label = new ()
{
Title = " Bar:",
X = 0,
Y = 0,
Y = 0
};
menuBarLikeExamples.Add (label);
Bar bar = new Bar
Bar bar = new ()
{
Id = "menuBar-like",
X = Pos.Right (label),
Y = Pos.Top (label),
Width = Dim.Fill (),
Width = Dim.Fill ()
};
ConfigMenuBar (bar);
menuBarLikeExamples.Add (bar);
label = new Label ()
label = new ()
{
Title = " MenuBar:",
X = 0,
@@ -96,80 +94,171 @@ public class Bars : Scenario
X = 0,
Y = Pos.Center (),
Width = Dim.Fill () - Dim.Width (eventLog),
Height = Dim.Percent (33),
Height = Dim.Percent (33)
};
Application.TopRunnableView.Add (menuLikeExamples);
mainWindow.Add (menuLikeExamples);
label = new Label ()
label = new ()
{
Title = "Bar:",
X = 0,
Y = 0,
Y = 0
};
menuLikeExamples.Add (label);
bar = new Bar
bar = new ()
{
Id = "menu-like",
X = 0,
Y = Pos.Bottom(label),
Y = Pos.Bottom (label),
//Width = Dim.Percent (40),
Orientation = Orientation.Vertical,
Orientation = Orientation.Vertical
};
ConfigureMenu (bar);
menuLikeExamples.Add (bar);
label = new Label ()
label = new ()
{
Title = "Menu:",
X = Pos.Right(bar) + 1,
Y = Pos.Top (label),
X = Pos.Right (bar) + 1,
Y = Pos.Top (label)
};
menuLikeExamples.Add (label);
bar = new Menu
bar = new ()
{
Id = "menu",
X = Pos.Left (label),
Y = Pos.Bottom (label),
Y = Pos.Bottom (label)
};
ConfigureMenu (bar);
bar.Arrangement = ViewArrangement.RightResizable;
menuLikeExamples.Add (bar);
label = new Label ()
label = new ()
{
Title = "PopOver Menu (Right click to show):",
X = Pos.Right (bar) + 1,
Y = Pos.Top (label),
Y = Pos.Top (label)
};
menuLikeExamples.Add (label);
Menu popOverMenu = new Menu
Menu popOverMenu = new ()
{
Id = "popupMenu",
X = Pos.Left (label),
Y = Pos.Bottom (label),
Y = Pos.Bottom (label)
};
ConfigureMenu (popOverMenu);
popOverMenu.Arrangement = ViewArrangement.Overlapped;
popOverMenu.Visible = false;
//popOverMenu.Enabled = false;
var toggleShortcut = new Shortcut
Shortcut toggleShortcut = new ()
{
Title = "Toggle Hide",
Text = "App",
BindKeyToApplication = true,
Key = Key.F4.WithCtrl,
Key = Key.F4.WithCtrl
};
popOverMenu.Add (toggleShortcut);
popOverMenu.Accepting += PopOverMenuOnAccept;
menuLikeExamples.Add (popOverMenu);
menuLikeExamples.MouseEvent += MenuLikeExamplesMouseEvent;
FrameView statusBarLikeExamples = new ()
{
Title = "StatusBar-Like Examples",
X = 0,
Y = Pos.AnchorEnd (),
Width = Dim.Width (menuLikeExamples),
Height = Dim.Percent (33)
};
mainWindow.Add (statusBarLikeExamples);
label = new ()
{
Title = " Bar:",
X = 0,
Y = 0
};
statusBarLikeExamples.Add (label);
bar = new()
{
Id = "statusBar-like",
X = Pos.Right (label),
Y = Pos.Top (label),
Width = Dim.Fill (),
Orientation = Orientation.Horizontal
};
ConfigStatusBar (bar);
statusBarLikeExamples.Add (bar);
label = new ()
{
Title = "StatusBar:",
X = 0,
Y = Pos.Bottom (bar) + 1
};
statusBarLikeExamples.Add (label);
bar = new ()
{
Id = "statusBar",
X = Pos.Right (label),
Y = Pos.Top (label),
Width = Dim.Fill ()
};
ConfigStatusBar (bar);
statusBarLikeExamples.Add (bar);
foreach (FrameView frameView in mainWindow.SubViews.OfType<FrameView> ())
{
foreach (Bar barView in frameView.SubViews.OfType<Bar> ())
{
foreach (Shortcut sh in barView.SubViews.OfType<Shortcut> ())
{
sh.Accepting += (_, _) =>
{
eventSource.Add ($"Accept: {sh!.SuperView!.Id} {sh!.CommandView.Text}");
eventLog.MoveDown ();
//args.Handled = true;
};
}
}
}
return;
void MenuLikeExamplesMouseEvent (object _, MouseEventArgs mouse)
{
if (mouse.Flags.HasFlag (MouseFlags.Button3Clicked))
{
popOverMenu.X = mouse.Position.X;
popOverMenu.Y = mouse.Position.Y;
popOverMenu.Visible = true;
//popOverMenu.Enabled = popOverMenu.Visible;
popOverMenu.SetFocus ();
}
else
{
popOverMenu.Visible = false;
//popOverMenu.Enabled = popOverMenu.Visible;
}
}
void PopOverMenuOnAccept (object o, CommandEventArgs args)
{
if (popOverMenu.Visible)
@@ -182,91 +271,8 @@ public class Bars : Scenario
popOverMenu.SetFocus ();
}
}
menuLikeExamples.Add (popOverMenu);
menuLikeExamples.MouseEvent += MenuLikeExamplesMouseEvent;
void MenuLikeExamplesMouseEvent (object _, MouseEventArgs e)
{
if (e.Flags.HasFlag (MouseFlags.Button3Clicked))
{
popOverMenu.X = e.Position.X;
popOverMenu.Y = e.Position.Y;
popOverMenu.Visible = true;
//popOverMenu.Enabled = popOverMenu.Visible;
popOverMenu.SetFocus ();
}
else
{
popOverMenu.Visible = false;
//popOverMenu.Enabled = popOverMenu.Visible;
}
}
FrameView statusBarLikeExamples = new ()
{
Title = "StatusBar-Like Examples",
X = 0,
Y = Pos.AnchorEnd (),
Width = Dim.Width (menuLikeExamples),
Height = Dim.Percent (33),
};
Application.TopRunnableView.Add (statusBarLikeExamples);
label = new Label ()
{
Title = " Bar:",
X = 0,
Y = 0,
};
statusBarLikeExamples.Add (label);
bar = new Bar
{
Id = "statusBar-like",
X = Pos.Right (label),
Y = Pos.Top (label),
Width = Dim.Fill (),
Orientation = Orientation.Horizontal,
};
ConfigStatusBar (bar);
statusBarLikeExamples.Add (bar);
label = new Label ()
{
Title = "StatusBar:",
X = 0,
Y = Pos.Bottom (bar) + 1,
};
statusBarLikeExamples.Add (label);
bar = new StatusBar ()
{
Id = "statusBar",
X = Pos.Right (label),
Y = Pos.Top (label),
Width = Dim.Fill (),
};
ConfigStatusBar (bar);
statusBarLikeExamples.Add (bar);
foreach (FrameView frameView in Application.TopRunnableView.SubViews.Where (f => f is FrameView)!)
{
foreach (Bar barView in frameView.SubViews.Where (b => b is Bar)!)
{
foreach (Shortcut sh in barView.SubViews.Where (s => s is Shortcut)!)
{
sh.Accepting += (o, args) =>
{
eventSource.Add ($"Accept: {sh!.SuperView.Id} {sh!.CommandView.Text}");
eventLog.MoveDown ();
//args.Handled = true;
};
}
}
}
}
//private void SetupContentMenu ()
//{
// Application.TopRunnable.Add (new Label { Text = "Right Click for Context Menu", X = Pos.Center (), Y = 4 });
@@ -407,10 +413,9 @@ public class Bars : Scenario
// Application.MouseEvent -= Application_MouseEvent;
//}
private void ConfigMenuBar (Bar bar)
{
var fileMenuBarItem = new Shortcut
Shortcut fileMenuBarItem = new ()
{
Title = "_File",
HelpText = "File Menu",
@@ -418,7 +423,7 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
var editMenuBarItem = new Shortcut
Shortcut editMenuBarItem = new ()
{
Title = "_Edit",
HelpText = "Edit Menu",
@@ -426,7 +431,7 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
var helpMenuBarItem = new Shortcut
Shortcut helpMenuBarItem = new ()
{
Title = "_Help",
HelpText = "Halp Menu",
@@ -439,8 +444,7 @@ public class Bars : Scenario
private void ConfigureMenu (Bar bar)
{
var shortcut1 = new Shortcut
Shortcut shortcut1 = new ()
{
Title = "Z_igzag",
Key = Key.I.WithCtrl,
@@ -448,7 +452,7 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
var shortcut2 = new Shortcut
Shortcut shortcut2 = new ()
{
Title = "Za_G",
Text = "Gonna zag",
@@ -456,7 +460,7 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
var shortcut3 = new Shortcut
Shortcut shortcut3 = new ()
{
Title = "_Three",
Text = "The 3rd item",
@@ -464,13 +468,13 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
var line = new Line ()
Line line = new ()
{
X = -1,
Width = Dim.Fill ()! + 1
};
var shortcut4 = new Shortcut
Shortcut shortcut4 = new ()
{
Title = "_Four",
Text = "Below the line",
@@ -478,39 +482,40 @@ public class Bars : Scenario
HighlightStates = MouseState.In
};
shortcut4.CommandView = new CheckBox ()
shortcut4.CommandView = new CheckBox
{
Title = shortcut4.Title,
HighlightStates = MouseState.None,
CanFocus = false
};
// This ensures the checkbox state toggles when the hotkey of Title is pressed.
shortcut4.Accepting += (sender, args) => args.Handled = true;
shortcut4.Accepting += (_, args) => args.Handled = true;
bar.Add (shortcut1, shortcut2, shortcut3, line, shortcut4);
}
public void ConfigStatusBar (Bar bar)
{
var shortcut = new Shortcut
Shortcut shortcut = new ()
{
Text = "Quit",
Title = "Q_uit",
Key = Key.Z.WithCtrl,
Key = Key.Z.WithCtrl
};
bar.Add (shortcut);
shortcut = new Shortcut
shortcut = new ()
{
Text = "Help Text",
Title = "Help",
Key = Key.F1,
Key = Key.F1
};
bar.Add (shortcut);
shortcut = new Shortcut
shortcut = new ()
{
Title = "_Show/Hide",
Key = Key.F10,
@@ -518,45 +523,48 @@ public class Bars : Scenario
{
CanFocus = false,
Text = "_Show/Hide"
},
}
};
bar.Add (shortcut);
var button1 = new Button
Button button1 = new ()
{
Text = "I'll Hide",
Text = "I'll Hide"
// Visible = false
};
button1.Accepting += Button_Clicked;
button1.Accepting += ButtonClicked;
bar.Add (button1);
shortcut.Accepting += (s, e) =>
{
button1.Visible = !button1.Visible;
button1.Enabled = button1.Visible;
e.Handled = true;
};
shortcut.Accepting += (_, e) =>
{
button1.Visible = !button1.Visible;
button1.Enabled = button1.Visible;
e.Handled = true;
};
bar.Add (new Label
{
HotKeySpecifier = new Rune ('_'),
Text = "Fo_cusLabel",
CanFocus = true
});
bar.Add (
new Label
{
HotKeySpecifier = new ('_'),
Text = "Fo_cusLabel",
CanFocus = true
});
var button2 = new Button
Button middleButton = new ()
{
Text = "Or me!",
Text = "Or me!"
};
button2.Accepting += (s, e) => Application.RequestStop ();
middleButton.Accepting += (s, _) => (s as View)?.App!.RequestStop ();
bar.Add (button2);
bar.Add (middleButton);
return;
void Button_Clicked (object sender, EventArgs e) { MessageBox.Query ((sender as View)?.App, "Hi", $"You clicked {sender}"); }
static void ButtonClicked (object sender, EventArgs e)
{
MessageBox.Query ((sender as View)?.App!, "Hi", $"You clicked {sender}");
}
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using JetBrains.Annotations;
using System.Text;
namespace UICatalog.Scenarios;
@@ -14,30 +10,29 @@ public class Buttons : Scenario
public override void Main ()
{
Application.Init ();
using IApplication app = Application.Instance;
Window main = new ()
{
Title = GetQuitKeyAndName ()
};
using Window main = new ();
main.Title = GetQuitKeyAndName ();
// Add a label & text field so we can demo IsDefault
var editLabel = new Label { X = 0, Y = 0, Text = "TextField (to demo IsDefault):" };
Label editLabel = new () { X = 0, Y = 0, Text = "TextField (to demo IsDefault):" };
main.Add (editLabel);
// Add a TextField using Absolute layout.
var edit = new TextField { X = 31, Width = 15, HotKey = Key.Y.WithAlt };
// Add a TextField using Absolute layout.
TextField edit = new () { X = 31, Width = 15, HotKey = Key.Y.WithAlt };
main.Add (edit);
// This is the default button (IsDefault = true); if user presses ENTER in the TextField
// the scenario will quit
var defaultButton = new Button { X = Pos.Center (), Y = Pos.AnchorEnd (), IsDefault = true, Text = "_Quit" };
Button defaultButton = new () { X = Pos.Center (), Y = Pos.AnchorEnd (), IsDefault = true, Text = "_Quit" };
main.Add (defaultButton);
// Note we handle Accept on main, not defaultButton
main.Accepting += (s, e) => Application.RequestStop ();
main.Accepting += (s, _) => (s as View)?.App!.RequestStop ();
var swapButton = new Button
Button swapButton = new ()
{
X = 50,
Width = 45,
@@ -46,47 +41,41 @@ public class Buttons : Scenario
SchemeName = "Error"
};
swapButton.Accepting += (s, e) =>
{
e.Handled = !swapButton.IsDefault;
defaultButton.IsDefault = !defaultButton.IsDefault;
swapButton.IsDefault = !swapButton.IsDefault;
};
swapButton.Accepting += (_, e) =>
{
e.Handled = !swapButton.IsDefault;
defaultButton.IsDefault = !defaultButton.IsDefault;
swapButton.IsDefault = !swapButton.IsDefault;
};
defaultButton.Accepting += (s, e) =>
{
e.Handled = !defaultButton.IsDefault;
{
e.Handled = !defaultButton.IsDefault;
if (e.Handled)
{
MessageBox.ErrorQuery ((s as View)?.App, "Error", "This button is no longer the Quit button; the Swap Default button is.", "_Ok");
}
};
if (e.Handled)
{
MessageBox.ErrorQuery (
(s as View)?.App!,
"Error",
"This button is no longer the Quit button; the Swap Default button is.",
"_Ok");
}
};
main.Add (swapButton);
static void DoMessage (Button button, string txt)
{
button.Accepting += (s, e) =>
{
string btnText = button.Text;
MessageBox.Query ((s as View)?.App, "Message", $"Did you click {txt}?", "Yes", "No");
e.Handled = true;
};
}
var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " };
Label colorButtonsLabel = new () { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " };
main.Add (colorButtonsLabel);
View prev = colorButtonsLabel;
foreach (KeyValuePair<string, Scheme> scheme in SchemeManager.GetSchemesForCurrentTheme ())
{
var colorButton = new Button
Button colorButton = new ()
{
X = Pos.Right (prev),
Y = Pos.Y (colorButtonsLabel),
Text = $"_{scheme.Key}",
SchemeName = scheme.Key,
SchemeName = scheme.Key
};
DoMessage (colorButton, colorButton.Text);
main.Add (colorButton);
@@ -108,59 +97,62 @@ public class Buttons : Scenario
// Note the 'N' in 'Newline' will be the hotkey
main.Add (
button = new () { X = 2, Y = Pos.Bottom (button) + 1, Height = 2, Text = "a Newline\nin the button" }
button = new () { X = 2, Y = Pos.Bottom (button), Height = 2, Text = "a Newline\nin the button" }
);
button.Accepting += (s, e) =>
{
MessageBox.Query ((s as View)?.App, "Message", "Question?", "Yes", "No");
e.Handled = true;
};
var textChanger = new Button { X = 2, Y = Pos.Bottom (button) + 1, Text = "Te_xt Changer" };
button.Accepting += (s, e) =>
{
MessageBox.Query ((s as View)?.App!, "Message", "Is There A Question?", "Yes", "No");
e.Handled = true;
};
var textChanger = new Button { X = 2, Y = Pos.Bottom (button), Text = "Te_xt Changer" };
main.Add (textChanger);
textChanger.Accepting += (s, e) =>
{
textChanger.Text += "!";
e.Handled = true;
};
textChanger.Accepting += (_, e) =>
{
textChanger.Text += "!";
e.Handled = true;
};
main.Add (
button = new ()
{
X = Pos.Right (textChanger) + 2,
Y = Pos.Y (textChanger),
Text = "Lets see if this will move as \"Text Changer\" grows"
Text = """This will move as "Text Changer" grows"""
}
);
button.Accepting += (sender, args) => { args.Handled = true; };
var removeButton = new Button
button.Accepting += (_, args) => { args.Handled = true; };
Button removeButton = new ()
{
X = 2, Y = Pos.Bottom (button) + 1,
X = 2, Y = Pos.Bottom (button),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Error),
Text = "Remove this button"
Title = "Press to remove this button"
};
main.Add (removeButton);
// This in interesting test case because `moveBtn` and below are laid out relative to this one!
removeButton.Accepting += (s, e) =>
{
removeButton.Visible = false;
e.Handled = true;
};
removeButton.Accepting += (_, e) =>
{
removeButton.Visible = false;
e.Handled = true;
};
var computedFrame = new FrameView
FrameView computedFrame = new ()
{
X = 0,
Y = Pos.Bottom (removeButton) + 1,
Y = Pos.Bottom (removeButton),
Width = Dim.Percent (50),
Height = 6,
Title = "Computed Layout"
Title = "Frame (Width = 50%)"
};
main.Add (computedFrame);
// Demonstrates how changing the View.Frame property can move Views
var moveBtn = new Button
Button moveBtn = new ()
{
X = 0,
Y = Pos.Center () - 1,
@@ -169,88 +161,82 @@ public class Buttons : Scenario
Text = "Move This \u263b Button v_ia Pos"
};
moveBtn.Accepting += (s, e) =>
{
moveBtn.X = moveBtn.Frame.X + 5;
e.Handled = true;
};
moveBtn.Accepting += (_, e) =>
{
moveBtn.X = moveBtn.Frame.X + 5;
e.Handled = true;
};
computedFrame.Add (moveBtn);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtn = new Button
Button sizeBtn = new ()
{
Y = Pos.Center () + 1,
X = 0,
Width = 30,
Text = "Grow This \u263a Button _via Pos",
SchemeName = "Error",
SchemeName = "Error"
};
sizeBtn.Accepting += (s, e) =>
{
sizeBtn.Width = sizeBtn.Frame.Width + 5;
e.Handled = true;
};
sizeBtn.Accepting += (_, e) =>
{
sizeBtn.Width = sizeBtn.Frame.Width + 5;
e.Handled = true;
};
computedFrame.Add (sizeBtn);
var absoluteFrame = new FrameView
FrameView absoluteFrame = new ()
{
X = Pos.Right (computedFrame),
Y = Pos.Bottom (removeButton) + 1,
Y = Pos.Top (computedFrame),
Width = Dim.Fill (),
Height = 6,
Title = "Absolute Layout"
Height = Dim.Height (computedFrame),
Title = "Frame (Width = Fill)"
};
main.Add (absoluteFrame);
// Demonstrates how changing the View.Frame property can move Views
var moveBtnA = new Button { SchemeName = "Error", Text = "Move This Button via Frame" };
Button moveBtnA = new () { SchemeName = "Error", Text = "Move This Button via Frame" };
moveBtnA.Accepting += (s, e) =>
{
moveBtnA.Frame = new (
moveBtnA.Frame.X + 5,
moveBtnA.Frame.Y,
moveBtnA.Frame.Width,
moveBtnA.Frame.Height
);
e.Handled = true;
};
moveBtnA.Accepting += (_, e) =>
{
moveBtnA.Frame = moveBtnA.Frame with { X = moveBtnA.Frame.X + 5 };
e.Handled = true;
};
absoluteFrame.Add (moveBtnA);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtnA = new Button
Button sizeBtnA = new ()
{
Y = 2, SchemeName = "Error", Text = " ~  s  gui.cs   master ↑_10 = Сохранить"
Y = 2, SchemeName = "Error", Text = " ~  s  gui.cs   main ↑_10 = Сохранить"
};
sizeBtnA.Accepting += (s, e) =>
{
sizeBtnA.Frame = new (
sizeBtnA.Frame.X,
sizeBtnA.Frame.Y,
sizeBtnA.Frame.Width + 5,
sizeBtnA.Frame.Height
);
e.Handled = true;
};
sizeBtnA.Accepting += (_, e) =>
{
sizeBtnA.Frame = sizeBtnA.Frame with { Width = sizeBtnA.Frame.Width + 5 };
e.Handled = true;
};
absoluteFrame.Add (sizeBtnA);
var label = new Label
Label label = new ()
{
X = 2, Y = Pos.Bottom (computedFrame) + 1,
Text = "Text Ali_gnment (changes the four buttons above): "
X = 2, Y = Pos.Bottom (computedFrame),
// ReSharper disable once StringLiteralTypo
Text = "Text Ali_gnment (changes all buttons): "
};
main.Add (label);
OptionSelector<Alignment> osAlignment = new ()
{
X = 4,
Y = Pos.Bottom (label) + 1,
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Width = 20,
Value = Alignment.Center,
AssignHotKeys = true,
Title = "_9 OptionSelector",
BorderStyle = LineStyle.Dotted,
BorderStyle = LineStyle.Dotted
// CanFocus = false
};
main.Add (osAlignment);
@@ -287,143 +273,211 @@ public class Buttons : Scenario
return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i));
}
var mhkb = "Click to Change th_is Button's Hotkey";
var moveHotKeyBtn = new Button
Button moveHotKeyBtn = new ()
{
X = 2,
Y = Pos.Bottom (osAlignment) + 1,
Y = Pos.Bottom (osAlignment),
Width = Dim.Width (computedFrame) - 2,
SchemeName = "Runnable",
Text = mhkb
Text = "Click to Change th_is Button's Hotkey"
};
moveHotKeyBtn.Accepting += (s, e) =>
{
moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
e.Handled = true;
};
moveHotKeyBtn.Accepting += (_, e) =>
{
moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
e.Handled = true;
};
main.Add (moveHotKeyBtn);
var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
var moveUnicodeHotKeyBtn = new Button
Button moveUnicodeHotKeyBtn = new ()
{
X = Pos.Left (absoluteFrame) + 1,
Y = Pos.Bottom (osAlignment) + 1,
Y = Pos.Bottom (osAlignment),
Width = Dim.Width (absoluteFrame) - 2,
SchemeName = "Runnable",
Text = muhkb
Text = " ~  s  gui.cs   main ↑10 = Сохранить"
};
moveUnicodeHotKeyBtn.Accepting += (s, e) =>
{
moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
e.Handled = true;
};
moveUnicodeHotKeyBtn.Accepting += (_, e) =>
{
moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
e.Handled = true;
};
main.Add (moveUnicodeHotKeyBtn);
osAlignment.ValueChanged += (s, args) =>
osAlignment.ValueChanged += (_, args) =>
{
if (args.Value is null)
{
return;
}
Alignment newValue = args.Value.Value;
moveBtn.TextAlignment = newValue;
sizeBtn.TextAlignment = newValue;
moveBtnA.TextAlignment = newValue;
sizeBtnA.TextAlignment = newValue;
moveHotKeyBtn.TextAlignment = newValue;
moveUnicodeHotKeyBtn.TextAlignment = newValue;
// ReSharper disable once AccessToDisposedClosure
SetTextAlignmentForAllButtons (main, args.Value.Value);
};
label = new ()
{
X = 0,
Y = Pos.Bottom (moveUnicodeHotKeyBtn) + 1,
Title = "_Numeric Up/Down (press-and-hold):",
Title = "Numeric Up/Down (press-and-_hold):"
};
var numericUpDown = new NumericUpDown<int>
NumericUpDown<int> numericUpDown = new ()
{
Value = 69,
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Y = Pos.Top (label)
};
numericUpDown.ValueChanged += NumericUpDown_ValueChanged;
numericUpDown.ValueChanged += NumericUpDownValueChanged;
void NumericUpDown_ValueChanged (object sender, EventArgs<int> e) { }
void NumericUpDownValueChanged (object sender, EventArgs<int> e) { }
main.Add (label, numericUpDown);
label = new ()
{
X = 0,
Y = Pos.Bottom (numericUpDown) + 1,
Title = "_No Repeat:"
Y = Pos.Bottom (numericUpDown),
// ReSharper disable once StringLiteralTypo
Title = "No Repea_t:"
};
var noRepeatAcceptCount = 0;
var noRepeatButton = new Button
Button noRepeatButton = new ()
{
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Title = $"Accept Cou_nt: {noRepeatAcceptCount}",
Title = $"Accepting Count: {noRepeatAcceptCount}",
WantContinuousButtonPressed = false
};
noRepeatButton.Accepting += (s, e) =>
{
noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}";
e.Handled = true;
};
noRepeatButton.Accepting += (_, e) =>
{
noRepeatButton.Title = $"Accepting Count: {++noRepeatAcceptCount}";
Logging.Trace ("noRepeatButton Button Pressed");
e.Handled = true;
};
main.Add (label, noRepeatButton);
label = new ()
{
X = 0,
Y = Pos.Bottom (label) + 1,
Title = "_Repeat (press-and-hold):"
X = Pos.Right (noRepeatButton) + 1,
Y = Pos.Top (label),
Title = "N_o Repeat (no highlight):"
};
var acceptCount = 0;
var noRepeatNoHighlightAcceptCount = 0;
var repeatButton = new Button
Button noRepeatNoHighlight = new ()
{
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Title = $"Accepting Count: {noRepeatNoHighlightAcceptCount}",
WantContinuousButtonPressed = false,
HighlightStates = MouseState.None
};
noRepeatNoHighlight.Accepting += (_, e) =>
{
noRepeatNoHighlight.Title = $"Accepting Count: {++noRepeatNoHighlightAcceptCount}";
Logging.Trace ("noRepeatNoHighlight Button Pressed");
e.Handled = true;
};
main.Add (label, noRepeatNoHighlight);
label = new ()
{
X = 0,
Y = Pos.Bottom (noRepeatNoHighlight),
Title = "Repeat (_press-and-hold):"
};
var repeatButtonAcceptingCount = 0;
Button repeatButton = new ()
{
Id = "repeatButton",
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
Title = $"Accept Co_unt: {acceptCount}",
Title = $"Accepting Co_unt: {repeatButtonAcceptingCount}",
WantContinuousButtonPressed = true
};
repeatButton.Accepting += (s, e) =>
{
repeatButton.Title = $"Accept Co_unt: {++acceptCount}";
e.Handled = true;
};
var enableCB = new CheckBox
repeatButton.Accepting += (_, e) =>
{
repeatButton.Title = $"Accepting Co_unt: {++repeatButtonAcceptingCount}";
e.Handled = true;
};
CheckBox enableCb = new ()
{
X = Pos.Right (repeatButton) + 1,
Y = Pos.Top (repeatButton),
Title = "Enabled",
CheckedState = CheckState.Checked
};
enableCB.CheckedStateChanging += (s, e) => { repeatButton.Enabled = !repeatButton.Enabled; };
main.Add (label, repeatButton, enableCB);
enableCb.CheckedStateChanging += (_, _) => { repeatButton.Enabled = !repeatButton.Enabled; };
main.Add (label, repeatButton, enableCb);
var decNumericUpDown = new NumericUpDown<int>
NumericUpDown<int> decNumericUpDown = new ()
{
// ReSharper disable once StringLiteralTypo
Title = "Hexadecima_l",
Value = 911,
Increment = 1,
Format = "{0:X}",
X = 0,
Y = Pos.Bottom (enableCB) + 1,
Y = Pos.Bottom (repeatButton),
BorderStyle = LineStyle.Single,
Width = 15
};
main.Add (decNumericUpDown);
Application.Run (main);
main.Dispose ();
Application.Shutdown ();
app.Run (main);
return;
static void DoMessage (Button button, string txt)
{
button.Accepting += (s, e) =>
{
MessageBox.Query ((s as View)?.App!, "Message", $"Did you click {txt}?", "Yes", "No");
e.Handled = true;
};
}
}
private static void SetTextAlignmentForAllButtons (View root, Alignment alignment)
{
foreach (Button button in GetAllSubViewsOfType<Button> (root))
{
button.TextAlignment = alignment;
}
}
/// <summary>
/// Recursively finds all subviews of a specified type in the view hierarchy.
/// </summary>
/// <typeparam name="T">The type of views to find.</typeparam>
/// <param name="view">The root view to start searching from.</param>
/// <returns>An all matching subviews.</returns>
private static IEnumerable<T> GetAllSubViewsOfType<T> (View view) where T : View
{
foreach (View subview in view.SubViews)
{
// If this subview is of the requested type, yield it
if (subview is T matchingView)
{
yield return matchingView;
}
// Recursively search this subview's children
foreach (T child in GetAllSubViewsOfType<T> (subview))
{
yield return child;
}
}
}
}

View File

@@ -137,14 +137,14 @@ public class CharacterMap : Scenario
_categoryList.Activating += (_, e) =>
{
// Only handle mouse clicks
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouse })
{
return;
}
_categoryList.ScreenToCell (mouseArgs.Position, out int? clickedCol);
_categoryList.ScreenToCell (mouse.Position, out int? clickedCol);
if (clickedCol != null && mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
if (clickedCol != null && mouse.Flags.HasFlag (MouseFlags.Button1Clicked))
{
EnumerableTableSource<UnicodeRange> table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
string prevSelection = table.Data.ElementAt (_categoryList.SelectedRow).Category;

View File

@@ -127,20 +127,20 @@ public abstract class EditorBase : View
ViewToEdit = App!.Navigation!.GetFocused ();
}
private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e)
private void ApplicationOnMouseEvent (object? sender, Terminal.Gui.Input.MouseEventArgs mouse)
{
if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit)
if (mouse.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit)
{
return;
}
if ((AutoSelectSuperView is { } && !AutoSelectSuperView.FrameToScreen ().Contains (e.Position))
|| FrameToScreen ().Contains (e.Position))
if ((AutoSelectSuperView is { } && !AutoSelectSuperView.FrameToScreen ().Contains (mouse.Position))
|| FrameToScreen ().Contains (mouse.Position))
{
return;
}
View? view = e.View;
View? view = mouse.View;
if (view is null)
{

View File

@@ -77,7 +77,6 @@ public class EventLog : ListView
Log ($"Initialized: {GetIdentifyingString (sender)}");
};
_viewToLog.MouseWheel += (_, args) => { Log ($"MouseWheel: {args}"); };
_viewToLog.HandlingHotKey += (_, args) => { Log ($"HandlingHotKey: {args.Context}"); };
_viewToLog.Activating += (_, args) => { Log ($"Activating: {args.Context}"); };
_viewToLog.Accepting += (_, args) => { Log ($"Accepting: {args.Context}"); };

View File

@@ -161,7 +161,6 @@ public class Keys : Scenario
Application.Driver!.GetInputProcessor ().AnsiSequenceSwallowed += (s, e) => { swallowedList.Add (e.Replace ("\x1b", "Esc")); };
Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down");
Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up");
void KeyDownPressUp (Key args, string updown)
{

View File

@@ -4,7 +4,7 @@ namespace UICatalog.Scenarios;
public interface ITool
{
void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent);
void OnMouseEvent (DrawingArea area, Terminal.Gui.Input.MouseEventArgs mouse);
}
internal class DrawLineTool : ITool
@@ -13,15 +13,15 @@ internal class DrawLineTool : ITool
public LineStyle LineStyle { get; set; } = LineStyle.Single;
/// <inheritdoc/>
public void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent)
public void OnMouseEvent (DrawingArea area, Terminal.Gui.Input.MouseEventArgs mouse)
{
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))
if (mouse.Flags.HasFlag (MouseFlags.Button1Pressed))
{
if (_currentLine == null)
{
// Mouse pressed down
// MouseEventArgs pressed down
_currentLine = new (
mouseEvent.Position,
mouse.Position,
0,
Orientation.Vertical,
LineStyle,
@@ -32,9 +32,9 @@ internal class DrawLineTool : ITool
}
else
{
// Mouse dragged
// MouseEventArgs dragged
Point start = _currentLine.Start;
Point end = mouseEvent.Position;
Point end = mouse.Position;
var orientation = Orientation.Vertical;
int length = end.Y - start.Y;
@@ -62,7 +62,7 @@ internal class DrawLineTool : ITool
}
else
{
// Mouse released
// MouseEventArgs released
if (_currentLine != null)
{
if (_currentLine.Length == 0)
@@ -93,7 +93,7 @@ internal class DrawLineTool : ITool
}
}
mouseEvent.Handled = true;
mouse.Handled = true;
}
}
@@ -325,11 +325,11 @@ public class DrawingArea : View
return false;
}
protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
protected override bool OnMouseEvent (Terminal.Gui.Input.MouseEventArgs mouse)
{
CurrentTool.OnMouseEvent (this, mouseEvent);
CurrentTool.OnMouseEvent (this, mouse);
return mouseEvent.Handled;
return mouse.Handled;
}
internal void AddLayer ()
@@ -432,23 +432,23 @@ public class AttributeView : View
}
/// <inheritdoc/>
protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
protected override bool OnMouseEvent (Terminal.Gui.Input.MouseEventArgs mouse)
{
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
if (mouse.Flags.HasFlag (MouseFlags.Button1Clicked))
{
if (IsForegroundPoint (mouseEvent.Position.X, mouseEvent.Position.Y))
if (IsForegroundPoint (mouse.Position.X, mouse.Position.Y))
{
ClickedInForeground ();
}
else if (IsBackgroundPoint (mouseEvent.Position.X, mouseEvent.Position.Y))
else if (IsBackgroundPoint (mouse.Position.X, mouse.Position.Y))
{
ClickedInBackground ();
}
mouseEvent.Handled = true;
mouse.Handled = true;
}
return mouseEvent.Handled;
return mouse.Handled;
}
private bool IsForegroundPoint (int x, int y) { return ForegroundPoints.Contains ((x, y)); }

View File

@@ -1,369 +0,0 @@
using System.Collections.ObjectModel;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("Mouse", "Demonstrates Mouse Events and States")]
[ScenarioCategory ("Mouse and Keyboard")]
public class Mouse : Scenario
{
public override void Main ()
{
Application.Init ();
Window win = new ()
{
Id = "win",
Title = GetQuitKeyAndName ()
};
Slider<MouseFlags> filterSlider = new ()
{
Title = "_Filter",
X = 0,
Y = 0,
BorderStyle = LineStyle.Single,
Type = SliderType.Multiple,
Orientation = Orientation.Vertical,
UseMinimumSize = true,
MinimumInnerSpacing = 0
};
filterSlider.Options = Enum.GetValues (typeof (MouseFlags))
.Cast<MouseFlags> ()
.Where (value => !value.ToString ().Contains ("None") && !value.ToString ().Contains ("All"))
.Select (
value => new SliderOption<MouseFlags>
{
Legend = value.ToString (),
Data = value
})
.ToList ();
for (var i = 0; i < filterSlider.Options.Count; i++)
{
if (filterSlider.Options [i].Data != MouseFlags.ReportMousePosition)
{
filterSlider.SetOption (i);
}
}
win.Add (filterSlider);
var clearButton = new Button
{
Title = "_Clear Logs",
X = 1,
Y = Pos.Bottom (filterSlider) + 1
};
win.Add (clearButton);
Label ml;
var count = 0;
ml = new () { X = Pos.Right (filterSlider), Y = 0, Text = "Mouse: " };
win.Add (ml);
CheckBox cbWantContinuousPresses = new ()
{
X = Pos.Right (filterSlider),
Y = Pos.Bottom (ml),
Title = "_Want Continuous Button Pressed"
};
win.Add (cbWantContinuousPresses);
CheckBox cbHighlightOnPressed = new ()
{
X = Pos.Right (filterSlider),
Y = Pos.Bottom (cbWantContinuousPresses),
Title = "_Highlight on Pressed"
};
win.Add (cbHighlightOnPressed);
CheckBox cbHighlightOnPressedOutside = new ()
{
X = Pos.Right (filterSlider),
Y = Pos.Bottom (cbHighlightOnPressed),
Title = "_Highlight on PressedOutside"
};
win.Add (cbHighlightOnPressedOutside);
var demo = new MouseEventDemoView
{
Id = "demo",
X = Pos.Right (filterSlider),
Y = Pos.Bottom (cbHighlightOnPressedOutside),
Width = Dim.Fill (),
Height = 15,
Title = "Enter/Leave Demo"
};
demo.Padding!.Initialized += DemoPaddingOnInitialized;
void DemoPaddingOnInitialized (object o, EventArgs eventArgs)
{
demo.Padding!.Add (
new MouseEventDemoView
{
X = 0,
Y = 0,
Width = Dim.Fill (),
Height = Dim.Func (_ => demo.Padding.Thickness.Top),
Title = "inPadding",
Id = "inPadding"
});
demo.Padding.Thickness = demo.Padding.Thickness with { Top = 5 };
}
View sub1 = new MouseEventDemoView
{
X = 0,
Y = 0,
Width = Dim.Percent (20),
Height = Dim.Fill (),
Title = "sub1",
Id = "sub1"
};
demo.Add (sub1);
View sub2 = new MouseEventDemoView
{
X = Pos.Right (sub1) - 4,
Y = Pos.Top (sub1) + 1,
Width = Dim.Percent (20),
Height = Dim.Fill (1),
Title = "sub2",
Id = "sub2"
};
demo.Add (sub2);
win.Add (demo);
cbHighlightOnPressed.CheckedState = demo.HighlightStates.HasFlag (MouseState.Pressed) ? CheckState.Checked : CheckState.UnChecked;
cbHighlightOnPressed.CheckedStateChanging += (_, e) =>
{
if (e.Result == CheckState.Checked)
{
demo.HighlightStates |= MouseState.Pressed;
}
else
{
demo.HighlightStates &= ~MouseState.Pressed;
}
foreach (View subview in demo.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.Pressed;
}
else
{
subview.HighlightStates &= ~MouseState.Pressed;
}
}
foreach (View subview in demo.Padding.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.Pressed;
}
else
{
subview.HighlightStates &= ~MouseState.Pressed;
}
}
};
cbHighlightOnPressedOutside.CheckedState = demo.HighlightStates.HasFlag (MouseState.PressedOutside) ? CheckState.Checked : CheckState.UnChecked;
cbHighlightOnPressedOutside.CheckedStateChanging += (_, e) =>
{
if (e.Result == CheckState.Checked)
{
demo.HighlightStates |= MouseState.PressedOutside;
}
else
{
demo.HighlightStates &= ~MouseState.PressedOutside;
}
foreach (View subview in demo.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.PressedOutside;
}
else
{
subview.HighlightStates &= ~MouseState.PressedOutside;
}
}
foreach (View subview in demo.Padding.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.PressedOutside;
}
else
{
subview.HighlightStates &= ~MouseState.PressedOutside;
}
}
};
cbWantContinuousPresses.CheckedStateChanging += (_, _) =>
{
demo.WantContinuousButtonPressed = !demo.WantContinuousButtonPressed;
foreach (View subview in demo.SubViews)
{
subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
}
foreach (View subview in demo.Padding.SubViews)
{
subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
}
};
var label = new Label
{
Text = "_App Events:",
X = Pos.Right (filterSlider),
Y = Pos.Bottom (demo)
};
ObservableCollection<string> appLogList = new ();
var appLog = new ListView
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = 50,
Height = Dim.Fill (),
SchemeName = "Runnable",
Source = new ListWrapper<string> (appLogList)
};
win.Add (label, appLog);
Application.MouseEvent += (_, a) =>
{
int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
if (filterSlider.GetSetOptions ().Contains (i))
{
ml.Text = $"MouseEvent: ({a.Position}) - {a.Flags} {count}";
appLogList.Add ($"({a.Position}) - {a.Flags} {count++}");
appLog.MoveDown ();
}
};
label = new ()
{
Text = "_Window Events:",
X = Pos.Right (appLog) + 1,
Y = Pos.Top (label)
};
ObservableCollection<string> winLogList = [];
var winLog = new ListView
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = Dim.Percent (50),
Height = Dim.Fill (),
SchemeName = "Runnable",
Source = new ListWrapper<string> (winLogList)
};
win.Add (label, winLog);
clearButton.Accepting += (_, _) =>
{
appLogList.Clear ();
appLog.SetSource (appLogList);
winLogList.Clear ();
winLog.SetSource (winLogList);
};
win.MouseEvent += (_, a) =>
{
int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
if (filterSlider.GetSetOptions ().Contains (i))
{
winLogList.Add ($"MouseEvent: ({a.Position}) - {a.Flags} {count++}");
winLog.MoveDown ();
}
};
Application.Run (win);
win.Dispose ();
Application.Shutdown ();
}
public class MouseEventDemoView : View
{
public MouseEventDemoView ()
{
CanFocus = true;
Id = "mouseEventDemoView";
Initialized += OnInitialized;
MouseLeave += (_, _) => { Text = "Leave"; };
MouseEnter += (_, _) => { Text = "Enter"; };
return;
void OnInitialized (object sender, EventArgs e)
{
TextAlignment = Alignment.Center;
VerticalTextAlignment = Alignment.Center;
Padding!.Thickness = new (1, 1, 1, 1);
Padding!.SetScheme (new (new Attribute (Color.Black)));
Padding.Id = $"{Id}.Padding";
Border!.Thickness = new (1);
Border.LineStyle = LineStyle.Rounded;
Border.Id = $"{Id}.Border";
MouseStateChanged += (_, args) =>
{
if (args.Value.HasFlag (MouseState.PressedOutside))
{
Border.LineStyle = LineStyle.Dotted;
}
else
{
Border.LineStyle = LineStyle.Single;
}
SetNeedsDraw ();
};
}
}
/// <inheritdoc/>
protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute)
{
if (role == VisualRole.Normal)
{
if (MouseState.HasFlag (MouseState.Pressed) && HighlightStates.HasFlag (MouseState.Pressed))
{
currentAttribute = currentAttribute with { Background = currentAttribute.Foreground.GetBrighterColor () };
return true;
}
}
return base.OnGettingAttributeForRole (in role, ref currentAttribute);
}
}
}

View File

@@ -0,0 +1,604 @@
using System.Collections.ObjectModel;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("Mouse Tester", "Illustrates Mouse event flow and handling")]
[ScenarioCategory ("Mouse and Keyboard")]
public class MouseTester : Scenario
{
public override void Main ()
{
Application.Init ();
// Prepping for modern app model
using IApplication app = Application.Instance;
using Runnable runnable = new ()
{
Id = "runnable",
};
MenuBar menuBar = new ();
menuBar.Add (new MenuBarItem ("_File", [new MenuItem { Title = "_Quit", Action = () => app.RequestStop () }]));
FlagSelector<DemoMouseFlags> mouseFlagsFilter = new ()
{
AssignHotKeys = true,
Value = (DemoMouseFlags.All & ~DemoMouseFlags.PositionReport),
};
menuBar.Add (
new MenuBarItem (
"_Filter",
[
new MenuItem
{
CommandView = mouseFlagsFilter
},
]
),
new MenuBarItem (runnable, Command.DeleteAll, "_Clear Logs")
);
runnable.Add (menuBar);
View lastDriverEvent = new ()
{
Height = 1,
Width = Dim.Auto (),
Y = Pos.Bottom (menuBar),
Text = "Last Driver Event: "
};
runnable.Add (lastDriverEvent);
View lastAppEvent = new ()
{
Height = 1,
Width = Dim.Auto (),
Y = Pos.Bottom (lastDriverEvent),
Text = "Last App Event: "
};
runnable.Add (lastAppEvent);
View lastViewEvent = new ()
{
Height = 1,
Width = Dim.Auto (),
Y = Pos.Bottom (lastAppEvent),
Text = "Last View Event: "
};
runnable.Add (lastViewEvent);
CheckBox cbRepeatOnHold = new ()
{
Y = Pos.Bottom (lastViewEvent),
Title = "_Repeat On Hold"
};
runnable.Add (cbRepeatOnHold);
CheckBox cbHighlightOnPressed = new ()
{
Y = Pos.Bottom (cbRepeatOnHold),
Title = "_Highlight on Pressed"
};
runnable.Add (cbHighlightOnPressed);
CheckBox cbHighlightOnPressedOutside = new ()
{
Y = Pos.Bottom (cbHighlightOnPressed),
Title = "_Highlight on PressedOutside"
};
runnable.Add (cbHighlightOnPressedOutside);
MouseEventDemoView demo = new ()
{
Id = "demo",
Y = Pos.Bottom (cbHighlightOnPressedOutside),
Width = Dim.Fill (),
Height = 15,
Title = "Enter/Leave Demo"
};
MouseEventDemoView demoInPadding = new ()
{
X = 0,
Y = 0,
Width = Dim.Fill (),
Height = Dim.Func (_ => demo.Padding!.Thickness.Top),
Title = "inPadding",
Id = "inPadding",
};
demo.Padding!.Add (demoInPadding);
demo.Padding!.Initialized += DemoPaddingOnInitialized;
void DemoPaddingOnInitialized (object o, EventArgs eventArgs)
{
demo.Padding!.Thickness = demo.Padding.Thickness with { Top = 5 };
}
MouseEventDemoView sub1 = new ()
{
X = 0,
Y = 0,
Width = Dim.Percent (20),
Height = Dim.Fill (),
Title = "sub1",
Id = "sub1"
};
demo.Add (sub1);
MouseEventDemoView sub2 = new ()
{
X = Pos.Right (sub1) - 4,
Y = Pos.Top (sub1) + 1,
Width = Dim.Percent (20),
Height = Dim.Fill (1),
Title = "sub2",
Id = "sub2"
};
demo.Add (sub2);
runnable.Add (demo);
cbHighlightOnPressed.CheckedState = demo.HighlightStates.HasFlag (MouseState.Pressed) ? CheckState.Checked : CheckState.UnChecked;
cbHighlightOnPressed.CheckedStateChanging += (_, e) =>
{
if (e.Result == CheckState.Checked)
{
demo.HighlightStates |= MouseState.Pressed;
}
else
{
demo.HighlightStates &= ~MouseState.Pressed;
}
foreach (View subview in demo.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.Pressed;
}
else
{
subview.HighlightStates &= ~MouseState.Pressed;
}
}
foreach (View subview in demo.Padding.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.Pressed;
}
else
{
subview.HighlightStates &= ~MouseState.Pressed;
}
}
};
cbHighlightOnPressedOutside.CheckedState = demo.HighlightStates.HasFlag (MouseState.PressedOutside) ? CheckState.Checked : CheckState.UnChecked;
cbHighlightOnPressedOutside.CheckedStateChanging += (_, e) =>
{
if (e.Result == CheckState.Checked)
{
demo.HighlightStates |= MouseState.PressedOutside;
}
else
{
demo.HighlightStates &= ~MouseState.PressedOutside;
}
foreach (View subview in demo.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.PressedOutside;
}
else
{
subview.HighlightStates &= ~MouseState.PressedOutside;
}
}
foreach (View subview in demo.Padding.SubViews)
{
if (e.Result == CheckState.Checked)
{
subview.HighlightStates |= MouseState.PressedOutside;
}
else
{
subview.HighlightStates &= ~MouseState.PressedOutside;
}
}
};
cbRepeatOnHold.CheckedStateChanging += (_, _) =>
{
demo.WantContinuousButtonPressed = !demo.WantContinuousButtonPressed;
foreach (View subview in demo.SubViews)
{
subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
}
foreach (View subview in demo.Padding.SubViews)
{
subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
}
};
Label label = new ()
{
Text = "Dri_ver Events:",
//X = Pos.Right (filterSlider),
Y = Pos.Bottom (demo)
};
ObservableCollection<string> driverLogList = new ();
ListView driverLog = new ()
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = Dim.Auto (minimumContentDim: Dim.Percent (20)),
Height = Dim.Fill (),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Base),
Source = new ListWrapper<string> (driverLogList)
};
runnable.Add (label, driverLog);
app.Driver!.MouseEvent += (_, mouse) =>
{
if (!mouseFlagsFilter.Value.HasValue)
{
return;
}
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastDriverEvent.Text = $"Last Driver Event: {mouse}";
Logging.Trace (lastDriverEvent.Text);
driverLogList.Add ($"{mouse.Position}:{mouse.Flags}");
driverLog.MoveEnd ();
}
};
label = new ()
{
Text = "_App Events:",
X = Pos.Right (driverLog) + 1,
Y = Pos.Bottom (demo)
};
ObservableCollection<string> appLogList = new ();
ListView appLog = new ()
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = Dim.Auto (minimumContentDim: Dim.Percent (20)),
Height = Dim.Fill (),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Base),
Source = new ListWrapper<string> (appLogList)
};
runnable.Add (label, appLog);
app.Mouse.MouseEvent += (_, mouse) =>
{
if (!mouseFlagsFilter.Value.HasValue)
{
return;
}
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastAppEvent.Text = $" Last App Event: {mouse}";
appLogList.Add ($"{mouse.Position}:{mouse.Flags}");
appLog.MoveEnd ();
}
};
label = new ()
{
Text = "_View Events:",
X = Pos.Right (appLog) + 1,
Y = Pos.Top (label)
};
ObservableCollection<string> viewLogList = [];
ListView viewLog = new ()
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = Dim.Auto (minimumContentDim: Dim.Percent (20)),
Height = Dim.Fill (),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Base),
Source = new ListWrapper<string> (viewLogList)
};
runnable.Add (label, viewLog);
demo.MouseEvent += (_, mouse) =>
{
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastViewEvent.Text = $" Last View Event: {mouse}";
viewLogList.Add ($"{mouse.Position}:{mouse.View!.Id}:{mouse.Flags}");
viewLog.MoveEnd ();
}
};
demoInPadding.MouseEvent += (_, mouse) =>
{
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastViewEvent.Text = $" Last View Event: {mouse}";
viewLogList.Add ($"{mouse.Position}:{mouse.View!.Id}:{mouse.Flags}");
viewLog.MoveEnd ();
}
};
sub1.MouseEvent += (_, mouse) =>
{
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastViewEvent.Text = $" Last View Event: {mouse}";
viewLogList.Add ($"{mouse.Position}:{mouse.View!.Id}:{mouse.Flags}");
viewLog.MoveEnd ();
}
};
sub2.MouseEvent += (_, mouse) =>
{
if (mouseFlagsFilter.Value.Value.HasFlag ((DemoMouseFlags)mouse.Flags))
{
lastViewEvent.Text = $" Last View Event: {mouse}";
viewLogList.Add ($"{mouse.Position}:{mouse.View!.Id}:{mouse.Flags}");
viewLog.MoveEnd ();
}
};
label = new ()
{
Text = "_Commands:",
X = Pos.Right (viewLog) + 1,
Y = Pos.Top (label)
};
ObservableCollection<string> commandLogList = [];
ListView commandLog = new ()
{
X = Pos.Left (label),
Y = Pos.Bottom (label),
Width = Dim.Auto (minimumContentDim: Dim.Percent (15)),
Height = Dim.Fill (),
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Base),
Source = new ListWrapper<string> (commandLogList)
};
runnable.Add (label, commandLog);
demo.Activating += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
demo.Accepting += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
demoInPadding.Activating += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
demoInPadding.Accepting += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
sub1.Activating += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
sub1.Accepting += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
sub2.Activating += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
sub2.Accepting += (_, args) =>
{
commandLogList.Add ($"{args.Context!.Source!.Id}:{args.Context!.Command}");
commandLog.MoveEnd ();
args.Handled = true;
};
runnable.CommandNotBound += (_, args) =>
{
if (args.Context!.Command == Command.DeleteAll)
{
driverLogList.Clear ();
driverLog.SetSource (driverLogList);
appLogList.Clear ();
appLog.SetSource (appLogList);
viewLogList.Clear ();
viewLog.SetSource (viewLogList);
commandLogList.Clear ();
commandLog.SetSource (commandLogList);
args.Handled = true;
}
};
app.Run (runnable);
}
public class MouseEventDemoView : View
{
public MouseEventDemoView ()
{
CanFocus = true;
Id = "mouseEventDemoView";
MouseLeave += (_, _) => { Text = "Leave"; };
MouseEnter += (_, _) => { Text = "Enter"; };
}
/// <inheritdoc />
public override void EndInit ()
{
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Base);
TextAlignment = Alignment.Center;
VerticalTextAlignment = Alignment.Center;
Padding!.Thickness = new (1, 1, 1, 1);
Padding!.SetScheme (new (new Attribute (Color.DarkGray)));
Padding.Id = $"{Id}.Padding";
Border!.Thickness = new (1);
Border.LineStyle = LineStyle.Rounded;
Border.Id = $"{Id}.Border";
base.EndInit ();
}
/// <inheritdoc />
protected override void OnMouseStateChanged (EventArgs<MouseState> args)
{
base.OnMouseStateChanged (args);
Border!.LineStyle = args.Value.HasFlag (MouseState.PressedOutside) ? LineStyle.Dotted : LineStyle.Single;
SetNeedsDraw ();
}
/// <inheritdoc/>
protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute)
{
switch (role)
{
case VisualRole.Normal when MouseState.HasFlag (MouseState.Pressed) && HighlightStates.HasFlag (MouseState.Pressed):
currentAttribute = currentAttribute with { Background = currentAttribute.Foreground.GetBrighterColor () };
return true;
default:
return base.OnGettingAttributeForRole (in role, ref currentAttribute);
}
}
}
}
// All the MouseFlags we can set for filtering
[Flags]
internal enum DemoMouseFlags
{
/// <summary>
/// No mouse event. This is the default value for <see cref="MouseEventArgs.Flags"/> when no mouse event is being
/// reported.
/// </summary>
None = 0,
/// <summary>The first mouse button was pressed.</summary>
Button1Pressed = 0x2,
/// <summary>The first mouse button was released.</summary>
Button1Released = 0x1,
/// <summary>The first mouse button was clicked (press+release).</summary>
Button1Clicked = 0x4,
/// <summary>The first mouse button was double-clicked.</summary>
Button1DoubleClicked = 0x8,
/// <summary>The first mouse button was triple-clicked.</summary>
Button1TripleClicked = 0x10,
/// <summary>The second mouse button was pressed.</summary>
MiddleButtonPressed = 0x80,
/// <summary>The second mouse button was released.</summary>
MiddleButtonReleased = 0x40,
/// <summary>The second mouse button was clicked (press+release).</summary>
MiddleButtonClicked = 0x100,
/// <summary>The second mouse button was double-clicked.</summary>
MiddleButtonDoubleClicked = 0x200,
/// <summary>The second mouse button was triple-clicked.</summary>
MiddleButtonTripleClicked = 0x400,
/// <summary>The third mouse button was pressed.</summary>
Button3Pressed = 0x2000,
/// <summary>The third mouse button was released.</summary>
Button3Released = 0x1000,
/// <summary>The third mouse button was clicked (press+release).</summary>
Button3Clicked = 0x4000,
/// <summary>The third mouse button was double-clicked.</summary>
Button3DoubleClicked = 0x8000,
/// <summary>The third mouse button was triple-clicked.</summary>
Button3TripleClicked = 0x10000,
/// <summary>The fourth mouse button was pressed.</summary>
Button4Pressed = 0x80000,
/// <summary>The fourth mouse button was released.</summary>
Button4Released = 0x40000,
/// <summary>The fourth mouse button was clicked.</summary>
Button4Clicked = 0x100000,
/// <summary>The fourth mouse button was double-clicked.</summary>
Button4DoubleClicked = 0x200000,
/// <summary>The fourth mouse button was triple-clicked.</summary>
Button4TripleClicked = 0x400000,
/// <summary>The mouse position is being reported in this event.</summary>
PositionReport = 0x8000000,
/// <summary>Vertical button wheeled up.</summary>
WheeledUp = 0x10000000,
/// <summary>Vertical button wheeled down.</summary>
WheeledDown = 0x20000000,
/// <summary>Vertical button wheeled up while pressing Ctrl.</summary>
WheeledLeft = 0x1000000 | WheeledUp,
/// <summary>Vertical button wheeled down while pressing Ctrl.</summary>
WheeledRight = 0x1000000 | WheeledDown,
All = -1
}

View File

@@ -1,6 +1,4 @@
#nullable enable
using System;
#nullable enable
namespace UICatalog.Scenarios;
[ScenarioMetadata ("NumericUpDown", "Demonstrates the NumericUpDown View")]
@@ -10,47 +8,46 @@ public class NumericUpDownDemo : Scenario
public override void Main ()
{
Application.Init ();
using IApplication app = Application.Instance;
Window app = new ()
{
Title = GetQuitKeyAndName (),
BorderStyle = LineStyle.None
};
using Window mainWindow = new ();
mainWindow.Title = GetQuitKeyAndName ();
mainWindow.BorderStyle = LineStyle.None;
NumericUpDownEditor<int> intEditor = new ()
{
X = 0,
Y = 0,
Title = "int",
Title = "_int"
};
app.Add (intEditor);
mainWindow.Add (intEditor);
NumericUpDownEditor<float> floatEditor = new ()
{
X = Pos.Right (intEditor),
Y = 0,
Title = "float",
Title = "_float"
};
app.Add (floatEditor);
mainWindow.Add (floatEditor);
floatEditor.NumericUpDown!.Increment = 0.1F;
floatEditor.NumericUpDown!.Format = "{0:0.0}";
app.Initialized += AppInitialized;
void AppInitialized (object? sender, EventArgs e)
NumericUpDownEditor<int> hexEditor = new ()
{
floatEditor!.NumericUpDown!.Increment = 0.1F;
floatEditor!.NumericUpDown!.Format = "{0:0.0}";
}
X = Pos.Right (floatEditor),
Y = 0,
Title = "_hex"
};
mainWindow.Add (floatEditor);
hexEditor.NumericUpDown!.Increment = 1;
hexEditor.NumericUpDown!.Format = "{0:X}";
mainWindow.Add (hexEditor);
intEditor.SetFocus ();
Application.Run (app);
app.Dispose ();
Application.Shutdown ();
app.Run (mainWindow);
}
}
internal class NumericUpDownEditor<T> : View where T : notnull
internal sealed class NumericUpDownEditor<T> : View where T : notnull
{
private NumericUpDown<T>? _numericUpDown;
@@ -63,6 +60,7 @@ internal class NumericUpDownEditor<T> : View where T : notnull
{
return;
}
_numericUpDown = value;
if (_numericUpDown is { } && _value is { })
@@ -72,9 +70,9 @@ internal class NumericUpDownEditor<T> : View where T : notnull
}
}
private TextField? _value;
private TextField? _format;
private TextField? _increment;
private readonly TextField? _value;
private readonly TextField? _format;
private readonly TextField? _increment;
internal NumericUpDownEditor ()
{
@@ -86,196 +84,167 @@ internal class NumericUpDownEditor<T> : View where T : notnull
TabStop = TabBehavior.TabGroup;
CanFocus = true;
Initialized += NumericUpDownEditorInitialized;
Label label = new ()
{
Title = "_Value: ",
Width = 12
};
label.TextFormatter.Alignment = Alignment.End;
_value = new ()
{
X = Pos.Right (label),
Y = Pos.Top (label),
Width = 8,
Title = "Value"
};
_value.Accepting += ValuedOnAccept;
Add (label, _value);
label = new ()
{
Y = Pos.Bottom (_value),
Width = 12,
Title = "_Format: "
};
label.TextFormatter.Alignment = Alignment.End;
_format = new ()
{
X = Pos.Right (label),
Y = Pos.Top (label),
Title = "Format",
Width = Dim.Width (_value)
};
_format.Accepting += FormatOnAccept;
Add (label, _format);
label = new ()
{
Y = Pos.Bottom (_format),
Width = 12,
Title = "_Increment: "
};
label.TextFormatter.Alignment = Alignment.End;
_increment = new ()
{
X = Pos.Right (label),
Y = Pos.Top (label),
Title = "Increment",
Width = Dim.Width (_value)
};
_increment.Accepting += IncrementOnAccept;
Add (label, _increment);
_numericUpDown = new ()
{
X = Pos.Center (),
Y = Pos.Bottom (_increment) + 1,
Increment = NumericUpDown<int>.TryConvert (1, out T? increment) ? increment : default (T?)
};
_numericUpDown.ValueChanged += NumericUpDownOnValueChanged;
_numericUpDown.IncrementChanged += NumericUpDownOnIncrementChanged;
Add (_numericUpDown);
_value.Text = _numericUpDown.Text;
_format.Text = _numericUpDown.Format;
_increment.Text = _numericUpDown!.Increment?.ToString ();
return;
void NumericUpDownEditorInitialized (object? sender, EventArgs e)
void NumericUpDownOnIncrementChanged (object? o, EventArgs<T> eventArgs) { _increment.Text = _numericUpDown!.Increment?.ToString (); }
void NumericUpDownOnValueChanged (object? o, EventArgs<T> eventArgs) { _value.Text = _numericUpDown.Text; }
void FormatOnAccept (object? o, EventArgs eventArgs)
{
Label label = new ()
if (_numericUpDown is null)
{
Title = "_Value: ",
Width = 12,
};
label.TextFormatter.Alignment = Alignment.End;
_value = new ()
{
X = Pos.Right (label),
Y = Pos.Top (label),
Width = 8,
Title = "Value",
};
_value.Accepting += ValuedOnAccept;
void ValuedOnAccept (object? sender, EventArgs e)
{
if (_numericUpDown is null)
{
return;
}
try
{
if (string.IsNullOrEmpty (_value.Text))
{
// Handle empty or null text if needed
_numericUpDown.Value = default!;
}
else
{
// Parse _value.Text and then convert to type T
_numericUpDown.Value = (T)Convert.ChangeType (_value.Text, typeof (T));
}
_value.SetScheme (SuperView!.GetScheme ());
}
catch (System.FormatException)
{
_value.SchemeName = "Error";
}
catch (InvalidCastException)
{
_value.SchemeName = "Error";
}
finally
{
}
}
Add (label, _value);
label = new ()
{
Y = Pos.Bottom (_value),
Width = 12,
Title = "_Format: ",
};
label.TextFormatter.Alignment = Alignment.End;
_format = new ()
{
X = Pos.Right (label),
Y = Pos.Top (label),
Title = "Format",
Width = Dim.Width (_value),
};
_format.Accepting += FormatOnAccept;
void FormatOnAccept (object? o, EventArgs eventArgs)
{
if (_numericUpDown is null)
{
return;
}
try
{
// Test format to ensure it's valid
_ = string.Format (_format.Text, _value);
_numericUpDown.Format = _format.Text;
_format.SetScheme (SuperView!.GetScheme ());
}
catch (System.FormatException)
{
_format.SchemeName = "Error";
}
catch (InvalidCastException)
{
_format.SchemeName = "Error";
}
finally
{
}
return;
}
Add (label, _format);
label = new ()
try
{
Y = Pos.Bottom (_format),
Width = 12,
Title = "_Increment: ",
};
label.TextFormatter.Alignment = Alignment.End;
_increment = new ()
// Test format to ensure it's valid
_ = string.Format (_format.Text, _value);
_numericUpDown.Format = _format.Text;
_format.SetScheme (SuperView!.GetScheme ());
}
catch (FormatException)
{
X = Pos.Right (label),
Y = Pos.Top (label),
Title = "Increment",
Width = Dim.Width (_value),
};
_increment.Accepting += IncrementOnAccept;
void IncrementOnAccept (object? o, EventArgs eventArgs)
_format.SchemeName = "Error";
}
catch (InvalidCastException)
{
if (_numericUpDown is null)
{
return;
}
_format.SchemeName = "Error";
}
}
try
{
if (string.IsNullOrEmpty (_value.Text))
{
// Handle empty or null text if needed
_numericUpDown.Increment = default!;
}
else
{
// Parse _value.Text and then convert to type T
_numericUpDown.Increment = (T)Convert.ChangeType (_increment.Text, typeof (T));
}
_increment.SetScheme (SuperView!.GetScheme ());
}
catch (System.FormatException)
{
_increment.SchemeName = "Error";
}
catch (InvalidCastException)
{
_increment.SchemeName = "Error";
}
finally
{
}
void IncrementOnAccept (object? o, EventArgs eventArgs)
{
if (_numericUpDown is null)
{
return;
}
Add (label, _increment);
_numericUpDown = new ()
try
{
X = Pos.Center (),
Y = Pos.Bottom (_increment) + 1,
Increment = NumericUpDown<int>.TryConvert (1, out T? increment) ? increment : default (T?),
};
if (string.IsNullOrEmpty (_value.Text))
{
// Handle empty or null text if needed
_numericUpDown.Increment = default (T?)!;
}
else
{
// Parse _value.Text and then convert to type T
_numericUpDown.Increment = (T)Convert.ChangeType (_increment.Text, typeof (T));
}
_numericUpDown.ValueChanged += NumericUpDownOnValueChanged;
void NumericUpDownOnValueChanged (object? o, EventArgs<T> eventArgs)
_increment.SetScheme (SuperView!.GetScheme ());
}
catch (FormatException)
{
_value.Text = _numericUpDown.Text;
_increment.SchemeName = "Error";
}
catch (InvalidCastException)
{
_increment.SchemeName = "Error";
}
}
void ValuedOnAccept (object? sender, EventArgs e)
{
if (_numericUpDown is null)
{
return;
}
_numericUpDown.IncrementChanged += NumericUpDownOnIncrementChanged;
void NumericUpDownOnIncrementChanged (object? o, EventArgs<T> eventArgs)
try
{
_increment.Text = _numericUpDown!.Increment?.ToString ();
if (string.IsNullOrEmpty (_value.Text))
{
// Handle empty or null text if needed
_numericUpDown.Value = default (T)!;
}
else
{
// Parse _value.Text and then convert to type T
_numericUpDown.Value = (T)Convert.ChangeType (_value.Text, typeof (T));
}
_value.SetScheme (SuperView!.GetScheme ());
}
catch (FormatException)
{
_value.SchemeName = "Error";
}
catch (InvalidCastException)
{
_value.SchemeName = "Error";
}
Add (_numericUpDown);
_value.Text = _numericUpDown.Text;
_format.Text = _numericUpDown.Format;
_increment.Text = _numericUpDown!.Increment?.ToString ();
}
}
}

View File

@@ -3,6 +3,8 @@ using System.Text;
using UICatalog;
using UICatalog.Scenarios;
// ReSharper disable AccessToDisposedClosure
/// <summary>
/// Demonstrates creating and drawing regions through mouse dragging.
/// </summary>
@@ -24,14 +26,14 @@ public class RegionScenario : Scenario
{
Application.Init ();
Window appWindow = new ()
{
Title = GetQuitKeyAndName (),
TabStop = TabBehavior.TabGroup
};
using IApplication app = Application.Instance;
using Window appWindow = new ();
appWindow.Title = GetQuitKeyAndName ();
appWindow.TabStop = TabBehavior.TabGroup;
appWindow.Padding!.Thickness = new (1);
var tools = new ToolsView { Title = "Tools", X = Pos.AnchorEnd (), Y = 2 };
ToolsView tools = new () { Title = "Tools", X = Pos.AnchorEnd (), Y = 2 };
tools.CurrentAttribute = appWindow.GetAttributeForRole (VisualRole.HotNormal);
@@ -41,100 +43,103 @@ public class RegionScenario : Scenario
appWindow.SetNeedsDraw ();
};
tools.RegionOpChanged += (s, e) => { _regionOp = e; };
tools.RegionOpChanged += (_, e) => { _regionOp = e; };
//tools.AddLayer += () => canvas.AddLayer ();
appWindow.Add (tools);
// Add drag handling to window
appWindow.MouseEvent += (s, e) =>
{
if (e.Flags.HasFlag (MouseFlags.Button1Pressed))
{
if (!e.Flags.HasFlag (MouseFlags.ReportMousePosition))
{ // Start drag
_dragStart = e.ScreenPosition;
_isDragging = true;
}
else
{
// Drag
if (_isDragging && _dragStart.HasValue)
{
appWindow.SetNeedsDraw ();
}
}
}
appWindow.MouseEvent += (_, e) =>
{
if (e.Flags.HasFlag (MouseFlags.Button1Pressed))
{
if (!e.Flags.HasFlag (MouseFlags.ReportMousePosition))
{ // Start drag
_dragStart = e.ScreenPosition;
_isDragging = true;
}
else
{
// Drag
if (_isDragging && _dragStart.HasValue)
{
appWindow.SetNeedsDraw ();
}
}
}
if (e.Flags.HasFlag (MouseFlags.Button1Released))
{
if (_isDragging && _dragStart.HasValue)
{
// Add the new region
AddRectangleFromPoints (_dragStart.Value, e.ScreenPosition, _regionOp);
_isDragging = false;
_dragStart = null;
}
if (!e.Flags.HasFlag (MouseFlags.Button1Released))
{
return;
}
appWindow.SetNeedsDraw ();
}
};
if (_isDragging && _dragStart.HasValue)
{
// Add the new region
AddRectangleFromPoints (_dragStart.Value, e.ScreenPosition, _regionOp);
_isDragging = false;
_dragStart = null;
}
appWindow.SetNeedsDraw ();
};
// Draw the regions
appWindow.DrawingContent += (s, e) =>
{
// Draw all regions with single line style
//_region.FillRectangles (_attribute.Value, _fillRune);
switch (_drawStyle)
{
case RegionDrawStyles.FillOnly:
_region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, _previewFillRune);
appWindow.DrawingContent += (s, _) =>
{
if (s is not View sendingView)
{
return;
}
break;
// Draw all regions with single line style
//_region.FillRectangles (_attribute.Value, _fillRune);
switch (_drawStyle)
{
case RegionDrawStyles.FillOnly:
_region.FillRectangles (sendingView.App?.Driver, tools.CurrentAttribute!.Value, _previewFillRune);
case RegionDrawStyles.InnerBoundaries:
_region.DrawBoundaries (appWindow.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
_region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
break;
break;
case RegionDrawStyles.InnerBoundaries:
_region.DrawBoundaries (sendingView.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
_region.FillRectangles (sendingView.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
case RegionDrawStyles.OuterBoundary:
_region.DrawOuterBoundary (appWindow.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
_region.FillRectangles (appWindow.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
break;
break;
}
case RegionDrawStyles.OuterBoundary:
_region.DrawOuterBoundary (sendingView.LineCanvas, LineStyle.Single, tools.CurrentAttribute);
_region.FillRectangles (sendingView.App?.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
// If currently dragging, draw preview rectangle
if (_isDragging && _dragStart.HasValue)
{
Point currentMousePos = appWindow.App!.Mouse.LastMousePosition!.Value;
Rectangle previewRect = GetRectFromPoints (_dragStart.Value, currentMousePos);
var previewRegion = new Region (previewRect);
break;
}
previewRegion.FillRectangles (appWindow.App.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
// If currently dragging, draw preview rectangle
if (_isDragging && _dragStart.HasValue)
{
Point currentMousePos = sendingView.App!.Mouse.LastMousePosition!.Value;
Rectangle previewRect = GetRectFromPoints (_dragStart.Value, currentMousePos);
Region previewRegion = new (previewRect);
previewRegion.DrawBoundaries (
appWindow.LineCanvas,
LineStyle.Dashed,
new (
tools.CurrentAttribute!.Value.Foreground.GetBrighterColor (),
tools.CurrentAttribute!.Value.Background));
}
};
previewRegion.FillRectangles (sendingView.App.Driver, tools.CurrentAttribute!.Value, (Rune)' ');
Application.Run (appWindow);
previewRegion.DrawBoundaries (
sendingView.LineCanvas,
LineStyle.Dashed,
new (
tools.CurrentAttribute!.Value.Foreground.GetBrighterColor (),
tools.CurrentAttribute!.Value.Background));
}
};
// Clean up
appWindow.Dispose ();
Application.Shutdown ();
app.Run (appWindow);
}
private void AddRectangleFromPoints (Point start, Point end, RegionOp op)
{
Rectangle rect = GetRectFromPoints (start, end);
var region = new Region (rect);
Region region = new (rect);
_region.Combine (region, op); // Or RegionOp.MinimalUnion if you want minimal rectangles
}
@@ -153,7 +158,7 @@ public class RegionScenario : Scenario
}
}
public enum RegionDrawStyles
internal enum RegionDrawStyles
{
FillOnly = 0,
@@ -162,7 +167,7 @@ public enum RegionDrawStyles
OuterBoundary = 2
}
public class ToolsView : Window
internal class ToolsView : Window
{
//private Button _addLayerBtn;
private readonly AttributeView _attributeView = new ();
@@ -183,13 +188,11 @@ public class ToolsView : Window
Width = Dim.Auto ();
}
//public event Action AddLayer;
public override void BeginInit ()
{
base.BeginInit ();
_attributeView.ValueChanged += (s, e) => AttributeChanged?.Invoke (this, e);
_attributeView.ValueChanged += (_, e) => AttributeChanged?.Invoke (this, e);
_stylePicker = new ()
{
@@ -201,7 +204,7 @@ public class ToolsView : Window
_stylePicker.Border!.Thickness = new (0, 1, 0, 0);
_stylePicker.Title = "Draw Style";
_stylePicker.ValueChanged += (s, a) => { SetStyle?.Invoke ((RegionDrawStyles)a.Value!); };
_stylePicker.ValueChanged += (_, a) => { SetStyle?.Invoke ((RegionDrawStyles)a.Value!); };
_stylePicker.Value = RegionDrawStyles.FillOnly;
_regionOpSelector = new ()
@@ -210,7 +213,8 @@ public class ToolsView : Window
Y = Pos.Bottom (_stylePicker) + 1,
AssignHotKeys = true
};
_regionOpSelector.ValueChanged += (s, a) =>
_regionOpSelector.ValueChanged += (_, a) =>
{
if (a.Value is { })
{
@@ -219,9 +223,6 @@ public class ToolsView : Window
};
_regionOpSelector.Value = RegionOp.MinimalUnion;
//_addLayerBtn = new () { Text = "New Layer", X = Pos.Center (), Y = Pos.Bottom (_stylePicker) };
//_addLayerBtn.Accepting += (s, a) => AddLayer?.Invoke ();
Add (_attributeView, _stylePicker, _regionOpSelector); //, _addLayerBtn);
}
@@ -230,7 +231,7 @@ public class ToolsView : Window
public event Action<RegionDrawStyles>? SetStyle;
}
public class AttributeView : View
internal class AttributeView : View
{
public event EventHandler<Attribute?>? ValueChanged;
private Attribute? _value;
@@ -303,9 +304,6 @@ public class AttributeView : View
// Square of background color
foreach ((int, int) point in _backgroundPoints)
{
// Make pattern like this when it is same color as background of control
/*▓▒
▒▓*/
Rune rune;
if (isTransparentBg)
@@ -324,28 +322,28 @@ public class AttributeView : View
}
/// <inheritdoc/>
protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
protected override bool OnMouseEvent (MouseEventArgs mouse)
{
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
if (mouse.Flags.HasFlag (MouseFlags.Button1Clicked))
{
if (IsForegroundPoint (mouseEvent.Position.X, mouseEvent.Position.Y))
if (IsForegroundPoint (mouse.Position.X, mouse.Position.Y))
{
ClickedInForeground ();
}
else if (IsBackgroundPoint (mouseEvent.Position.X, mouseEvent.Position.Y))
else if (IsBackgroundPoint (mouse.Position.X, mouse.Position.Y))
{
ClickedInBackground ();
}
}
mouseEvent.Handled = true;
mouse.Handled = true;
return mouseEvent.Handled;
return mouse.Handled;
}
private bool IsForegroundPoint (int x, int y) { return _foregroundPoints.Contains ((x, y)); }
private bool IsForegroundPoint (int x, int y) => _foregroundPoints.Contains ((x, y));
private bool IsBackgroundPoint (int x, int y) { return _backgroundPoints.Contains ((x, y)); }
private bool IsBackgroundPoint (int x, int y) => _backgroundPoints.Contains ((x, y));
private void ClickedInBackground ()
{

View File

@@ -618,24 +618,24 @@ public class TableEditor : Scenario
}
// Only handle mouse clicks
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouse })
{
return;
}
_tableView!.ScreenToCell (mouseArgs.Position, out int? clickedCol);
_tableView!.ScreenToCell (mouse.Position, out int? clickedCol);
if (clickedCol != null)
{
if (mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
if (mouse.Flags.HasFlag (MouseFlags.Button1Clicked))
{
// left click in a header
SortColumn (clickedCol.Value);
}
else if (mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
else if (mouse.Flags.HasFlag (MouseFlags.Button3Clicked))
{
// right click in a header
ShowHeaderContextMenu (clickedCol.Value, mouseArgs);
ShowHeaderContextMenu (clickedCol.Value, mouse);
}
}
};
@@ -1380,7 +1380,7 @@ public class TableEditor : Scenario
_tableView!.Update ();
}
private void ShowHeaderContextMenu (int clickedCol, MouseEventArgs e)
private void ShowHeaderContextMenu (int clickedCol, Terminal.Gui.Input.MouseEventArgs e)
{
if (HasCheckboxes () && clickedCol == 0)
{

View File

@@ -443,7 +443,7 @@ public class TextAlignmentAndDirection : Scenario
Text = txt
};
app.KeyUp += (s, m) =>
app.KeyDown += (s, m) =>
{
foreach (View v in singleLineLabels)
{

View File

@@ -232,7 +232,7 @@ public sealed class Transparent : Scenario
protected override bool OnClearingViewport () { return false; }
/// <inheritdoc />
protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { return false; }
protected override bool OnMouseEvent (Terminal.Gui.Input.MouseEventArgs mouse) { return false; }
/// <summary>

View File

@@ -564,15 +564,15 @@ public class TreeViewFileSystem : Scenario
}
// Only handle mouse clicks
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouse })
{
return;
}
// if user right clicks
if (mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
if (mouse.Flags.HasFlag (MouseFlags.Button3Clicked))
{
IFileSystemInfo? rightClicked = _treeViewFiles.GetObjectOnRow (mouseArgs.Position.Y);
IFileSystemInfo? rightClicked = _treeViewFiles.GetObjectOnRow (mouse.Position.Y);
// nothing was clicked
if (rightClicked is null)
@@ -582,8 +582,8 @@ public class TreeViewFileSystem : Scenario
ShowContextMenu (
new (
mouseArgs.Position.X + _treeViewFiles.Frame.X,
mouseArgs.Position.Y + _treeViewFiles.Frame.Y + 2
mouse.Position.X + _treeViewFiles.Frame.X,
mouse.Position.Y + _treeViewFiles.Frame.Y + 2
),
rightClicked
);

View File

@@ -53,7 +53,7 @@ public class ViewportSettings : Scenario
MouseEvent += VirtualDemoView_MouseEvent;
}
private void VirtualDemoView_MouseEvent (object sender, MouseEventArgs e)
private void VirtualDemoView_MouseEvent (object sender, Terminal.Gui.Input.MouseEventArgs e)
{
if (e.Flags == MouseFlags.WheeledDown)
{

View File

@@ -322,7 +322,7 @@ public class UICatalogRunnable : Runnable
_disableMouseCb = new ()
{
Title = "_Disable Mouse",
Title = "_Disable MouseEventArgs",
CheckedState = Application.IsMouseDisabled ? CheckState.Checked : CheckState.UnChecked,
// Best practice for CheckBoxes in menus is to disable focus and highlight states
CanFocus = false,
@@ -340,7 +340,7 @@ public class UICatalogRunnable : Runnable
new MenuItem
{
CommandView = _disableMouseCb,
HelpText = "Disable Mouse"
HelpText = "Disable MouseEventArgs"
});
return menuItems.ToArray ();